Python's PyYAML library handles YAML parsing and generation. Always use yaml.safe_load() for untrusted input — never yaml.load() without a Loader. ruamel.yaml preserves comments and round-trips perfectly.
| Item | Syntax / Value | Description |
|---|---|---|
| yaml.safe_load | yaml.safe_load(stream) → dict/list/str | Parse YAML string/file safely — always use this |
| yaml.safe_load_all | yaml.safe_load_all(stream) → generator | Parse multi-document YAML file |
| yaml.load | yaml.load(stream, Loader=yaml.SafeLoader) | Parse YAML with explicit Loader |
| yaml.dump | yaml.dump(data, default_flow_style=False) → str | Serialize Python object to YAML |
| yaml.dump_all | yaml.dump_all([d1,d2], stream) | Serialize multiple documents |
| yaml.safe_dump | yaml.safe_dump(data) → str | Serialize safely (no Python-specific tags) |
| stream parameter | open('file.yaml') | safe_load/dump accepts file-like objects |
| default_flow_style | yaml.dump(data, default_flow_style=False) | False = block style, True = flow/inline |
| indent | yaml.dump(data, indent=2) | Set indentation spaces |
| sort_keys | yaml.dump(data, sort_keys=True) | Sort mapping keys alphabetically |
| allow_unicode | yaml.dump(data, allow_unicode=True) | Allow non-ASCII characters directly |
| width | yaml.dump(data, width=80) | Line wrapping width |
| YAMLError | except yaml.YAMLError as e: | Base exception for parse errors |
| ruamel.yaml | from ruamel.yaml import YAML | Round-trip parser — preserves comments |
| YAML() | yaml = YAML(); yaml.preserve_quotes = True | ruamel.yaml instance |
| yaml.load(file) | data = yaml.load(open('f.yaml')) | ruamel: load preserving comments |
| yaml.dump(data,file) | yaml.dump(data, open('f.yaml','w')) | ruamel: dump preserving structure |
| yaml.indent | yaml.indent(mapping=2, sequence=4) | ruamel: fine-grained indent control |
| !custom tag | Representer/Constructor for custom types | Add custom YAML tags |
import yaml
from pathlib import Path
# ── 1. Load YAML string ───────────────────────────────────────
yaml_text = """
name: Alice Smith
age: 30
gpa: 3.95
active: true
languages:
- Python
- Go
- JavaScript
address:
city: Techville
state: CA
courses:
- id: CS101
title: Python Programming
credits: 3
grade: A
- id: CS201
title: JavaScript & Node.js
credits: 3
grade: A-
"""
data = yaml.safe_load(yaml_text)
print(f"Name: {data['name']}")
print(f"GPA: {data['gpa']}")
print(f"Langs: {', '.join(data['languages'])}")
print(f"City: {data['address']['city']}")
print(f"Courses: {len(data['courses'])}")
# ── 2. Dump to YAML ───────────────────────────────────────────
new_student = {
'name': 'Bob Jones',
'age': 25,
'gpa': 3.72,
'active': True,
'languages': ['Rust', 'Go'],
'address': {'city': 'Springfield', 'state': 'IL'}
}
yaml_out = yaml.dump(new_student, default_flow_style=False,
allow_unicode=True, sort_keys=False, indent=2)
print("\n--- Generated YAML ---")
print(yaml_out)
# ── 3. File I/O ───────────────────────────────────────────────
Path("student.yaml").write_text(yaml_text)
with open("student.yaml") as f:
loaded = yaml.safe_load(f)
print(f"Loaded from file: {loaded['name']}")
# ── 4. Multi-document YAML ────────────────────────────────────
multi = """
---
name: Alice
role: admin
---
name: Bob
role: user
---
name: Carol
role: moderator
"""
docs = list(yaml.safe_load_all(multi))
for doc in docs:
print(f" {doc['name']:10s} ({doc['role']})")
# ── 5. Error handling ─────────────────────────────────────────
for test in ["valid: yaml", "invalid: yaml: here", "key: [unclosed"]:
try:
result = yaml.safe_load(test)
print(f" ✅ Parsed: {result}")
except yaml.YAMLError as e:
print(f" ❌ Error: {e.problem if hasattr(e,'problem') else e}")
# ── 6. Custom dump options ────────────────────────────────────
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
# Register representer for custom class
def student_representer(dumper, data):
return dumper.represent_mapping('!student', {
'name': data.name, 'score': data.score
})
yaml.add_representer(Student, student_representer)
students = [Student('Alice', 95), Student('Bob', 87)]
print("\nCustom class YAML:")
print(yaml.dump(students, default_flow_style=False))
Path("student.yaml").unlink(missing_ok=True)
# python3 yaml_demo.py (pip install pyyaml)