mirror of
https://github.com/biojppm/rapidyaml.git
synced 2026-01-18 13:31:19 +01:00
[fix] update python API: deprecate emit() et al
This commit is contained in:
@@ -158,7 +158,7 @@ class SimpleHardcoded:
|
||||
|
||||
yaml = "{'HELLO': a, foo: \"b\", bar: c, baz: d, seq: [0, 1, 2, 3]}"
|
||||
|
||||
def check(self, ut, t):
|
||||
def check(self, ut, t, is_json=False):
|
||||
# some convenient shorthands
|
||||
eq = ut.assertEqual
|
||||
ne = ut.assertNotEqual
|
||||
@@ -209,29 +209,58 @@ class SimpleHardcoded:
|
||||
eq(t.val(7), b"1")
|
||||
eq(t.val(8), b"2")
|
||||
eq(t.val(9), b"3")
|
||||
tr(t.is_key_quoted(1))
|
||||
fs(t.is_key_quoted(2))
|
||||
fs(t.is_key_quoted(3))
|
||||
fs(t.is_key_quoted(4))
|
||||
fs(t.is_key_quoted(5))
|
||||
fs(t.is_val_quoted(1))
|
||||
tr(t.is_val_quoted(2))
|
||||
fs(t.is_val_quoted(3))
|
||||
fs(t.is_val_quoted(4))
|
||||
fs(t.is_val_quoted(5))
|
||||
fs(t.is_val_quoted(6))
|
||||
fs(t.is_val_quoted(7))
|
||||
fs(t.is_val_quoted(8))
|
||||
fs(t.is_val_quoted(9))
|
||||
tr(t.is_quoted(1))
|
||||
tr(t.is_quoted(2))
|
||||
fs(t.is_quoted(3))
|
||||
fs(t.is_quoted(4))
|
||||
fs(t.is_quoted(5))
|
||||
fs(t.is_quoted(6))
|
||||
fs(t.is_quoted(7))
|
||||
fs(t.is_quoted(8))
|
||||
fs(t.is_quoted(9))
|
||||
if not is_json:
|
||||
tr(t.is_key_quoted(1))
|
||||
fs(t.is_key_quoted(2))
|
||||
fs(t.is_key_quoted(3))
|
||||
fs(t.is_key_quoted(4))
|
||||
fs(t.is_key_quoted(5))
|
||||
else:
|
||||
tr(t.is_key_quoted(1))
|
||||
tr(t.is_key_quoted(2))
|
||||
tr(t.is_key_quoted(3))
|
||||
tr(t.is_key_quoted(4))
|
||||
tr(t.is_key_quoted(5))
|
||||
if not is_json:
|
||||
fs(t.is_val_quoted(1))
|
||||
tr(t.is_val_quoted(2))
|
||||
fs(t.is_val_quoted(3))
|
||||
fs(t.is_val_quoted(4))
|
||||
fs(t.is_val_quoted(5))
|
||||
fs(t.is_val_quoted(6))
|
||||
fs(t.is_val_quoted(7))
|
||||
fs(t.is_val_quoted(8))
|
||||
fs(t.is_val_quoted(9))
|
||||
else:
|
||||
tr(t.is_val_quoted(1))
|
||||
tr(t.is_val_quoted(2))
|
||||
tr(t.is_val_quoted(3))
|
||||
tr(t.is_val_quoted(4))
|
||||
fs(t.is_val_quoted(5))
|
||||
fs(t.is_val_quoted(6))
|
||||
fs(t.is_val_quoted(7))
|
||||
fs(t.is_val_quoted(8))
|
||||
fs(t.is_val_quoted(9))
|
||||
if not is_json:
|
||||
tr(t.is_quoted(1))
|
||||
tr(t.is_quoted(2))
|
||||
fs(t.is_quoted(3))
|
||||
fs(t.is_quoted(4))
|
||||
fs(t.is_quoted(5))
|
||||
fs(t.is_quoted(6))
|
||||
fs(t.is_quoted(7))
|
||||
fs(t.is_quoted(8))
|
||||
fs(t.is_quoted(9))
|
||||
else:
|
||||
tr(t.is_quoted(1))
|
||||
tr(t.is_quoted(2))
|
||||
tr(t.is_quoted(3))
|
||||
tr(t.is_quoted(4))
|
||||
tr(t.is_quoted(5))
|
||||
fs(t.is_quoted(6))
|
||||
fs(t.is_quoted(7))
|
||||
fs(t.is_quoted(8))
|
||||
fs(t.is_quoted(9))
|
||||
tr(t.has_sibling(1, b"bar"))
|
||||
tr(t.has_sibling(1, b"baz"))
|
||||
tr(t.has_sibling(2, b"foo"))
|
||||
@@ -385,35 +414,65 @@ class _TestBase(unittest.TestCase):
|
||||
self.case.check(self, t)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
def _test41_emit(self):
|
||||
def _test41_emit_yaml(self):
|
||||
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
||||
yaml = ryml.emit(tree)
|
||||
yaml = ryml.emit_yaml(tree)
|
||||
output_tree = ryml.parse_in_arena(yaml)
|
||||
self.case.check(self, output_tree)
|
||||
|
||||
def _test42_compute_emit_length(self):
|
||||
def _test41_emit_json(self):
|
||||
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
||||
yaml = ryml.emit(tree)
|
||||
length = ryml.compute_emit_length(tree)
|
||||
json = ryml.emit_json(tree)
|
||||
output_tree = ryml.parse_in_arena(json)
|
||||
self.case.check(self, output_tree, is_json=True)
|
||||
|
||||
def _test42_compute_emit_yaml_length(self):
|
||||
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
||||
yaml = ryml.emit_yaml(tree)
|
||||
length = ryml.compute_emit_yaml_length(tree)
|
||||
self.assertEqual(len(yaml), length)
|
||||
|
||||
def _test43_emit_in_place(self):
|
||||
def _test42_compute_emit_json_length(self):
|
||||
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
||||
yaml = ryml.emit(tree)
|
||||
length = ryml.compute_emit_length(tree)
|
||||
json = ryml.emit_json(tree)
|
||||
length = ryml.compute_emit_json_length(tree)
|
||||
self.assertEqual(len(json), length)
|
||||
|
||||
def _test43_emit_yaml_in_place(self):
|
||||
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
||||
yaml = ryml.emit_yaml(tree)
|
||||
length = ryml.compute_emit_yaml_length(tree)
|
||||
self.assertEqual(len(yaml), length)
|
||||
buf = bytearray(length)
|
||||
s = ryml.emit_in_place(tree, buf)
|
||||
s = ryml.emit_yaml_in_place(tree, buf)
|
||||
self.assertEqual(len(s), length)
|
||||
self.assertTrue(s.tobytes().decode('utf-8') == yaml)
|
||||
self.assertTrue(buf.decode('utf-8') == yaml)
|
||||
|
||||
def _test44_short_buf(self):
|
||||
def _test43_emit_json_in_place(self):
|
||||
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
||||
length = ryml.compute_emit_length(tree)
|
||||
json = ryml.emit_json(tree)
|
||||
length = ryml.compute_emit_json_length(tree)
|
||||
self.assertEqual(len(json), length)
|
||||
buf = bytearray(length)
|
||||
s = ryml.emit_json_in_place(tree, buf)
|
||||
self.assertEqual(len(s), length)
|
||||
self.assertTrue(s.tobytes().decode('utf-8') == json)
|
||||
self.assertTrue(buf.decode('utf-8') == json)
|
||||
|
||||
def _test44_emit_yaml_short_buf(self):
|
||||
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
||||
length = ryml.compute_emit_yaml_length(tree)
|
||||
buf = bytearray(length-1)
|
||||
with self.assertRaises(IndexError):
|
||||
ryml.emit_in_place(tree, buf)
|
||||
ryml.emit_yaml_in_place(tree, buf)
|
||||
|
||||
def _test44_emit_json_short_buf(self):
|
||||
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
||||
length = ryml.compute_emit_json_length(tree)
|
||||
buf = bytearray(length-1)
|
||||
with self.assertRaises(IndexError):
|
||||
ryml.emit_json_in_place(tree, buf)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -457,17 +516,30 @@ class TestSimpleHardCoded(_TestBase):
|
||||
def test34_bytearray__rw__reuse_tree(self):
|
||||
self._test34_bytearray__rw__reuse_tree()
|
||||
|
||||
def test41_emit(self):
|
||||
self._test41_emit()
|
||||
# ----------------------------------------------------------
|
||||
def test41_emit_yaml(self):
|
||||
self._test41_emit_yaml()
|
||||
|
||||
def test42_compute_emit_length(self):
|
||||
self._test42_compute_emit_length()
|
||||
def test41_emit_json(self):
|
||||
self._test41_emit_json()
|
||||
|
||||
def test43_emit_in_place(self):
|
||||
self._test43_emit_in_place()
|
||||
def test42_compute_emit_yaml_length(self):
|
||||
self._test42_compute_emit_yaml_length()
|
||||
|
||||
def test44_short_buf(self):
|
||||
self._test44_short_buf()
|
||||
def test42_compute_emit_json_length(self):
|
||||
self._test42_compute_emit_json_length()
|
||||
|
||||
def test43_emit_yaml_in_place(self):
|
||||
self._test43_emit_yaml_in_place()
|
||||
|
||||
def test43_emit_json_in_place(self):
|
||||
self._test43_emit_json_in_place()
|
||||
|
||||
def test44_emit_yaml_short_buf(self):
|
||||
self._test44_emit_yaml_short_buf()
|
||||
|
||||
def test44_emit_json_short_buf(self):
|
||||
self._test44_emit_json_short_buf()
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
127
api/ryml.i
127
api/ryml.i
@@ -123,31 +123,60 @@ void parse_substr(c4::substr s, c4::yml::Tree *t)
|
||||
c4::yml::parse_in_place(s, t);
|
||||
}
|
||||
|
||||
char * emit_malloc(const c4::yml::Tree &t, size_t id)
|
||||
char * emit_yaml_malloc(c4::yml::Tree const& t, size_t id)
|
||||
{
|
||||
c4::substr buf;
|
||||
c4::substr ret = c4::yml::emit(t, id, buf, /*error_on_excess*/false);
|
||||
c4::substr ret = c4::yml::emit_yaml(t, id, buf, /*error_on_excess*/false);
|
||||
if(ret.str == nullptr && ret.len > 0)
|
||||
{
|
||||
// Use new[] to parse with delete[] in SWIG.
|
||||
char * alloc = new char[ret.len+1];
|
||||
char * alloc = new char[ret.len + 1]; // we'll return a c-string and not a csubstr
|
||||
c4::substr alloced_buf(alloc, ret.len);
|
||||
ret = c4::yml::emit(t, id, alloced_buf, /*error_on_excess*/true);
|
||||
ret = c4::yml::emit_yaml(t, id, alloced_buf, /*error_on_excess*/true);
|
||||
ret.str[ret.len] = 0;
|
||||
}
|
||||
return ret.str;
|
||||
}
|
||||
|
||||
size_t emit_length(const c4::yml::Tree &t, size_t id)
|
||||
char * emit_json_malloc(c4::yml::Tree const& t, size_t id)
|
||||
{
|
||||
c4::substr buf;
|
||||
c4::substr ret = c4::yml::emit(t, id, buf, /*error_on_excess*/false);
|
||||
c4::substr ret = c4::yml::emit_json(t, id, buf, /*error_on_excess*/false);
|
||||
if(ret.str == nullptr && ret.len > 0)
|
||||
{
|
||||
// Use new[] to parse with delete[] in SWIG.
|
||||
char * alloc = new char[ret.len + 1]; // we'll return a c-string and not a csubstr
|
||||
c4::substr alloced_buf(alloc, ret.len);
|
||||
ret = c4::yml::emit_json(t, id, alloced_buf, /*error_on_excess*/true);
|
||||
ret.str[ret.len] = 0;
|
||||
}
|
||||
return ret.str;
|
||||
}
|
||||
|
||||
size_t emit_yaml_length(const c4::yml::Tree &t, size_t id)
|
||||
{
|
||||
c4::substr buf;
|
||||
c4::substr ret = c4::yml::emit_yaml(t, id, buf, /*error_on_excess*/false);
|
||||
return ret.len;
|
||||
}
|
||||
|
||||
bool emit_to_substr(const c4::yml::Tree &t, size_t id, c4::substr s, size_t *OUTPUT)
|
||||
size_t emit_json_length(const c4::yml::Tree &t, size_t id)
|
||||
{
|
||||
c4::substr result = c4::yml::emit(t, id, s, /*error_on_excess*/false);
|
||||
c4::substr buf;
|
||||
c4::substr ret = c4::yml::emit_json(t, id, buf, /*error_on_excess*/false);
|
||||
return ret.len;
|
||||
}
|
||||
|
||||
bool emit_yaml_to_substr(const c4::yml::Tree &t, size_t id, c4::substr s, size_t *OUTPUT)
|
||||
{
|
||||
c4::substr result = c4::yml::emit_yaml(t, id, s, /*error_on_excess*/false);
|
||||
*OUTPUT = result.len;
|
||||
return result.str == nullptr;
|
||||
}
|
||||
|
||||
bool emit_json_to_substr(const c4::yml::Tree &t, size_t id, c4::substr s, size_t *OUTPUT)
|
||||
{
|
||||
c4::substr result = c4::yml::emit_json(t, id, s, /*error_on_excess*/false);
|
||||
*OUTPUT = result.len;
|
||||
return result.str == nullptr;
|
||||
}
|
||||
@@ -186,6 +215,8 @@ bool _same_mem(c4::csubstr l, c4::csubstr r)
|
||||
|
||||
%pythoncode %{
|
||||
|
||||
from deprecation import deprecated
|
||||
|
||||
|
||||
def as_csubstr(s):
|
||||
return _get_as_csubstr(s)
|
||||
@@ -199,20 +230,22 @@ def u(memview):
|
||||
|
||||
def children(tree, node=None):
|
||||
assert tree is not None
|
||||
if node is None: node = tree.root_id()
|
||||
if node is None:
|
||||
node = tree.root_id()
|
||||
ch = tree.first_child(node)
|
||||
while ch != NONE:
|
||||
yield ch
|
||||
ch = tree.next_sibling(ch)
|
||||
yield ch
|
||||
ch = tree.next_sibling(ch)
|
||||
|
||||
|
||||
def siblings(tree, node):
|
||||
assert tree is not None
|
||||
if node is None: return
|
||||
if node is None:
|
||||
return
|
||||
ch = tree.first_sibling(node)
|
||||
while ch != NONE:
|
||||
yield ch
|
||||
ch = tree.next_sibling(ch)
|
||||
yield ch
|
||||
ch = tree.next_sibling(ch)
|
||||
|
||||
|
||||
def walk(tree, node=None, indentation_level=0):
|
||||
@@ -235,28 +268,6 @@ def parse_in_arena(buf, **kwargs):
|
||||
return _call_parse(parse_csubstr, buf, **kwargs)
|
||||
|
||||
|
||||
def emit(tree, id=None):
|
||||
if id is None:
|
||||
id = tree.root_id()
|
||||
return emit_malloc(tree, id)
|
||||
|
||||
|
||||
def compute_emit_length(tree, id=None):
|
||||
if id is None:
|
||||
id = tree.root_id()
|
||||
return emit_length(tree, id)
|
||||
|
||||
|
||||
def emit_in_place(tree, buf, id=None):
|
||||
if id is None:
|
||||
id = tree.root_id()
|
||||
(failed, expected_size) = emit_to_substr(tree, id, buf)
|
||||
if failed:
|
||||
raise IndexError("Output buffer has {} bytes, but emit required {} bytes".format(
|
||||
len(buf), expected_size))
|
||||
return memoryview(buf)[:expected_size]
|
||||
|
||||
|
||||
def _call_parse(parse_fn, buf, **kwargs):
|
||||
tree = kwargs.get("tree", Tree())
|
||||
parse_fn(buf, tree)
|
||||
@@ -267,6 +278,50 @@ def _check_valid_for_in_situ(obj):
|
||||
if type(obj) in (str, bytes):
|
||||
raise TypeError("cannot parse in situ: " + type(obj).__name__)
|
||||
|
||||
|
||||
|
||||
@deprecated(deprecated_in="0.5.0", details="Use emit_yaml() instead")
|
||||
def emit(tree, id=None):
|
||||
return emit_yaml(tree, id)
|
||||
def emit_yaml(tree, id=None):
|
||||
if id is None:
|
||||
id = tree.root_id()
|
||||
return emit_yaml_malloc(tree, id)
|
||||
def emit_json(tree, id=None):
|
||||
if id is None:
|
||||
id = tree.root_id()
|
||||
return emit_json_malloc(tree, id)
|
||||
|
||||
|
||||
@deprecated(deprecated_in="0.5.0", details="Use compute_emit_yaml_length() instead")
|
||||
def compute_emit_length(tree, id=None):
|
||||
return compute_emit_yaml_length(tree, id)
|
||||
def compute_emit_yaml_length(tree, id=None):
|
||||
if id is None:
|
||||
id = tree.root_id()
|
||||
return emit_yaml_length(tree, id)
|
||||
def compute_emit_json_length(tree, id=None):
|
||||
if id is None:
|
||||
id = tree.root_id()
|
||||
return emit_json_length(tree, id)
|
||||
|
||||
|
||||
@deprecated(deprecated_in="0.5.0", details="Use emit_yaml_in_place() instead")
|
||||
def emit_in_place(tree, buf, id=None):
|
||||
return emit_yaml_in_place(tree, buf, id)
|
||||
def emit_yaml_in_place(tree, buf, id=None):
|
||||
return _emit_fn_in_place(tree, buf, id, emit_yaml_to_substr)
|
||||
def emit_json_in_place(tree, buf, id=None):
|
||||
return _emit_fn_in_place(tree, buf, id, emit_json_to_substr)
|
||||
def _emit_fn_in_place(tree, buf, id, fn):
|
||||
if id is None:
|
||||
id = tree.root_id()
|
||||
(failed, expected_size) = fn(tree, id, buf)
|
||||
if failed:
|
||||
raise IndexError("Output buffer has {} bytes, but emit requires {} bytes".format(
|
||||
len(buf), expected_size))
|
||||
return memoryview(buf)[:expected_size]
|
||||
|
||||
%}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
- The initial version of `ConstNodeRef/NodeRef` had the problem that const methods in the CRTP base did not participate in overload resolution ([#294](https://github.com/biojppm/rapidyaml/issues/294)), preventing calls from `const NodeRef` objects. This was fixed by moving non-const methods to the CRTP base and disabling them with SFINAE ([PR#295](https://github.com/biojppm/rapidyaml/pull/295)).
|
||||
- Also added disambiguation iteration methods: `.cbegin()`, `.cend()`, `.cchildren()`, `.csiblings()` ([PR#295](https://github.com/biojppm/rapidyaml/pull/295)).
|
||||
- Deprecate `emit()` and `emitrs()` ([#120](https://github.com/biojppm/rapidyaml/issues/120), [PR#303](https://github.com/biojppm/rapidyaml/pull/303)): use `emit_yaml()` and `emitrs_yaml()` instead. This was done to improve compatibility with Qt, which leaks a macro named `emit`. For more information, see [#120](https://github.com/biojppm/rapidyaml/issues/120).
|
||||
- In the Python API:
|
||||
- Deprecate `emit()`, add `emit_yaml()` and `emit_json()`.
|
||||
- Deprecate `compute_emit_length()`, add `compute_emit_yaml_length()` and `compute_emit_json_length()`.
|
||||
- Deprecate `emit_in_place()`, add `emit_yaml_in_place()` and `emit_json_in_place()`.
|
||||
- Calling the deprecated functions will now trigger a warning.
|
||||
|
||||
|
||||
### Performance improvements
|
||||
|
||||
@@ -5,3 +5,4 @@ build
|
||||
twine
|
||||
setuptools_scm
|
||||
setuptools-git
|
||||
deprecation
|
||||
|
||||
Reference in New Issue
Block a user