{"id":8790,"library":"yamlloader","title":"Ordered YAML Loader and Dumper","description":"yamlloader is a Python library (version 1.6.0) that provides ordered YAML loaders and dumpers for PyYAML, ensuring that the order of items in dictionaries is preserved when loading from or dumping to YAML files. It offers faster C-version implementations and automatically falls back to pure Python versions if C bindings are unavailable. The library is actively maintained, with recent updates for Python 3.14 support.","status":"active","version":"1.6.0","language":"en","source_language":"en","source_url":"https://github.com/Phynix/yamlloader","tags":["YAML","PyYAML","ordered dictionary","configuration","serialization","parser","dumper"],"install":[{"cmd":"pip install yamlloader","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"yamlloader extends and relies on PyYAML for core YAML parsing and serialization functionality. It became an explicit runtime requirement in version 1.5.2.","package":"PyYAML","optional":false}],"imports":[{"note":"The main package import.","symbol":"yamlloader","correct":"import yamlloader"},{"note":"CLoader (and CDumper) are within the 'ordereddict' submodule. Using the C-versions is recommended for performance; they gracefully fall back to pure Python if C bindings are not compiled for PyYAML.","wrong":"from yamlloader import CLoader","symbol":"CLoader","correct":"from yamlloader.ordereddict import CLoader"},{"note":"CDumper for dumping YAML while preserving order, with C-speed if available.","symbol":"CDumper","correct":"from yamlloader.ordereddict import CDumper"},{"note":"yamlloader builds on PyYAML, so the base PyYAML library is often imported alongside it.","symbol":"yaml","correct":"import yaml"}],"quickstart":{"code":"import yaml\nfrom yamlloader.ordereddict import CLoader, CDumper\nimport os\n\nyaml_content = \"\"\"\nkey_a: value_1\nkey_b: value_2\nkey_c: value_3\nlist_items:\n  - item1\n  - item2\n  - item3\n\"\"\"\n\n# Create a dummy YAML file\nwith open('config.yaml', 'w') as f:\n    f.write(yaml_content)\n\n# --- Loading YAML --- \nprint('--- Loading YAML ---')\nwith open('config.yaml', 'r') as f:\n    # Using CLoader to preserve order\n    data = yaml.load(f, Loader=CLoader)\n\nprint(f\"Loaded data type: {type(data)}\")\nprint(f\"Loaded data: {data}\")\n\n# Verify order preservation (Python 3.7+ dicts preserve insertion order by default,\n# but yamlloader explicitly guarantees and was designed around OrderedDict behavior)\nexpected_keys = ['key_a', 'key_b', 'key_c', 'list_items']\nactual_keys = list(data.keys())\nprint(f\"Keys in order: {actual_keys == expected_keys}\")\n\n# --- Dumping YAML --- \nprint('\\n--- Dumping YAML ---')\nmodified_data = data\nmodified_data['new_key'] = 'new_value'\n\noutput_yaml = yaml.dump(modified_data, Dumper=CDumper, default_flow_style=False)\nprint(f\"Dumped YAML:\\n{output_yaml}\")\n\n# Clean up dummy file\nos.remove('config.yaml')","lang":"python","description":"This quickstart demonstrates how to load and dump YAML content using `yamlloader`'s `CLoader` and `CDumper` to ensure dictionary order is preserved. It highlights how `yaml.load` is used with the custom loader and how the order is maintained in the resulting Python object, even for standard dictionaries in Python 3.7+."},"warnings":[{"fix":"Upgrade Python to 3.8+ or pin `yamlloader` to `<1.3.0` for Python 3.7 environments.","message":"Support for Python 3.7 was dropped in `yamlloader` version 1.3.2. Users on Python 3.7 must use `yamlloader` version 1.2 or older. Later versions require Python 3.8+.","severity":"breaking","affected_versions":">=1.3.2"},{"fix":"Always explicitly specify a loader when calling `yaml.load()`. For safe loading of untrusted input, use `yaml.safe_load()` or `yaml.load(file, Loader=yaml.SafeLoader)`. When using `yamlloader`, ensure you pass its specific loaders: `yaml.load(file, Loader=yamlloader.ordereddict.CLoader)` or `yaml.load(file, Loader=yamlloader.ordereddict.CSafeLoader)`.","message":"PyYAML's `yaml.load()` function without an explicit `Loader` argument (e.g., `yaml.load(file_obj)`) has been deprecated since PyYAML 5.1 due to security concerns, as it could lead to arbitrary code execution when processing untrusted YAML. While `yamlloader`'s examples always specify a Loader, users might accidentally revert to the insecure pattern.","severity":"deprecated","affected_versions":"PyYAML >=5.1"},{"fix":"For consistent ordered dictionary behavior, ensure you are using `yamlloader` version `1.0.0` or newer. For Python 3.7+, standard `dict`s preserve insertion order, but explicit `OrderedDict`s or `yamlloader`'s wrappers provide a stronger guarantee and consistent API.","message":"While `yamlloader` explicitly uses `OrderedDict` internally (and `dict` for Python 3.7+ as `dict` preserves insertion order), prior to `yamlloader 1.0.0`, it might have behaved differently with Python 3.7+ native `dict` ordering. Since `1.0.0`, it consistently returns `OrderedDict` or order-preserving `dict` for all supported Python versions.","severity":"gotcha","affected_versions":"<1.0.0"},{"fix":"To ensure C-version performance, install `libyaml-dev` (or equivalent for your OS) and `Cython` before installing PyYAML or `yamlloader`. Check `yaml.cyaml` exists in your environment to verify C-binding availability.","message":"yamlloader leverages PyYAML's C-bindings for performance (`CLoader`, `CDumper`). If PyYAML was installed without C extensions (e.g., missing `libyaml-dev` or `Cython`), these C-versions will automatically fall back to their pure Python equivalents. This fallback is usually seamless but can hide performance issues. You can disable this fallback by setting `yamlloader.settings.ALLOW_C_VERSION_FALLBACK = False` which will cause an error if C-versions are unavailable.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Install PyYAML: `pip install pyyaml` (or simply `pip install yamlloader` which should pull in PyYAML as a dependency).","cause":"The underlying PyYAML library, which `yamlloader` depends on, is not installed.","error":"ModuleNotFoundError: No module named 'yaml'"},{"fix":"Always provide a `Loader` argument. For `yamlloader`'s ordered loading, use `yaml.load(file_obj, Loader=yamlloader.ordereddict.CLoader)`. For general safe loading, use `yaml.safe_load(file_obj)` or `yaml.load(file_obj, Loader=yaml.SafeLoader)`.","cause":"You are calling PyYAML's `yaml.load()` function without explicitly specifying a `Loader` class. This warning is from PyYAML itself, which `yamlloader` uses.","error":"YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://pyyaml.readthedocs.io/en/latest/api.html#yamllib-org-api"},{"fix":"For extremely large YAML files, consider processing them in chunks if the structure allows, or using alternative streaming parsers not offered by `yamlloader`/`PyYAML`. Ensure your system has sufficient RAM for the file size.","cause":"Attempting to load a very large YAML file (e.g., several gigabytes) into memory at once, potentially exceeding available RAM.","error":"MemoryError: cannot allocate vector of size ..."},{"fix":"Replace all tab characters with spaces for indentation in your YAML file. Many text editors have 'convert tabs to spaces' functionality. Ensure consistent indentation levels (e.g., always 2 or 4 spaces).","cause":"YAML syntax is very strict about indentation. This error typically means you've used a tab character for indentation where spaces are required, or there's an inconsistent mix of tabs and spaces.","error":"yaml.scanner.ScannerError: while scanning for the next token found character '\\t' that cannot start any token in \"<string>\", line X, column Y"}]}