re #513: fix python README example, run as test

This commit is contained in:
Joao Paulo Magalhaes
2025-04-01 01:35:45 +01:00
parent 009242d262
commit 3b3ad1e093
6 changed files with 281 additions and 178 deletions

View File

@@ -1,7 +1,7 @@
SHELL := bash
YS_VERSION := 0.1.88
YS_PREFIX := /tmp/rapidyaml
YS_PREFIX := $(shell cd ../.. ; pwd)/build/ys
YS := $(YS_PREFIX)/bin/ys-$(YS_VERSION)
INPUT_FILES := $(wildcard */*)
@@ -55,6 +55,7 @@ force:
# Auto install a specific version of ys
install-ys: $(YS)
$(YS):
mkdir -p $(YS_PREFIX)
curl -s https://yamlscript.org/install | \
BIN=1 VERSION=$(YS_VERSION) PREFIX=$(YS_PREFIX) bash

View File

@@ -156,104 +156,68 @@ jobs:
matrix:
# Local function to expand python entries:
python =:
fn(a0 a1 a2 a3 os)::
pythonv:: a0
cibw_pyv:: a1
cibw_arch:: a2
cibw_platform:: a3
name:: "python/$a0/linux/$a2"
sfx:: "python$a0_linux$a2" # suffix
osname: linux
fn(pyv cibwpyv cibwarch cibwplatform os cmkflags):: # NOTE: cannot use _ in names?
name:: "python/$pyv/$cibwplatform"
sfx:: "python$pyv-$cibwplatform" # suffix
os:: os
pythonv:: pyv
cibw_pyv:: cibwpyv
cibw_arch:: cibwarch
cibw_platform:: cibwplatform
cmakeflags:: cmkflags
config:
#- ! python('3.13' 313 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04')
#- ! python('3.13' 313 'i686' 'manylinux_i686' 'ubuntu-24.04')
- ! python('3.12' 312 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04')
- ! python('3.12' 312 'i686' 'manylinux_i686' 'ubuntu-24.04')
- ! python('3.11' 311 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04')
- ! python('3.11' 311 'i686' 'manylinux_i686' 'ubuntu-24.04')
- ! python('3.10' 310 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04')
- ! python('3.10' 310 'i686' 'manylinux_i686' 'ubuntu-24.04')
- ! python('3.9' 39 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04')
- ! python('3.9' 39 'i686' 'manylinux_i686' 'ubuntu-24.04')
- ! python('3.8' 38 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04')
- ! python('3.8' 38 'i686' 'manylinux_i686' 'ubuntu-24.04')
- ! python('3.7' 37 'x86_64' 'manylinux_x86_64' 'ubuntu-22.04')
- ! python('3.7' 37 'i686' 'manylinux_i686' 'ubuntu-22.04')
#- ! python('3.6' 36 'x86_64' 'manylinux_x86_64' 'ubuntu-22.04')
#- ! python('3.6' 36 'i686' 'manylinux_i686' 'ubuntu-22.04')
# the windows builds are disabled because they are causing problems and
# preventing the release.
# the problems are related to CMakeExtension forcing the use of Ninja
# which does not play well with the -G 'Visual Studio...' option used
# below.
# fixing this looks like it will be time-intensive.
#- {pythonv: '3.11', cibw_pyv: 311, cibw_arch: AMD64 ,
# cibw_platform: win_amd64, osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A x64'}
#- {pythonv: '3.11', cibw_pyv: 311, cibw_arch: x86 ,
# cibw_platform: win32 , osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A Win32'}
#- {pythonv: '3.10', cibw_pyv: 310, cibw_arch: AMD64 ,
# cibw_platform: win_amd64, osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A x64'}
#- {pythonv: '3.10', cibw_pyv: 310, cibw_arch: x86 ,
# cibw_platform: win32 , osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A Win32'}
#- {pythonv: '3.9' , cibw_pyv: 39 , cibw_arch: AMD64 ,
# cibw_platform: win_amd64, osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A x64'}
#- {pythonv: '3.9' , cibw_pyv: 39 , cibw_arch: x86 ,
# cibw_platform: win32 , osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A Win32'}
#- {pythonv: '3.8' , cibw_pyv: 38 , cibw_arch: AMD64 ,
# cibw_platform: win_amd64, osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A x64'}
#- {pythonv: '3.8' , cibw_pyv: 38 , cibw_arch: x86 ,
# cibw_platform: win32 , osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A Win32'}
#- {pythonv: '3.7' , cibw_pyv: 37 , cibw_arch: AMD64 ,
# cibw_platform: win_amd64, osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A x64'}
#- {pythonv: '3.7' , cibw_pyv: 37 , cibw_arch: x86 ,
# cibw_platform: win32 , osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A Win32'}
#- {pythonv: '3.6' , cibw_pyv: 36 , cibw_arch: AMD64 ,
# cibw_platform: win_amd64, osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A x64'}
#- {pythonv: '3.6' , cibw_pyv: 36 , cibw_arch: x86 ,
# cibw_platform: win32 , osname: win , os: windows-2019,
# cxx: vs2019},
# cmakeflags: '-G "Visual Studio 16 2019" -A Win32'}
## macosx builds are generating a SIGSEGV when importing. (!)
## /biojppm/rapidyaml/actions/runs/3062528713/jobs/4943611397#step:7:269
#- {pythonv: '3.11', cibw_pyv: 311, cibw_arch: x86_64,
# cibw_platform: macosx_x86_64, osname: macos, os: macos-10.15}
#- {pythonv: '3.10', cibw_pyv: 310, cibw_arch: x86_64,
# cibw_platform: macosx_x86_64, osname: macos, os: macos-10.15}
#- {pythonv: '3.9' , cibw_pyv: 39 , cibw_arch: x86_64,
# cibw_platform: macosx_x86_64, osname: macos, os: macos-10.15}
#- {pythonv: '3.8' , cibw_pyv: 38 , cibw_arch: x86_64,
# cibw_platform: macosx_x86_64, osname: macos, os: macos-10.15}
#- {pythonv: '3.7' , cibw_pyv: 37 , cibw_arch: x86_64,
# cibw_platform: macosx_x86_64, osname: macos, os: macos-10.15}
#- {pythonv: '3.6' , cibw_pyv: 36 , cibw_arch: x86_64,
# cibw_platform: macosx_x86_64, osname: macos, os: macos-10.15}
# pyv pyv arch platform os cmakeflags
- ! python('3.13' 313 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04' '')
- ! python('3.13' 313 'i686' 'manylinux_i686' 'ubuntu-24.04' '')
#- ! python('3.13' 313 'AMD64' 'win_amd64' 'windows-2022' '-G "Visual Studio 16 2019" -A x64')
#- ! python('3.13' 313 'x86' 'win32' 'windows-2022' '-G "Visual Studio 16 2019" -A Win32')
#- ! python('3.13' 313 'x86_64' 'macosx_x86_64' 'macosx-10.15' '')
#
- ! python('3.12' 312 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04' '')
- ! python('3.12' 312 'i686' 'manylinux_i686' 'ubuntu-24.04' '')
#- ! python('3.12' 312 'AMD64' 'win_amd64' 'windows-2022' '-G "Visual Studio 16 2019" -A x64')
#- ! python('3.12' 312 'x86' 'win32' 'windows-2022' '-G "Visual Studio 16 2019" -A Win32')
#- ! python('3.12' 312 'x86_64' 'macosx_x86_64' 'macosx-10.15' '')
#
- ! python('3.11' 311 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04' '')
- ! python('3.11' 311 'i686' 'manylinux_i686' 'ubuntu-24.04' '')
#- ! python('3.11' 311 'AMD64' 'win_amd64' 'windows-2022' '-G "Visual Studio 16 2019" -A x64')
#- ! python('3.11' 311 'x86' 'win32' 'windows-2022' '-G "Visual Studio 16 2019" -A Win32')
#- ! python('3.11' 311 'x86_64' 'macosx_x86_64' 'macosx-10.15' '')
#
- ! python('3.10' 310 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04' '')
- ! python('3.10' 310 'i686' 'manylinux_i686' 'ubuntu-24.04' '')
#- ! python('3.10' 310 'AMD64' 'win_amd64' 'windows-2022' '-G "Visual Studio 16 2019" -A x64')
#- ! python('3.10' 310 'x86' 'win32' 'windows-2022' '-G "Visual Studio 16 2019" -A Win32')
#- ! python('3.10' 310 'x86_64' 'macosx_x86_64' 'macosx-10.15' '')
#
- ! python('3.9' 39 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04' '')
- ! python('3.9' 39 'i686' 'manylinux_i686' 'ubuntu-24.04' '')
#- ! python('3.9' 39 'AMD64' 'win_amd64' 'windows-2022' '-G "Visual Studio 16 2019" -A x64')
#- ! python('3.9' 39 'x86' 'win32' 'windows-2022' '-G "Visual Studio 16 2019" -A Win32')
#- ! python('3.9' 39 'x86_64' 'macosx_x86_64' 'macosx-10.15' '')
#
- ! python('3.8' 38 'x86_64' 'manylinux_x86_64' 'ubuntu-24.04' '')
- ! python('3.8' 38 'i686' 'manylinux_i686' 'ubuntu-24.04' '')
#- ! python('3.8' 38 'AMD64' 'win_amd64' 'windows-2022' '-G "Visual Studio 16 2019" -A x64')
#- ! python('3.8' 38 'x86' 'win32' 'windows-2022' '-G "Visual Studio 16 2019" -A Win32')
#- ! python('3.8' 38 'x86_64' 'macosx_x86_64' 'macosx-10.15' '')
#
- ! python('3.7' 37 'x86_64' 'manylinux_x86_64' 'ubuntu-22.04' '')
- ! python('3.7' 37 'i686' 'manylinux_i686' 'ubuntu-22.04' '')
#- ! python('3.7' 37 'AMD64' 'win_amd64' 'windows-2022' '-G "Visual Studio 16 2019" -A x64')
#- ! python('3.7' 37 'x86' 'win32' 'windows-2022' '-G "Visual Studio 16 2019" -A Win32')
#- ! python('3.7' 37 'x86_64' 'macosx_x86_64' 'macosx-10.15' '')
#
- ! python('3.6' 36 'x86_64' 'manylinux_x86_64' 'ubuntu-20.04' '') # setup-python 3.6 requires ubuntu 20.04
- ! python('3.6' 36 'i686' 'manylinux_i686' 'ubuntu-20.04' '') # setup-python 3.6 requires ubuntu 20.04
#- ! python('3.6' 36 'AMD64' 'win_amd64' 'windows-2022' '-G "Visual Studio 16 2019" -A x64')
#- ! python('3.6' 36 'x86' 'win32' 'windows-2022' '-G "Visual Studio 16 2019" -A Win32')
#- ! python('3.6' 36 'x86_64' 'macosx_x86_64' 'macosx-10.15' '')
steps:
- :: checkout-action
- name: create wheel
uses: pypa/cibuildwheel@v2.17
uses: pypa/cibuildwheel@v2.23
- name: rename wheelhouse -> dist
run: mv -fv wheelhouse dist
- name: Verify artifacts

View File

@@ -290,102 +290,134 @@ jobs:
fail-fast: false
matrix:
config:
- pythonv: '3.12'
- name: python/3.13/manylinux_x86_64
sfx: python3.13-manylinux_x86_64
os: ubuntu-24.04
pythonv: '3.13'
cibw_pyv: 313
cibw_arch: x86_64
cibw_platform: manylinux_x86_64
cmakeflags: ''
- name: python/3.13/manylinux_i686
sfx: python3.13-manylinux_i686
os: ubuntu-24.04
pythonv: '3.13'
cibw_pyv: 313
cibw_arch: i686
cibw_platform: manylinux_i686
cmakeflags: ''
- name: python/3.12/manylinux_x86_64
sfx: python3.12-manylinux_x86_64
os: ubuntu-24.04
pythonv: '3.12'
cibw_pyv: 312
cibw_arch: x86_64
cibw_platform: manylinux_x86_64
name: python/3.12/linux/x86_64
sfx: python3.12_linuxx86_64
osname: linux
cmakeflags: ''
- name: python/3.12/manylinux_i686
sfx: python3.12-manylinux_i686
os: ubuntu-24.04
- pythonv: '3.12'
pythonv: '3.12'
cibw_pyv: 312
cibw_arch: i686
cibw_platform: manylinux_i686
name: python/3.12/linux/i686
sfx: python3.12_linuxi686
osname: linux
cmakeflags: ''
- name: python/3.11/manylinux_x86_64
sfx: python3.11-manylinux_x86_64
os: ubuntu-24.04
- pythonv: '3.11'
pythonv: '3.11'
cibw_pyv: 311
cibw_arch: x86_64
cibw_platform: manylinux_x86_64
name: python/3.11/linux/x86_64
sfx: python3.11_linuxx86_64
osname: linux
cmakeflags: ''
- name: python/3.11/manylinux_i686
sfx: python3.11-manylinux_i686
os: ubuntu-24.04
- pythonv: '3.11'
pythonv: '3.11'
cibw_pyv: 311
cibw_arch: i686
cibw_platform: manylinux_i686
name: python/3.11/linux/i686
sfx: python3.11_linuxi686
osname: linux
cmakeflags: ''
- name: python/3.10/manylinux_x86_64
sfx: python3.10-manylinux_x86_64
os: ubuntu-24.04
- pythonv: '3.10'
pythonv: '3.10'
cibw_pyv: 310
cibw_arch: x86_64
cibw_platform: manylinux_x86_64
name: python/3.10/linux/x86_64
sfx: python3.10_linuxx86_64
osname: linux
cmakeflags: ''
- name: python/3.10/manylinux_i686
sfx: python3.10-manylinux_i686
os: ubuntu-24.04
- pythonv: '3.10'
pythonv: '3.10'
cibw_pyv: 310
cibw_arch: i686
cibw_platform: manylinux_i686
name: python/3.10/linux/i686
sfx: python3.10_linuxi686
osname: linux
cmakeflags: ''
- name: python/3.9/manylinux_x86_64
sfx: python3.9-manylinux_x86_64
os: ubuntu-24.04
- pythonv: '3.9'
pythonv: '3.9'
cibw_pyv: 39
cibw_arch: x86_64
cibw_platform: manylinux_x86_64
name: python/3.9/linux/x86_64
sfx: python3.9_linuxx86_64
osname: linux
cmakeflags: ''
- name: python/3.9/manylinux_i686
sfx: python3.9-manylinux_i686
os: ubuntu-24.04
- pythonv: '3.9'
pythonv: '3.9'
cibw_pyv: 39
cibw_arch: i686
cibw_platform: manylinux_i686
name: python/3.9/linux/i686
sfx: python3.9_linuxi686
osname: linux
cmakeflags: ''
- name: python/3.8/manylinux_x86_64
sfx: python3.8-manylinux_x86_64
os: ubuntu-24.04
- pythonv: '3.8'
pythonv: '3.8'
cibw_pyv: 38
cibw_arch: x86_64
cibw_platform: manylinux_x86_64
name: python/3.8/linux/x86_64
sfx: python3.8_linuxx86_64
osname: linux
cmakeflags: ''
- name: python/3.8/manylinux_i686
sfx: python3.8-manylinux_i686
os: ubuntu-24.04
- pythonv: '3.8'
pythonv: '3.8'
cibw_pyv: 38
cibw_arch: i686
cibw_platform: manylinux_i686
name: python/3.8/linux/i686
sfx: python3.8_linuxi686
osname: linux
os: ubuntu-24.04
- pythonv: '3.7'
cmakeflags: ''
- name: python/3.7/manylinux_x86_64
sfx: python3.7-manylinux_x86_64
os: ubuntu-22.04
pythonv: '3.7'
cibw_pyv: 37
cibw_arch: x86_64
cibw_platform: manylinux_x86_64
name: python/3.7/linux/x86_64
sfx: python3.7_linuxx86_64
osname: linux
cmakeflags: ''
- name: python/3.7/manylinux_i686
sfx: python3.7-manylinux_i686
os: ubuntu-22.04
- pythonv: '3.7'
pythonv: '3.7'
cibw_pyv: 37
cibw_arch: i686
cibw_platform: manylinux_i686
name: python/3.7/linux/i686
sfx: python3.7_linuxi686
osname: linux
os: ubuntu-22.04
cmakeflags: ''
- name: python/3.6/manylinux_x86_64
sfx: python3.6-manylinux_x86_64
os: ubuntu-20.04
pythonv: '3.6'
cibw_pyv: 36
cibw_arch: x86_64
cibw_platform: manylinux_x86_64
cmakeflags: ''
- name: python/3.6/manylinux_i686
sfx: python3.6-manylinux_i686
os: ubuntu-20.04
pythonv: '3.6'
cibw_pyv: 36
cibw_arch: i686
cibw_platform: manylinux_i686
cmakeflags: ''
steps:
- name: checkout (action)
uses: actions/checkout@v4
@@ -393,7 +425,7 @@ jobs:
submodules: recursive
fetch-depth: 0
- name: create wheel
uses: pypa/cibuildwheel@v2.17
uses: pypa/cibuildwheel@v2.23
- name: rename wheelhouse -> dist
run: mv -fv wheelhouse dist
- name: Verify artifacts

View File

@@ -618,29 +618,57 @@ A JavaScript+WebAssembly port is available, compiled through [emscripten](https:
### Python
(Note that this is a work in progress. Additions will be made and things will
be changed.) With that said, here's an example of the Python API:
be changed.) With that said, here's an example of the Python API (from a [test file](api/python/tests/)):
```python
import ryml
# ryml cannot accept strings because it does not take ownership of the
# source buffer; only bytes or bytearrays are accepted.
src = b"{HELLO: a, foo: b, bar: c, baz: d, seq: [0, 1, 2, 3]}"
def check(tree):
# for now, only the index-based low-level API is implemented
# verify that the given tree is as expected from the source above
def check(tree: ryml.Tree):
# For now, only the index-based low-level API is implemented.
# Here's the node structure for a tree parsed from the source
# above:
#
# [node 0] root, map
# ` [node 1] "HELLO": "a"
# ` [node 2] "foo": "b"
# ` [node 3] "bar": "c"
# ` [node 4] "baz": "d"
# ` [node 5] "seq":
# ` [node 6] "0"
# ` [node 7] "1"
# ` [node 8] "2"
# ` [node 9] "3"
#
# let's now do some assertions:
assert tree.size() == 10
assert tree.root_id() == 0
assert tree.first_child(0) == 1
assert tree.next_sibling(1) == 2
assert tree.first_sibling(5) == 2
assert tree.last_sibling(1) == 5
# use bytes objects for queries
assert tree.find_child(0, b"foo") == 1
assert tree.key(1) == b"foo")
assert tree.val(1) == b"b")
assert tree.find_child(0, b"seq") == 5
assert tree.is_root(0)
assert tree.is_map(0)
assert tree.is_seq(5)
# use bytes objects for queries
assert tree.find_child(0, b"HELLO") == 1
assert tree.find_child(0, b"foo") == 2
assert tree.find_child(0, b"seq") == 5
assert tree.key(1) == b"HELLO"
assert tree.val(1) == b"a"
assert tree.key(2) == b"foo"
assert tree.val(2) == b"b"
assert tree.find_child(0, b"seq") == 5
# hierarchy:
assert tree.first_child(0) == 1
assert tree.last_child(0) == 5
assert tree.next_sibling(1) == 2
assert tree.first_sibling(5) == 1
assert tree.last_sibling(1) == 5
assert tree.first_child(5) == 6
assert tree.last_child(5) == 9
# to loop over children:
for i, ch in enumerate(ryml.children(tree, 5)):
assert tree.val(ch) == [b"0", b"1", b"2", b"3"][i]
@@ -649,34 +677,31 @@ def check(tree):
assert tree.key(sib) == [b"HELLO", b"foo", b"bar", b"baz", b"seq"][i]
# to walk over all elements
visited = [False] * tree.size()
for n, indentation_level in ryml.walk(tree):
# just a dumb emitter
left = " " * indentation_level
if tree.is_keyval(n):
print("{}{}: {}".format(left, tree.key(n), tree.val(n))
elif tree.is_val(n):
print("- {}".format(left, tree.val(n))
elif tree.is_keyseq(n):
print("{}{}:".format(left, tree.key(n))
visited[inode] = True
for node_id, indentation_level in ryml.walk(tree):
visited[node_id] = True
assert False not in visited
# NOTE about encoding!
k = tree.get_key(5)
k = tree.key(5)
print(k) # '<memory at 0x7f80d5b93f48>'
assert k == b"seq" # ok, as expected
assert k != "seq" # not ok - NOTE THIS!
assert k != "seq" # not ok - NOTE THIS!
assert str(k) != "seq" # not ok
assert str(k, "utf8") == "seq" # ok again
# parse immutable buffer
tree = ryml.parse_in_arena(src)
check(tree) # OK
# parse mutable buffer.
# requires bytearrays or objects offering writeable memory
mutable = bytearray(src)
tree = ryml.parse_in_place(mutable)
check(tree) # OK
def test_immutable_buffer():
# copy the source buffer to the tree arena and parse the copy
tree = ryml.parse_in_arena(src)
check(tree) # OK
def test_mutable_buffer():
# parse a mutable buffer in place
# requires bytearrays or objects offering writeable memory
mutable_buffer = bytearray(src)
# WATCHOUT: the tree is pointing into mutable_buffer!
tree = ryml.parse_in_place(mutable_buffer)
check(tree) # OK
```
As expected, the performance results so far are encouraging. In
a [timeit benchmark](api/python/parse_bm.py) compared

View File

@@ -0,0 +1,81 @@
import ryml
# ryml cannot accept strings because it does not take ownership of the
# source buffer; only bytes or bytearrays are accepted.
src = b"{HELLO: a, foo: b, bar: c, baz: d, seq: [0, 1, 2, 3]}"
# verify that the given tree is as expected from the source above
def check(tree: ryml.Tree):
# For now, only the index-based low-level API is implemented.
# Here's the node structure for a tree parsed from the source
# above:
#
# [node 0] root, map
# ` [node 1] "HELLO": "a"
# ` [node 2] "foo": "b"
# ` [node 3] "bar": "c"
# ` [node 4] "baz": "d"
# ` [node 5] "seq":
# ` [node 6] "0"
# ` [node 7] "1"
# ` [node 8] "2"
# ` [node 9] "3"
#
# let's now do some assertions:
assert tree.size() == 10
assert tree.root_id() == 0
assert tree.is_root(0)
assert tree.is_map(0)
assert tree.is_seq(5)
# use bytes objects for queries
assert tree.find_child(0, b"HELLO") == 1
assert tree.find_child(0, b"foo") == 2
assert tree.find_child(0, b"seq") == 5
assert tree.key(1) == b"HELLO"
assert tree.val(1) == b"a"
assert tree.key(2) == b"foo"
assert tree.val(2) == b"b"
assert tree.find_child(0, b"seq") == 5
# hierarchy:
assert tree.first_child(0) == 1
assert tree.last_child(0) == 5
assert tree.next_sibling(1) == 2
assert tree.first_sibling(5) == 1
assert tree.last_sibling(1) == 5
assert tree.first_child(5) == 6
assert tree.last_child(5) == 9
# to loop over children:
for i, ch in enumerate(ryml.children(tree, 5)):
assert tree.val(ch) == [b"0", b"1", b"2", b"3"][i]
# to loop over siblings:
for i, sib in enumerate(ryml.siblings(tree, 5)):
assert tree.key(sib) == [b"HELLO", b"foo", b"bar", b"baz", b"seq"][i]
# to walk over all elements
visited = [False] * tree.size()
for node_id, indentation_level in ryml.walk(tree):
visited[node_id] = True
assert False not in visited
# NOTE about encoding!
k = tree.key(5)
print(k) # '<memory at 0x7f80d5b93f48>'
assert k == b"seq" # ok, as expected
assert k != "seq" # not ok - NOTE THIS!
assert str(k) != "seq" # not ok
assert str(k, "utf8") == "seq" # ok again
def test_immutable_buffer():
# copy the source buffer to the tree arena and parse the copy
tree = ryml.parse_in_arena(src)
check(tree) # OK
def test_mutable_buffer():
# parse a mutable buffer in place
# requires bytearrays or objects offering writeable memory
mutable_buffer = bytearray(src)
# WATCHOUT: the tree is pointing into mutable_buffer!
tree = ryml.parse_in_place(mutable_buffer)
check(tree) # OK