{"id":259,"library":"pyyaml","title":"PyYAML","description":"PyYAML is a YAML 1.1 parser and emitter for Python, providing safe and unsafe loaders, a complete Unicode-aware parser, pickle-compatible serialisation, and a capable extension API for custom tags and representers. Current version is 6.0.3 (released September 2025), which adds Python 3.14 and experimental free-threading support. The 6.x line follows an irregular maintenance cadence with patch releases typically spaced 1–2 years apart; a 7.0 dev branch exists but has no published release date.","status":"active","version":"6.0.3","language":"python","source_language":"en","source_url":"https://github.com/yaml/pyyaml","tags":["yaml","parser","serialization","configuration","markup","data-formats"],"install":[{"cmd":"pip install pyyaml","lang":"bash","label":"pip (pure Python + optional C extension)"},{"cmd":"pip install pyyaml libyaml","lang":"bash","label":"pip with explicit libyaml (faster C bindings)"}],"dependencies":[{"reason":"Optional C extension (LibYAML) that significantly speeds up parsing and emitting. PyYAML falls back to pure Python if not present.","package":"libyaml","optional":true}],"imports":[{"note":"The PyPI slug is 'pyyaml' but the Python package name is 'yaml'. Importing 'pyyaml' raises ModuleNotFoundError.","wrong":"import pyyaml","symbol":"yaml","correct":"import yaml"},{"note":"yaml.load() without a Loader raises TypeError in 6.0+; even with Loader=yaml.FullLoader it was vulnerable to RCE before 5.4. Always prefer safe_load() for untrusted input.","wrong":"yaml.load(stream)","symbol":"yaml.safe_load","correct":"import yaml\ndata = yaml.safe_load(stream)"},{"note":"safe_dump() does not accept a Dumper kwarg; use yaml.dump(data, Dumper=yaml.SafeDumper) if you need to pass one explicitly.","symbol":"yaml.safe_dump","correct":"import yaml\ntext = yaml.safe_dump(data, allow_unicode=True)"},{"note":"Base exception for all PyYAML parse and emit errors; catch this rather than bare Exception for YAML-specific error handling.","symbol":"yaml.YAMLError","correct":"from yaml import YAMLError"},{"note":"Returns a generator; the file/stream must remain open for the entire iteration. Consuming outside the 'with' block silently returns no documents.","symbol":"yaml.safe_load_all","correct":"import yaml\nfor doc in yaml.safe_load_all(stream): ..."}],"quickstart":{"code":"import yaml\n\n# --- Parse YAML (safe, no arbitrary code execution) ---\nraw = \"\"\"\nservice:\n  host: localhost\n  port: 8080\n  debug: false\ntags:\n  - web\n  - api\n\"\"\"\n\nconfig = yaml.safe_load(raw)\nprint(config['service']['host'])   # 'localhost'\nprint(config['service']['port'])   # 8080  (int, not str)\nprint(type(config['service']['debug']))  # <class 'bool'>\n\n# --- Dump back to YAML text ---\noutput = yaml.safe_dump(config, allow_unicode=True, sort_keys=False)\nprint(output)\n\n# --- Load multiple documents ---\nmulti = \"\"\"\n---\nname: alpha\n---\nname: beta\n\"\"\"\nimport io\ndocs = list(yaml.safe_load_all(io.StringIO(multi)))\nprint(docs)  # [{'name': 'alpha'}, {'name': 'beta'}]\n\n# --- Error handling ---\ntry:\n    yaml.safe_load(\"key: [unclosed\")\nexcept yaml.YAMLError as exc:\n    print(f\"Parse error: {exc}\")\n","lang":"python","description":"Round-trip: parse a YAML config string then dump it back to YAML text, with safe loader/dumper throughout."},"warnings":[{"fix":"Replace yaml.load(data) with yaml.safe_load(data) for plain data, or yaml.load(data, Loader=yaml.SafeLoader) if you must use load().","message":"yaml.load() now requires an explicit Loader argument. Calling yaml.load(data) without Loader raises TypeError in 6.0+. Previously it issued a DeprecationWarning (5.1–5.4) before becoming a hard error.","severity":"breaking","affected_versions":"<6.0"},{"fix":"Always use yaml.safe_load() or yaml.safe_load_all() for any input not fully controlled by the application. Never pass Loader=yaml.Loader (UnsafeLoader) on untrusted data.","message":"yaml.load() / yaml.full_load() with FullLoader were vulnerable to arbitrary code execution (CVE-2020-14343) on untrusted input in versions before 5.4. yaml.Loader (UnsafeLoader) remains dangerous in all versions.","severity":"breaking","affected_versions":"<5.4"},{"fix":"Quote string values that look like booleans or octal numbers (e.g., 'NO', '0755'). Use explicit !!str tags if quoting is not possible.","message":"PyYAML implements YAML 1.1, not YAML 1.2. Values like 'yes', 'no', 'on', 'off', 'true', 'false' (all case variants) are parsed as booleans. The two-letter country code 'NO' becomes Python False. Octal literals use the 0777 syntax (not 0o777). These differ from YAML 1.2 and JSON.","severity":"gotcha","affected_versions":"all"},{"fix":"Pass allow_unicode=True to yaml.safe_dump() or yaml.dump() to emit UTF-8 characters directly.","message":"yaml.safe_dump() escapes non-ASCII characters to \\uXXXX by default, making UTF-8 content unreadable in the output file.","severity":"gotcha","affected_versions":"all"},{"fix":"Quote time-like strings explicitly, e.g. '\"1:30\"', or use a YAML 1.2-compliant library such as ruamel.yaml.","message":"Sexagesimal (base-60) number parsing: a YAML 1.1 value like '1:30' is parsed as the integer 90, not a string. This silently corrupts time-string fields.","severity":"gotcha","affected_versions":"all"},{"fix":"Consume the generator inside the 'with' block, or eagerly materialise it with list(yaml.safe_load_all(f)) before the block exits.","message":"yaml.safe_load_all() returns a lazy generator. If the stream is closed before the generator is exhausted (e.g., outside a 'with' block), iteration silently yields nothing or raises an error.","severity":"gotcha","affected_versions":"all"},{"fix":"Configure editors to expand tabs to spaces for .yaml/.yml files. Use a linter (yamllint) in CI to catch tab indentation early.","message":"Tabs are not valid YAML indentation. Files indented with tabs instead of spaces raise a yaml.scanner.ScannerError that can be cryptic to diagnose.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure the libyaml development package (e.g., 'libyaml-dev' on Debian/Ubuntu, 'libyaml-devel' on RHEL/Fedora) is installed on the system before attempting to install PyYAML via pip.","message":"PyYAML's C extensions, which provide significant performance, require the libyaml C library to be present during installation. If libyaml is not installed on the system, pip may fail to find a suitable wheel or compile the extensions from source, leading to installation errors such as 'ERROR: Could not find a version that satisfies the requirement libyaml' or compilation failures.","severity":"breaking","affected_versions":"all"},{"fix":"Ensure the 'libyaml' development packages are installed in the system environment. For Alpine Linux, use 'apk add libyaml-dev'. For Debian/Ubuntu, use 'apt-get install libyaml-dev'. For Fedora/RHEL, use 'yum install libyaml-devel' or 'dnf install libyaml-devel'.","message":"PyYAML's installation can fail if the 'libyaml' C library development packages are not available in the system environment. This is especially true when a pre-built wheel is not available for the specific Python version and OS (e.g., musllinux/Alpine), forcing a source build that requires libyaml headers. The error 'ERROR: Could not find a version that satisfies the requirement libyaml' or 'No matching distribution found for libyaml' often points to this issue.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"search_vec":"'1':68 '1.1':6 '2':69 '2025':43 '3.14':47 '6':55 '6.0.3':40 '7.0':73 'add':45 'apart':71 'api':31 'awar':21 'branch':75 'cadenc':62 'capabl':29 'compat':25 'complet':18 'configur':86 'current':37 'custom':33 'data':89 'data-format':88 'date':82 'dev':74 'emitt':9 'exist':76 'experiment':49 'extens':30 'follow':58 'format':90 'free':51 'free-thread':50 'irregular':60 'line':57 'loader':16 'mainten':61 'markup':87 'parser':7,22,84 'patch':64 'pickl':24 'pickle-compat':23 'provid':12 'publish':80 'python':11,46 'pyyaml':1,2 'releas':41,65,81 'represent':36 'safe':13 'septemb':42 'serial':85 'serialis':26 'space':67 'support':53 'tag':34 'thread':52 'typic':66 'unicod':20 'unicode-awar':19 'unsaf':15 'version':38 'x':56 'yaml':5,83 'year':70","created_at":"2026-03-28T03:56:29.648339+00:00","updated_at":"2026-04-16T20:38:45.401584+00:00","problems":[{"fix":"Explicitly specify a loader, typically `Loader=yaml.SafeLoader` for basic safe parsing or `Loader=yaml.FullLoader` for more features, to suppress the warning and enhance security: `data = yaml.load(yaml_file_content, Loader=yaml.SafeLoader)`","cause":"The `yaml.load()` function was called without explicitly specifying a `Loader` class, triggering a warning that the default `Loader` might be unsafe for untrusted input.","error":"YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated"},{"fix":"Install the library using pip: `pip install PyYAML`","cause":"The PyYAML library is not installed in the current Python environment or the script is attempting to import 'yaml' without it being available.","error":"ModuleNotFoundError: No module named 'yaml'"},{"fix":"Review and correct the YAML syntax in the file or string, ensuring proper indentation, valid key-value structure, and adherence to the YAML specification.","cause":"The YAML content being parsed contains a syntax error, commonly due to incorrect indentation, missing colons, or invalid characters.","error":"yaml.scanner.ScannerError: while scanning a simple key"},{"fix":"Define a custom representer for the specific object type using `yaml.add_representer()` to instruct PyYAML on how to serialize it, or convert the object to a standard Python type that PyYAML can handle before dumping.","cause":"PyYAML attempted to serialize a custom Python object (e.g., an instance of a user-defined class or certain built-in types like sets) for which it has no predefined rule (representer) on how to convert it to YAML.","error":"yaml.representer.RepresenterError: cannot represent an object"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"quickstart_score":80,"quickstart_tag":"verified","pypi_latest":"6.0.3","cli_name":"","cli_version":null,"type":"library","homepage":"https://pyyaml.org/","github":"https://github.com/yaml/pyyaml","docs":"https://pyyaml.org/wiki/PyYAMLDocumentation","changelog":null,"pypi":"https://pypi.org/project/pyyaml/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-27","last_verified":"2026-08-27","next_check":"2026-07-27","install_tag":"verified"}}