Skip to main content

A YAML round-trip library that preserves comments and insertion order

Project description

yarutsk

A Python YAML library that round-trips documents while preserving comments and insertion order.

What it does

Most YAML libraries silently drop comments on load. yarutsk keeps them attached to their keys — both inline (key: value # like this) and block-level (# above a key) — so a load → modify → dump cycle leaves the rest of the file intact.

import io
import yarutsk

doc = yarutsk.load(io.StringIO("""
# database config
host: localhost  # primary
port: 5432
"""))

doc["port"] = 5433

out = io.StringIO()
yarutsk.dump(doc, out)
print(out.getvalue())
# # database config
# host: localhost  # primary
# port: 5433

YamlMapping is a subclass of dict and YamlSequence is a subclass of list, so they work everywhere a dict or list is expected:

import json

doc = yarutsk.loads("name: Alice\nscores: [10, 20, 30]")

isinstance(doc, dict)           # True
isinstance(doc["scores"], list) # True
json.dumps(doc)                 # '{"name": "Alice", "scores": [10, 20, 30]}'

Installation

Built with Maturin. From the repo root:

pip install maturin
maturin develop

API

Loading and dumping

# Load from stream (StringIO / BytesIO)
doc  = yarutsk.load(stream)            # first document
docs = yarutsk.load_all(stream)        # all documents as a list

# Load from string
doc  = yarutsk.loads(text)
docs = yarutsk.loads_all(text)

# Dump to stream
yarutsk.dump(doc, stream)
yarutsk.dump_all(docs, stream)

# Dump to string
text = yarutsk.dumps(doc)
text = yarutsk.dumps_all(docs)

load / loads return a YamlMapping, YamlSequence, YamlScalar, or None (for empty input). Nested nodes are also YamlMapping or YamlSequence; scalar leaves are returned as native Python primitives (int, float, bool, str, or None).

YamlScalar

Top-level scalar documents are wrapped in a YamlScalar node:

doc = yarutsk.loads("42")
doc.value                              # 42 (Python int)
doc.to_dict()                          # same as .value

YamlMapping

YamlMapping is a subclass of dict with insertion-ordered keys. All standard dict operations work directly:

# Standard dict interface (inherited)
doc["key"]                             # get (KeyError if missing)
doc["key"] = value                     # set (preserves position if key exists)
del doc["key"]                         # delete
"key" in doc                           # membership test
len(doc)                               # number of entries
for key in doc: ...                    # iterate over keys in order
doc.keys()                             # KeysView in insertion order
doc.values()                           # ValuesView in insertion order
doc.items()                            # ItemsView of (key, value) pairs
doc.get("key")                         # returns None if missing
doc.get("key", default)                # returns default if missing
doc.pop("key")                         # remove & return (KeyError if missing)
doc.pop("key", default)                # remove & return, or default
doc.setdefault("key", default)         # get or insert default
doc.update(other)                      # merge from dict or YamlMapping
doc == {"a": 1}                        # equality comparison

# Works with any dict-expecting library
isinstance(doc, dict)                  # True
json.dumps(doc)                        # works

# Conversion
doc.to_dict()                          # deep conversion to plain Python dict

# Comments
doc.get_comment_inline("key")          # -> str | None
doc.get_comment_before("key")          # -> str | None
doc.set_comment_inline("key", text)
doc.set_comment_before("key", text)

# Sorting
doc.sort_keys()                        # alphabetical, in-place
doc.sort_keys(reverse=True)            # reverse alphabetical
doc.sort_keys(key=lambda k: len(k))    # custom key function on key strings
doc.sort_keys(recursive=True)          # also sort all nested mappings

YamlSequence

YamlSequence is a subclass of list. All standard list operations work directly:

# Standard list interface (inherited)
doc[0]                                 # get by index (negative indices supported)
doc[0] = value                         # set by index
del doc[0]                             # delete by index
value in doc                           # membership test
len(doc)                               # number of items
for item in doc: ...                   # iterate over items
doc.append(value)                      # add to end
doc.insert(idx, value)                 # insert before index
doc.pop()                              # remove & return last item
doc.pop(idx)                           # remove & return item at index
doc.remove(value)                      # remove first occurrence (ValueError if missing)
doc.extend(iterable)                   # append items from list or YamlSequence
doc.index(value)                       # index of first occurrence
doc.count(value)                       # number of occurrences
doc.reverse()                          # reverse in-place
doc == [1, 2, 3]                       # equality comparison

# Works with any list-expecting library
isinstance(doc, list)                  # True
json.dumps(doc)                        # works

# Conversion
doc.to_dict()                          # deep conversion to plain Python list

# Comments (addressed by integer index)
doc.get_comment_inline(idx)            # -> str | None
doc.get_comment_before(idx)            # -> str | None
doc.set_comment_inline(idx, text)
doc.set_comment_before(idx, text)

# Sorting (preserves comment metadata)
doc.sort()                             # natural order, in-place
doc.sort(reverse=True)
doc.sort(key=lambda v: len(v))         # custom key function on item values

Sorting preserves all comments — each entry or item carries its inline and before-key comments with it when reordered.

Running tests

You need Rust (nightly) and Python 3.12+ with uv. Python 3.12 is the minimum — YamlSequence subclasses list, which requires PyO3's extends = PyList support introduced in Python 3.12.

# 1. Clone with the yaml-test-suite submodule
git clone --recurse-submodules https://github.com/theyugin/yarutsk
cd yarutsk

# 2. Create a virtual environment and install dev dependencies
uv sync --group dev

# 3. Build the extension in dev (debug) mode
uv run maturin develop

# 4. Run the suites
uv run pytest tests/ --ignore=tests/test_yaml_suite.py -v  # core library tests
uv run pytest tests/test_yaml_suite.py -q                   # yaml-test-suite compliance

test_yaml_suite.py requires the yaml-test-suite submodule. Tests that fail due to known YAML normalisation differences are marked xfail and do not count as failures.

Internals

The scanner and parser are vendored from yaml-rust2 (MIT licensed) with one targeted modification: the comment-skipping loop in the scanner now emits Comment tokens instead of discarding them. Everything else — block/flow parsing, scalar type coercion, multi-document support — comes from yaml-rust2 unchanged. The builder layer wires those tokens to the data model, and a hand-written block-style emitter serialises it back out.

YamlMapping and YamlSequence are PyO3 pyclasses that extend Python's built-in dict and list types. A Rust inner field stores the full YAML data model (including comments); the parent dict/list is kept in sync on every mutation so that all standard Python operations work transparently.

Disclaimer

This library was created with Claude Code (Anthropic). The design, implementation, tests, and this README were written by Claude under human direction.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

yarutsk-0.0.9.tar.gz (92.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

yarutsk-0.0.9-cp314-cp314-win_amd64.whl (343.5 kB view details)

Uploaded CPython 3.14Windows x86-64

yarutsk-0.0.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (465.2 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

yarutsk-0.0.9-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (878.1 kB view details)

Uploaded CPython 3.14macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

yarutsk-0.0.9-cp313-cp313-win_amd64.whl (346.4 kB view details)

Uploaded CPython 3.13Windows x86-64

yarutsk-0.0.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (467.9 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

yarutsk-0.0.9-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (882.3 kB view details)

Uploaded CPython 3.13macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

yarutsk-0.0.9-cp312-cp312-win_amd64.whl (346.9 kB view details)

Uploaded CPython 3.12Windows x86-64

yarutsk-0.0.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (468.6 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

yarutsk-0.0.9-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (883.0 kB view details)

Uploaded CPython 3.12macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file yarutsk-0.0.9.tar.gz.

File metadata

  • Download URL: yarutsk-0.0.9.tar.gz
  • Upload date:
  • Size: 92.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for yarutsk-0.0.9.tar.gz
Algorithm Hash digest
SHA256 769df5279f16f7567dc532e1e3bebfa6795158835daa635e757763a48c3e1434
MD5 5126e0c4fb7279bc93b8454bd9127ddb
BLAKE2b-256 c6741bfb415c7b94ea33c8dd009de8279a782105ed1d9abb2b42812fa701a3e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for yarutsk-0.0.9.tar.gz:

Publisher: ci.yml on theyugin/yarutsk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yarutsk-0.0.9-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: yarutsk-0.0.9-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 343.5 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for yarutsk-0.0.9-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 b31c4cb255be31d94a83ad3f3c631ccee4c0f586461fd1565a2763d03daf0a19
MD5 ecf3703da7851ce657c39bee2d6aea03
BLAKE2b-256 65ac5fe848fa75c3a6bcd5b279d0775d629cb36bfa3d7a92f0c45ff3b1d42996

See more details on using hashes here.

Provenance

The following attestation bundles were made for yarutsk-0.0.9-cp314-cp314-win_amd64.whl:

Publisher: ci.yml on theyugin/yarutsk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yarutsk-0.0.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for yarutsk-0.0.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 185c40bd2430ad5afe521dc6a4dd17eac3500142c8348a7daf1926023079473e
MD5 7aa1af5adee87da44d561daa15ea5c19
BLAKE2b-256 8ad32b6f7ebc6bcabcd1d7afdb5863a723378c407154676ef8c5bd5914328cbe

See more details on using hashes here.

Provenance

The following attestation bundles were made for yarutsk-0.0.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci.yml on theyugin/yarutsk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yarutsk-0.0.9-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for yarutsk-0.0.9-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 a4053c912f8e6fed38b37729743be9f05213016257ec6992f31968dc3ca6b5d2
MD5 ddca7e13dd216ae860f89c2323ee5bc8
BLAKE2b-256 531bb403d374b843e87c0e8827c75823ca94388f0e77007e7ab63c9467a030dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for yarutsk-0.0.9-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: ci.yml on theyugin/yarutsk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yarutsk-0.0.9-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: yarutsk-0.0.9-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 346.4 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for yarutsk-0.0.9-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 6beaf11ddf4cca4220826dafa8a4567de9a5919b79eefe62d0c802fd1fd2c56a
MD5 8ae371c46a713028558641e347374862
BLAKE2b-256 80ac76cb4e8a2218b53d4ea6eb53f4acaf84ac78f64f97aab0054f84fc7e2125

See more details on using hashes here.

Provenance

The following attestation bundles were made for yarutsk-0.0.9-cp313-cp313-win_amd64.whl:

Publisher: ci.yml on theyugin/yarutsk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yarutsk-0.0.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for yarutsk-0.0.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6518e423d0c97461715d115c01485ed4a2b96d8bd4ee74c5d7e6f53971fd7700
MD5 8091163c0647711b2e1dfd6a877a852b
BLAKE2b-256 9007117ff74a79c7aaa3533edf9def28a4b6a776f98a9b2281002538856f4f57

See more details on using hashes here.

Provenance

The following attestation bundles were made for yarutsk-0.0.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci.yml on theyugin/yarutsk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yarutsk-0.0.9-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for yarutsk-0.0.9-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 0a2d4c92d68d5adbab95ec833592c2ee93976b73e04fb7630556a07cfeb2341c
MD5 7dc1c21dedf63207430d2552f1123d23
BLAKE2b-256 2f9472485bdff6a83c2682e9b58cce08499d85a08192250547844beaefcd5cb0

See more details on using hashes here.

Provenance

The following attestation bundles were made for yarutsk-0.0.9-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: ci.yml on theyugin/yarutsk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yarutsk-0.0.9-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: yarutsk-0.0.9-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 346.9 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for yarutsk-0.0.9-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 b726dbc099a165fc24c93a86d44efbf9a2333382a6519a507807c14b97d560b7
MD5 eb3c199854cb17ceb999492176800a57
BLAKE2b-256 5622fa3b70694b059f82fed6146c0e1f8b2762c4873c5fa072ea0a20b2e286a3

See more details on using hashes here.

Provenance

The following attestation bundles were made for yarutsk-0.0.9-cp312-cp312-win_amd64.whl:

Publisher: ci.yml on theyugin/yarutsk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yarutsk-0.0.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for yarutsk-0.0.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 880fcd213071e9953cf24c3012d8d37aab28849acadb237a2f19388a650b2468
MD5 7e88a9b3716c6f17e24d5727c6283032
BLAKE2b-256 e41ab0c57ac58ea788dc1b1f4f5a4b6d1e62945e3a7873b3d2deb4286d33076a

See more details on using hashes here.

Provenance

The following attestation bundles were made for yarutsk-0.0.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci.yml on theyugin/yarutsk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yarutsk-0.0.9-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for yarutsk-0.0.9-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 ebdfd1e28f565572b4f888378c960ba9b2a6fd09cd8522a27e4d6c4e56e5cd0e
MD5 512b4eefb7c5ec5e2d1c351b79490f88
BLAKE2b-256 1286fcf1b747f3d02d3e191585a505f5a7cf1ac7ecc0d37dbed054319944e26f

See more details on using hashes here.

Provenance

The following attestation bundles were made for yarutsk-0.0.9-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: ci.yml on theyugin/yarutsk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page