Skip to content

Migration compatibility

YAMLRocks is meant to be easy to adopt, but YAML compatibility is not one thing. Projects usually depend on a mix of library API, schema behavior, parser leniency, custom tags, error reporting, and formatting. This page makes those layers explicit so a migration can be planned without surprises.

The short version: the safe PyYAML surface has a compatibility shim, ruamel-style round-trip editing has a direct YAMLRocks workflow, and YAML 1.1-era booleans can be read deliberately. The work before 1.0 is mostly real downstream testing: finding which PyYAML quirks projects accidentally rely on, then deciding whether YAMLRocks should support them, warn about them, or reject them with clear docs.

YAMLRocks tries to keep the default path as pure and predictable as possible: YAML 1.2 semantics, safe loading, spec-compliant parsing, and round-trip preservation when requested. That does not mean every project has to adopt those defaults all at once.

The OPT_* flags are the compatibility surface. They let a project opt into the behavior it needs for migration, legacy configuration, or domain-specific tags without weakening the default behavior for everyone else. A project can keep using PyYAML’s practical behavior, even where it differs from strict YAML 1.1, by enabling OPT_PYYAML_COMPAT. Another project can choose strict YAML 1.1 with OPT_YAML_1_1, or read legacy 1.1 spellings while writing canonical 1.2 with OPT_UPGRADE_1_1.

In other words: YAMLRocks is opinionated by default, but configurable on purpose. See the options reference for the full flag surface.

AreaStatusMigration path
PyYAML safe loadingCompatible for common safe_load useUse yamlrocks.compat.safe_load or native yamlrocks.loads
PyYAML safe dumpingCompatible through shimUse yamlrocks.compat.safe_dump for str output and PyYAML-style sorting
PyYAML unsafe object tagsIntentionally not supportedReplace unsafe constructors with explicit tags or tag_handler callbacks
PyYAML 1.1 booleansSupported with optionsUse OPT_PYYAML_COMPAT for PyYAML’s boolean set, or OPT_YAML_1_1 for spec 1.1
PyYAML parser leniencyCase by case before 1.0Test real configs; use documented compatibility paths where they exist
PyYAML alias object identitySupported on rich pathsUse OPT_ANNOTATED, OPT_ROUND_TRIP, or custom-tag paths when identity matters
ruamel safe load/dumpCompatible conceptuallyUse native loads, load, dumps, and dump
ruamel round-trip editingSupported with different APIUse OPT_ROUND_TRIP, YAMLRocksDocument, YAMLRocksDocumentView, and YAMLRocksNode
ruamel fine-grained comment editingNot equivalent yetYAMLRocks preserves comments, but does not expose a full .ca-style authoring API
Application tagsSupported explicitlyUse tags, tag_handler, OPT_PASSTHROUGH_TAG, or domain flags such as OPT_INCLUDES
Source locationsSupportedUse OPT_ANNOTATED, round-trip YAMLRocksNode handles, and structured exceptions
Includes and secretsSupported with trust-boundary flagsEnable only the tags a document is trusted to use

PyYAML compatibility has three useful levels.

NeedUseNotes
Drop-in safe APIimport yamlrocks.compat as yamlKeeps safe_dump returning str and accepts common PyYAML keyword arguments.
Native fast APIyamlrocks.loads / yamlrocks.dumpsFaster and smaller, but dumps returns bytes and YAML 1.2 is the default.
Legacy scalar behaviorOPT_PYYAML_COMPATReads PyYAML’s off-spec boolean set, useful for Home Assistant, ESPHome, and Ansible style migrations.

OPT_YAML_1_1 follows the YAML 1.1 specification. OPT_PYYAML_COMPAT follows PyYAML’s practical behavior where words like yes, no, on, and off are booleans, but single-letter y and n stay strings. That difference matters for real configurations that use y as a coordinate or ordinary key.

import yamlrocks
source = """
y: 2
on: 5
"""
yamlrocks.loads(source, option=yamlrocks.OPT_YAML_1_1)
# {True: 5}
yamlrocks.loads(source, option=yamlrocks.OPT_PYYAML_COMPAT)
# {'y': 2, True: 5}

For a gradual migration, combine compatibility reading with the upgrade path:

  • use OPT_YAML_1_1_WARN to discover values that behave differently between schemas;
  • use OPT_UPGRADE_1_1 when you want to accept old spellings while writing back canonical YAML 1.2;
  • use OPT_PYYAML_COMPAT when the project is migrating from PyYAML behavior, not strict YAML 1.1 behavior.

See YAML 1.1 vs 1.2 for the scalar details.

PyYAML accepts some inputs that are not valid YAML according to the spec. Some projects accidentally rely on this because PyYAML has been the default library for a long time. These cases are the migration edges that need real-world battle testing before 1.0.

PatternYAMLRocks positionMigration note
Comments not preceded by whitespaceRejects as invalid YAMLAdd whitespace before # or quote the value when # is data.
Multi-line quoted scalar continuations at the block indentRejects as invalid YAMLIndent continuation lines past the parent block.
Flow collection content not indented past the surrounding blockRejects as invalid YAMLRe-indent the flow collection or use block style.
Template files with .yaml extensionNot standalone YAMLRender with the owning tool first, or exclude from parser-level checks.
Unknown application tagsPreserved or passed through by opt-inRegister handlers only for tags the application wants to interpret.

These are not all permanent decisions. For each real downstream project, the question is whether a compatibility mode would make migration safer without weakening the parser’s default correctness and security.

ruamel.yaml users usually migrate for speed while keeping comment-preserving edits. YAMLRocks is closest when the workflow starts from an existing file, changes values, and writes the same document back.

NeedYAMLRocks supportNotes
Preserve comments and formattingOPT_ROUND_TRIPUnmodified documents re-emit byte-for-byte.
Edit mapping and sequence valuesYAMLRocksDocument and YAMLRocksDocumentViewNormal indexing and assignment write through to the AST.
Inspect anchors, tags, comments, and locationsYAMLRocksNode handlesUse YAMLRocksDocument.node or YAMLRocksDocumentView.node.
Build commented documents from scratchLimited before 1.0Preserve-and-edit is the primary target today.
Move or author individual commentsLimited before 1.0ruamel’s .ca API is still more complete here.

See Migrating from ruamel.yaml and Round-trip editing for the editing workflow.

For a project currently using PyYAML or ruamel.yaml, start with a shadow run instead of replacing the parser outright.

  1. Load the same files with the current library and YAMLRocks.
  2. Compare the resulting native values for the paths that matter to the application.
  3. For config editors, load with OPT_ROUND_TRIP and confirm unmodified files write back byte-for-byte.
  4. Enable OPT_YAML_1_1_WARN or OPT_PYYAML_COMPAT when migrating from PyYAML and inspect scalar warnings.
  5. Record any PyYAML leniency cases separately from real parser bugs.

When a migration depends on behavior outside strict YAML, please open an issue with the smallest file that demonstrates it. Those reports are exactly what should shape the 1.0 compatibility contract.