0
# Loaders and Dumpers
1
2
Configurable loader and dumper classes that combine different processing components for customized YAML processing. These classes provide fine-grained control over the YAML processing pipeline.
3
4
## Capabilities
5
6
### Loader Classes
7
8
Loader classes combine Reader, Scanner, Parser, Composer, Constructor, and Resolver components to provide complete YAML loading functionality.
9
10
```python { .api }
11
class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver):
12
"""
13
Basic loader combining fundamental processing components.
14
15
Constructor parameters:
16
- stream: Input stream to read from
17
"""
18
19
class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Resolver):
20
"""
21
Safe loader for trusted YAML input.
22
23
Only constructs standard YAML tags, preventing arbitrary code execution.
24
Recommended for loading YAML from untrusted sources.
25
26
Constructor parameters:
27
- stream: Input stream to read from
28
"""
29
30
class FullLoader(Reader, Scanner, Parser, Composer, FullConstructor, Resolver):
31
"""
32
Full-featured loader with extended Python object support.
33
34
Supports Python objects like tuples, sets, and other built-in types
35
while remaining safer than UnsafeLoader.
36
37
Constructor parameters:
38
- stream: Input stream to read from
39
"""
40
41
class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver):
42
"""
43
Legacy loader class (alias for SafeLoader in modern PyYAML).
44
45
Constructor parameters:
46
- stream: Input stream to read from
47
"""
48
49
class UnsafeLoader(Reader, Scanner, Parser, Composer, Constructor, Resolver):
50
"""
51
Unsafe loader allowing arbitrary Python object construction.
52
53
WARNING: Can execute arbitrary Python code. Only use with trusted input.
54
55
Constructor parameters:
56
- stream: Input stream to read from
57
"""
58
```
59
60
### Dumper Classes
61
62
Dumper classes combine Emitter, Serializer, Representer, and Resolver components to provide complete YAML dumping functionality.
63
64
```python { .api }
65
class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver):
66
"""
67
Basic dumper combining fundamental processing components.
68
69
Constructor parameters:
70
- stream: Output stream to write to
71
- default_style: Default scalar style
72
- default_flow_style: Default collection style
73
- canonical: Produce canonical YAML
74
- indent: Indentation spaces
75
- width: Maximum line width
76
- allow_unicode: Allow unicode characters
77
- line_break: Line break character
78
- encoding: Output encoding
79
- explicit_start: Add document start marker
80
- explicit_end: Add document end marker
81
- version: YAML version
82
- tags: Tag handle mappings
83
- sort_keys: Sort mapping keys
84
"""
85
86
class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver):
87
"""
88
Safe dumper for standard Python types.
89
90
Only represents standard Python types, preventing arbitrary code serialization.
91
Recommended for general YAML output.
92
93
Constructor parameters: (same as BaseDumper)
94
"""
95
96
class Dumper(Emitter, Serializer, Representer, Resolver):
97
"""
98
Full-featured dumper with extended Python object support.
99
100
Can represent complex Python objects including functions and classes.
101
102
Constructor parameters: (same as BaseDumper)
103
"""
104
```
105
106
## Usage Examples
107
108
### Custom Loader Usage
109
110
```python
111
import yaml
112
from io import StringIO
113
114
yaml_content = """
115
name: John Doe
116
age: 30
117
skills:
118
- Python
119
- YAML
120
active: true
121
"""
122
123
# Using SafeLoader directly
124
stream = StringIO(yaml_content)
125
loader = yaml.SafeLoader(stream)
126
127
try:
128
data = loader.get_single_data()
129
print(data)
130
finally:
131
loader.dispose()
132
133
# More convenient - let PyYAML manage the loader
134
data = yaml.load(yaml_content, Loader=yaml.SafeLoader)
135
print(data)
136
```
137
138
### Custom Dumper Usage
139
140
```python
141
import yaml
142
from io import StringIO
143
144
data = {
145
'name': 'John Doe',
146
'age': 30,
147
'skills': ['Python', 'YAML'],
148
'active': True
149
}
150
151
# Using SafeDumper directly
152
stream = StringIO()
153
dumper = yaml.SafeDumper(
154
stream,
155
default_flow_style=False,
156
indent=4,
157
sort_keys=True
158
)
159
160
try:
161
dumper.open()
162
dumper.represent(data)
163
dumper.close()
164
yaml_output = stream.getvalue()
165
print(yaml_output)
166
finally:
167
dumper.dispose()
168
169
# More convenient - let PyYAML manage the dumper
170
yaml_output = yaml.dump(data, Dumper=yaml.SafeDumper, indent=4, sort_keys=True)
171
print(yaml_output)
172
```
173
174
### Loader Safety Comparison
175
176
```python
177
import yaml
178
179
# Safe YAML that works with all loaders
180
safe_yaml = """
181
name: John
182
numbers: [1, 2, 3]
183
mapping: {key: value}
184
"""
185
186
# YAML with Python-specific constructs
187
python_yaml = """
188
name: John
189
coordinates: !!python/tuple [10, 20]
190
dataset: !!set {a, b, c}
191
"""
192
193
# YAML with potentially dangerous constructs
194
dangerous_yaml = """
195
name: John
196
command: !!python/object/apply:subprocess.call [['rm', '-rf', '/']]
197
"""
198
199
# SafeLoader - works with safe YAML only
200
data1 = yaml.load(safe_yaml, Loader=yaml.SafeLoader) # ✓ Works
201
try:
202
data2 = yaml.load(python_yaml, Loader=yaml.SafeLoader) # ✗ Error
203
except yaml.constructor.ConstructorError as e:
204
print("SafeLoader rejected Python constructs")
205
206
# FullLoader - works with safe YAML and basic Python types
207
data3 = yaml.load(safe_yaml, Loader=yaml.FullLoader) # ✓ Works
208
data4 = yaml.load(python_yaml, Loader=yaml.FullLoader) # ✓ Works
209
try:
210
data5 = yaml.load(dangerous_yaml, Loader=yaml.FullLoader) # ✗ Error
211
except yaml.constructor.ConstructorError as e:
212
print("FullLoader rejected dangerous constructs")
213
214
# UnsafeLoader - works with everything (DANGEROUS!)
215
data6 = yaml.load(safe_yaml, Loader=yaml.UnsafeLoader) # ✓ Works
216
data7 = yaml.load(python_yaml, Loader=yaml.UnsafeLoader) # ✓ Works
217
# data8 = yaml.load(dangerous_yaml, Loader=yaml.UnsafeLoader) # ✓ EXECUTES CODE!
218
```
219
220
### Dumper Capability Comparison
221
222
```python
223
import yaml
224
from collections import OrderedDict
225
import datetime
226
227
data = {
228
'string': 'hello',
229
'integer': 42,
230
'float': 3.14,
231
'boolean': True,
232
'list': [1, 2, 3],
233
'dict': {'nested': 'value'},
234
'tuple': (1, 2, 3),
235
'set': {1, 2, 3},
236
'ordered_dict': OrderedDict([('first', 1), ('second', 2)]),
237
'date': datetime.date(2023, 12, 25),
238
'datetime': datetime.datetime(2023, 12, 25, 10, 30, 0)
239
}
240
241
# SafeDumper - handles standard types
242
safe_yaml = yaml.dump(data, Dumper=yaml.SafeDumper)
243
print("SafeDumper output:")
244
print(safe_yaml)
245
246
# Dumper - handles extended types with custom tags
247
full_yaml = yaml.dump(data, Dumper=yaml.Dumper)
248
print("Dumper output:")
249
print(full_yaml)
250
```
251
252
### Loader/Dumper Pipeline
253
254
```python
255
import yaml
256
257
# Complete pipeline: Python -> YAML -> Python
258
original_data = {
259
'config': {
260
'host': 'localhost',
261
'port': 8080,
262
'features': ['auth', 'logging', 'metrics']
263
}
264
}
265
266
# Dump to YAML
267
yaml_string = yaml.dump(original_data, Dumper=yaml.SafeDumper)
268
print("YAML output:")
269
print(yaml_string)
270
271
# Load back to Python
272
restored_data = yaml.load(yaml_string, Loader=yaml.SafeLoader)
273
print("Restored data:")
274
print(restored_data)
275
276
# Verify round-trip
277
assert original_data == restored_data
278
print("Round-trip successful!")
279
```