C "safe" parser fails to parse {a: b:c}
C version of reader, parser and emitter for ruamel.yaml
Brought to you by:
anthon
When using the C safe loader, {a: b:c} fails to parse. This does not occur when using the pure Python loader.
Versions:
Running this code:
import ruamel.yaml
yaml = ruamel.yaml.YAML(typ="safe", pure=False)
print(yaml.load("{a: b:c}"))
Produces this error:
Traceback (most recent call last):
File "<python-input-0>", line 3, in <module>
print(yaml.load("{a: b:c}"))
~~~~~~~~~^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/ruamel/yaml/main.py", line 453, in load
return constructor.get_single_data()
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/usr/local/lib/python3.13/site-packages/ruamel/yaml/constructor.py", line 117, in get_single_data
node = self.composer.get_single_node()
File "_ruamel_yaml.pyx", line 703, in ruamel.yaml.clib._ruamel_yaml.CParser.get_single_node
File "_ruamel_yaml.pyx", line 904, in ruamel.yaml.clib._ruamel_yaml.CParser._parse_next_event
ruamel.yaml.scanner.ScannerError: while scanning a plain scalar
in "<unicode string>", line 1, column 5
found unexpected ':'
in "<unicode string>", line 1, column 6
Switching pure=True results in a successful parse:
{'a': 'b:c'}
This reproduces in Docker:
$ docker run -it --rm python:3.13 bash
root@37cc7ba4252d:/# pip install ruamel.yaml
Collecting ruamel.yaml
Downloading ruamel.yaml-0.18.16-py3-none-any.whl.metadata (25 kB)
Collecting ruamel.yaml.clib>=0.2.7 (from ruamel.yaml)
Downloading ruamel_yaml_clib-0.2.15-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.metadata (3.5 kB)
Downloading ruamel.yaml-0.18.16-py3-none-any.whl (119 kB)
Downloading ruamel_yaml_clib-0.2.15-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (748 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 748.0/748.0 kB 9.6 MB/s 0:00:00
Installing collected packages: ruamel.yaml.clib, ruamel.yaml
Successfully installed ruamel.yaml-0.18.16 ruamel.yaml.clib-0.2.15
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.
root@37cc7ba4252d:/# python3
Python 3.13.10 (main, Dec 3 2025, 01:15:11) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ruamel.yaml
... yaml = ruamel.yaml.YAML(typ="safe", pure=False)
... print(yaml.load("{a: b:c}"))
...
Traceback (most recent call last):
File "<python-input-0>", line 3, in <module>
print(yaml.load("{a: b:c}"))
~~~~~~~~~^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/ruamel/yaml/main.py", line 453, in load
return constructor.get_single_data()
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/usr/local/lib/python3.13/site-packages/ruamel/yaml/constructor.py", line 117, in get_single_data
node = self.composer.get_single_node()
File "_ruamel_yaml.pyx", line 703, in ruamel.yaml.clib._ruamel_yaml.CParser.get_single_node
File "_ruamel_yaml.pyx", line 904, in ruamel.yaml.clib._ruamel_yaml.CParser._parse_next_event
ruamel.yaml.scanner.ScannerError: while scanning a plain scalar
in "<unicode string>", line 1, column 5
found unexpected ':'
in "<unicode string>", line 1, column 6
Hi Edward, thanks for the report.
This is actually a bug in libyaml, which I inherited in
ruamel.yaml.clib, where a fork of the responsible code is located (which gets imported byruamel.yaml)IIRC there is an open issue there for this already. Best thing to do until that is fixed is to quote the scalar that contains the colon.
Ticket moved from /p/ruamel-yaml/tickets/553/
Thanks for having a look Anthon :)
I can't see a similar issue over at https://github.com/yaml/libyaml, do you know if that's the right place to raise this further?
Unfortunately the YAML I'm parsing is generated by another tool (pnpm in this case)
I thought there was a ticket here at
ruamel.yaml.clibalready I have my own fork with some fixes that never made it in libyaml, but not a fix for this one.It might be that I knew of this because of a post on StackOverflow (although I should have made an issue here if that is so).
I tried compiling libyaml (0.2.5) and running locally and didn't have the issue:
Though I don't know if that test runs the code in the same way as your library - do you have any guidance on how I can make a reproducible for upstream?