A YAML 1.2 subset parser built for speed, written in Rust.
Project description
TurboYAML
Subset of YAML 1.2, built for parsing speed. A Rust parser with Rust and Python bindings.
Valid TurboYAML is always valid YAML 1.2. The reverse need not hold — so parse with TurboYAML and fall back to a full YAML parser when you hit something it deliberately doesn't support.
Why
TurboYAML trades YAML's full feature richness for speed, while keeping a useful, real-world feature set alive. On typical config and data it parses roughly 25–45× faster than PyYAML's libyaml C extension, producing native Python objects (dict / list / str / int / float / bool / None) directly — no intermediate tree.
| Profile | turboyaml (Python) | PyYAML (libyaml) | speedup |
|---|---|---|---|
| Flat records | 9.4M lines/s | 372k lines/s | 25× |
| Deep tree | 4.1M lines/s | 111k lines/s | 37× |
| Inline flow collections | 1.5M lines/s | 32k lines/s | 47× |
| Block scalars | 7.2M lines/s | 238k lines/s | 30× |
| Mixed (nested + flow + blocks) | 3.0M lines/s | 90k lines/s | 33× |
Measured on one machine over a randomized corpus that includes quoted/escaped scalars and block scalars; reproduce with cargo run --release --features gen --bin perf_test && python perf_test.py. Speedup is the relative metric; absolute throughput varies with document complexity, but both parsers see the same corpus.
Install
pip install rs-turboyaml
The PyPI distribution is rs-turboyaml; the import name is turboyaml.
Usage
Python
import turboyaml
obj = turboyaml.load(text) # → dict / list / str / int / float / bool / None
# Options (both default False):
# strict=True → raise ParseError on duplicate mapping keys
# yaml_1_1_bools=True → yes/no/on/off/y/n become bool (YAML 1.1 parity)
obj = turboyaml.load(text, yaml_1_1_bools=True)
Fall back to a full parser when a document uses something TurboYAML doesn't cover.
Catch the base TurboYamlError so the fallback also triggers on the handful of
valid-YAML constructs (e.g. multi-line scalars) that surface as ParseError:
try:
obj = turboyaml.load(text) # fast path
except turboyaml.TurboYamlError: # UnsupportedFeatureError or ParseError
import yaml
obj = yaml.safe_load(text) # full parser is the authority
This is safe because TurboYAML never silently returns data that differs from a full parser — for anything it can't handle it raises (checked in CI by a differential against PyYAML on unsupported constructs).
Rust
let value = turboyaml::parse(input)?;
Supported
- Block mappings and sequences, arbitrarily nested
- Compact notation —
- key: value,- - nested - Scalar type inference:
null/~, booleans, integers (decimal /0x/0o), floats (incl..inf/.nan), strings - Quoted strings (single line) — double-quoted with the YAML 1.2 escape set (
\n,\t,\",\uXXXX, …) and single-quoted (literal,''escape) - Flow collections —
[1, 2],{a: 1}— single-line, nestable - Block scalars —
|literal and>folded, with+/-chomping and explicit indentation indicators (|2,>3) #comments- Any scalar type as a mapping key (
42:,True:,null:) - Optional duplicate-key rejection —
load(text, strict=True)/parse_strict
Notable differences from full YAML 1.2
- Indentation is spaces in multiples of two — no tabs, no odd widths.
- Core-schema booleans by default: the three YAML 1.2 spellings of each —
true/True/TRUEandfalse/False/FALSE— are bool; any other casing (tRuE) and the YAML 1.1 wordsyes/no/on/off/y/nare strings. Passyaml_1_1_bools=Trueto opt into full YAML 1.1 boolean parity (those tokens become bool, matching ruamel.yaml's 1.1 resolver). - Quoted strings are single line — for multi-line text, use a block scalar.
- One document per stream; UTF-8 only, no BOM.
Not supported
These raise a typed UnsupportedFeatureError — distinct from a malformed-input ParseError — so the fallback pattern above can recover them cleanly:
- Anchors and aliases —
&anchor,*alias - Tags —
!!str,!custom - Merge keys (
<<:) and explicit/complex keys (? key) - Document markers (
---,...) and directives (%YAML)
Multi-document streams and multi-line quoted/plain scalars are also out of scope (for multi-line text, use a block scalar). These (and the items above) raise rather than silently mis-parse, so the fallback recovers them.
Status
Alpha, but extensively validated. Correctness rests on layered, independent checks, all run in CI:
- Unit + integration tests — hand-written fixtures plus generator round-trips
- A randomized differential fuzz against PyYAML — 70k+ documents, 0 mismatches
- A boundary differential proving TurboYAML raises (never silently diverges) on unsupported constructs — the guarantee that makes the fallback safe
- Exact YAML 1.1 boolean parity with ruamel.yaml (for
yaml_1_1_bools=True) - The official YAML test suite — the supported subset matches its expected output; see docs/yaml-test-suite.md for the conformance breakdown
See spec.md for the normative specification.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rs_turboyaml-0.2.0.tar.gz.
File metadata
- Download URL: rs_turboyaml-0.2.0.tar.gz
- Upload date:
- Size: 86.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3cfd2afac420218798b3114f158dd7ea2f6bd04fb4d3a763ffb1e6686b5d739d
|
|
| MD5 |
f67085d65a622b4c6508e7c33ad8df1d
|
|
| BLAKE2b-256 |
0db0e644a057e85044bb206da73f99f1509aefc7d101364c6efaba67fb1824f8
|
File details
Details for the file rs_turboyaml-0.2.0-cp38-abi3-win_amd64.whl.
File metadata
- Download URL: rs_turboyaml-0.2.0-cp38-abi3-win_amd64.whl
- Upload date:
- Size: 629.5 kB
- Tags: CPython 3.8+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f1fa822f91ea53f84d98e5e4a575e761077b1019d309df148f55074ed6581a5
|
|
| MD5 |
fc42d7eaf6806e802576ac7b2237b8e4
|
|
| BLAKE2b-256 |
399a1dc5ee189b29808bf2b0204ab3f6ee02fe6821f67be116632547ffadb613
|
File details
Details for the file rs_turboyaml-0.2.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: rs_turboyaml-0.2.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 259.3 kB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
afb40bc17f75aab29c7d053b69bcbc79f25c0a9027a7d7a6da693ad693123d6a
|
|
| MD5 |
edb516ae8f6c6b0e923bbd3b3aa9ad32
|
|
| BLAKE2b-256 |
1076cbf3bdb3db7cac4a9ff5c11ddd91e42c665423dcb6f16d596298ff0bf04e
|
File details
Details for the file rs_turboyaml-0.2.0-cp38-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: rs_turboyaml-0.2.0-cp38-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 653.7 kB
- Tags: CPython 3.8+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bde306086b36027e061050f08133e070ef37b41b142a74437a9ea4d91abe5bef
|
|
| MD5 |
03489e148a068e9fd505065a2a1d737f
|
|
| BLAKE2b-256 |
16c2e8fc5d7af18d2d862787d41f135638a5418c7454a2f97ee3716fa19f0f4f
|
File details
Details for the file rs_turboyaml-0.2.0-cp38-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: rs_turboyaml-0.2.0-cp38-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 653.8 kB
- Tags: CPython 3.8+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4f6cf1676d848187d67a0c958ff6335a38f0c109c006e8b90c4a3a844fda164
|
|
| MD5 |
e75002f1af6b46533c999bd76b364068
|
|
| BLAKE2b-256 |
3651645a9f77fb638ab3a837cad729a3beec295859e09ceee91f3811d6dc9c71
|