PyYAML
raw JSON → 6.0.3 verified Tue May 12 auth: no python install: verified quickstart: verified
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.
pip install pyyaml Common errors
error YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated ↓
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.
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) error ModuleNotFoundError: No module named 'yaml' ↓
cause The PyYAML library is not installed in the current Python environment or the script is attempting to import 'yaml' without it being available.
fix
Install the library using pip:
pip install PyYAML error yaml.scanner.ScannerError: while scanning a simple key ↓
cause The YAML content being parsed contains a syntax error, commonly due to incorrect indentation, missing colons, or invalid characters.
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.
error yaml.representer.RepresenterError: cannot represent an object ↓
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.
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. Warnings
breaking 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. ↓
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().
breaking 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. ↓
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.
gotcha 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. ↓
fix Quote string values that look like booleans or octal numbers (e.g., 'NO', '0755'). Use explicit !!str tags if quoting is not possible.
gotcha yaml.safe_dump() escapes non-ASCII characters to \uXXXX by default, making UTF-8 content unreadable in the output file. ↓
fix Pass allow_unicode=True to yaml.safe_dump() or yaml.dump() to emit UTF-8 characters directly.
gotcha 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. ↓
fix Quote time-like strings explicitly, e.g. '"1:30"', or use a YAML 1.2-compliant library such as ruamel.yaml.
gotcha 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. ↓
fix Consume the generator inside the 'with' block, or eagerly materialise it with list(yaml.safe_load_all(f)) before the block exits.
gotcha Tabs are not valid YAML indentation. Files indented with tabs instead of spaces raise a yaml.scanner.ScannerError that can be cryptic to diagnose. ↓
fix Configure editors to expand tabs to spaces for .yaml/.yml files. Use a linter (yamllint) in CI to catch tab indentation early.
breaking 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. ↓
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.
breaking 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. ↓
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'.
Install
pip install pyyaml libyaml Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.09s 19.9M
3.10 alpine (musl) - - - -
3.10 slim (glibc) - - 0.05s 21M
3.10 slim (glibc) - - - -
3.11 alpine (musl) - - 0.25s 21.9M
3.11 alpine (musl) - - - -
3.11 slim (glibc) - - 0.20s 23M
3.11 slim (glibc) - - - -
3.12 alpine (musl) - - 0.15s 13.8M
3.12 alpine (musl) - - - -
3.12 slim (glibc) - - 0.17s 15M
3.12 slim (glibc) - - - -
3.13 alpine (musl) - - 0.14s 13.5M
3.13 alpine (musl) - - - -
3.13 slim (glibc) - - 0.16s 15M
3.13 slim (glibc) - - - -
3.9 alpine (musl) - - 0.07s 19.4M
3.9 alpine (musl) - - - -
3.9 slim (glibc) - - 0.07s 21M
3.9 slim (glibc) - - - -
Imports
- yaml wrong
import pyyamlcorrectimport yaml - yaml.safe_load wrong
yaml.load(stream)correctimport yaml data = yaml.safe_load(stream) - yaml.safe_dump
import yaml text = yaml.safe_dump(data, allow_unicode=True) - yaml.YAMLError
from yaml import YAMLError - yaml.safe_load_all
import yaml for doc in yaml.safe_load_all(stream): ...
Quickstart verified last tested: 2026-04-23
import yaml
# --- Parse YAML (safe, no arbitrary code execution) ---
raw = """
service:
host: localhost
port: 8080
debug: false
tags:
- web
- api
"""
config = yaml.safe_load(raw)
print(config['service']['host']) # 'localhost'
print(config['service']['port']) # 8080 (int, not str)
print(type(config['service']['debug'])) # <class 'bool'>
# --- Dump back to YAML text ---
output = yaml.safe_dump(config, allow_unicode=True, sort_keys=False)
print(output)
# --- Load multiple documents ---
multi = """
---
name: alpha
---
name: beta
"""
import io
docs = list(yaml.safe_load_all(io.StringIO(multi)))
print(docs) # [{'name': 'alpha'}, {'name': 'beta'}]
# --- Error handling ---
try:
yaml.safe_load("key: [unclosed")
except yaml.YAMLError as exc:
print(f"Parse error: {exc}")