{"id":3729,"library":"oyaml","title":"Ordered YAML (oyaml)","description":"oyaml is a drop-in replacement for PyYAML designed to preserve dictionary ordering during YAML loading and dumping. It supports both Python 2 and Python 3 by patching the underlying PyYAML library. The current version is 1.1, with releases occurring infrequently, primarily for compatibility updates with newer PyYAML versions or test suite improvements.","status":"active","version":"1.1","language":"en","source_language":"en","source_url":"https://github.com/wimglenn/oyaml","tags":["yaml","ordereddict","pyyaml","serialization","deserialization","configuration"],"install":[{"cmd":"pip install oyaml","lang":"bash","label":"Install oyaml"}],"dependencies":[{"reason":"oyaml acts as a patch/wrapper around PyYAML to provide ordered dictionary functionality, requiring PyYAML to be installed.","package":"PyYAML"}],"imports":[{"note":"oyaml is intended as a drop-in replacement. Aliasing it as 'yaml' ensures that code expecting PyYAML's interface benefits from oyaml's order-preserving features without modifications. Importing `yaml` directly would use PyYAML, not oyaml.","wrong":"import yaml","symbol":"yaml","correct":"import oyaml as yaml"}],"quickstart":{"code":"import oyaml as yaml\nfrom collections import OrderedDict\n\nyaml_data = \"\"\"\nkey_c: 3\nkey_a: 1\nkey_b: 2\n\"\"\"\n\n# Load YAML preserving order\nloaded_dict = yaml.safe_load(yaml_data)\nprint(f\"Loaded dictionary type: {type(loaded_dict)}\")\nprint(f\"Loaded dictionary keys order: {list(loaded_dict.keys())}\")\n\n# Dump a dictionary with explicit order\nordered_data = OrderedDict([\n    ('first_key', 'value_1'),\n    ('second_key', 'value_2'),\n    ('third_key', 'value_3')\n])\ndumped_yaml = yaml.safe_dump(ordered_data, sort_keys=False)\nprint(f\"\\nDumped YAML with order preserved:\\n{dumped_yaml}\")\n","lang":"python","description":"This quickstart demonstrates how to import oyaml as `yaml` and use its `safe_load` and `safe_dump` functions. It shows that `oyaml` preserves the order of keys when loading from a YAML string and when dumping an `OrderedDict` to a YAML string, by default, if `sort_keys=False` is used for `safe_dump` with standard dictionaries. For Python versions < 3.7, `safe_load` will return `OrderedDict` instances. For Python 3.7+ with standard `dict`s, while `safe_load` might return a standard `dict`, its order is insertion-ordered."},"warnings":[{"fix":"Consider if `oyaml` is truly necessary for new code on Python 3.7+, or if direct `PyYAML` usage with `sort_keys=False` for dumping (if order matters for output) is sufficient. For cross-version compatibility or explicit `OrderedDict` requirements, `oyaml` remains useful.","message":"For Python 3.7 and later, standard dictionaries (`dict`) inherently preserve insertion order. This reduces the primary benefit of `oyaml` for these Python versions when working with standard `dict`s, though `oyaml` still ensures `OrderedDict`s are used or order is strictly maintained across all operations and Python versions.","severity":"gotcha","affected_versions":"Python 3.7+"},{"fix":"Explicitly cast the loaded dictionary to `OrderedDict` if the specific type is required, or ensure your code is robust to handling either `dict` or `OrderedDict` from `FullLoader`.","message":"In `oyaml` v0.8, the behavior for `FullLoader` in CPython 3.6+ was changed to deserialize YAML maps into a standard Python `dict` instead of `collections.OrderedDict`. If your application relied on `FullLoader` returning `OrderedDict` on CPython 3.6+ specifically, this change is breaking.","severity":"breaking","affected_versions":"v0.8+"},{"fix":"Replace all instances of `yaml.load()` with `yaml.safe_load()` when processing input from untrusted sources.","message":"Like PyYAML, it is unsafe to use `yaml.load()` with untrusted input due to the potential for arbitrary code execution. Always prefer `yaml.safe_load()` for security.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}