master
py 313 lines 9.41 KB
Raw
1 # SPDX-License-Identifier: MIT
2
3 from .error import *
4
5 from .tokens import *
6 from .events import *
7 from .nodes import *
8
9 from .loader import *
10 from .dumper import *
11
12 __version__ = '3.11'
13 try:
14 from .cyaml import *
15 __with_libyaml__ = True
16 except ImportError:
17 __with_libyaml__ = False
18
19 import io
20
21 def scan(stream, Loader=Loader):
22 """
23 Scan a YAML stream and produce scanning tokens.
24 """
25 loader = Loader(stream)
26 try:
27 while loader.check_token():
28 yield loader.get_token()
29 finally:
30 loader.dispose()
31
32 def parse(stream, Loader=Loader):
33 """
34 Parse a YAML stream and produce parsing events.
35 """
36 loader = Loader(stream)
37 try:
38 while loader.check_event():
39 yield loader.get_event()
40 finally:
41 loader.dispose()
42
43 def compose(stream, Loader=Loader):
44 """
45 Parse the first YAML document in a stream
46 and produce the corresponding representation tree.
47 """
48 loader = Loader(stream)
49 try:
50 return loader.get_single_node()
51 finally:
52 loader.dispose()
53
54 def compose_all(stream, Loader=Loader):
55 """
56 Parse all YAML documents in a stream
57 and produce corresponding representation trees.
58 """
59 loader = Loader(stream)
60 try:
61 while loader.check_node():
62 yield loader.get_node()
63 finally:
64 loader.dispose()
65
66 def load(stream, Loader=Loader):
67 """
68 Parse the first YAML document in a stream
69 and produce the corresponding Python object.
70 """
71 loader = Loader(stream)
72 try:
73 return loader.get_single_data()
74 finally:
75 loader.dispose()
76
77 def load_all(stream, Loader=Loader):
78 """
79 Parse all YAML documents in a stream
80 and produce corresponding Python objects.
81 """
82 loader = Loader(stream)
83 try:
84 while loader.check_data():
85 yield loader.get_data()
86 finally:
87 loader.dispose()
88
89 def safe_load(stream):
90 """
91 Parse the first YAML document in a stream
92 and produce the corresponding Python object.
93 Resolve only basic YAML tags.
94 """
95 return load(stream, SafeLoader)
96
97 def safe_load_all(stream):
98 """
99 Parse all YAML documents in a stream
100 and produce corresponding Python objects.
101 Resolve only basic YAML tags.
102 """
103 return load_all(stream, SafeLoader)
104
105 def emit(events, stream=None, Dumper=Dumper,
106 canonical=None, indent=None, width=None,
107 allow_unicode=None, line_break=None):
108 """
109 Emit YAML parsing events into a stream.
110 If stream is None, return the produced string instead.
111 """
112 getvalue = None
113 if stream is None:
114 stream = io.StringIO()
115 getvalue = stream.getvalue
116 dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
117 allow_unicode=allow_unicode, line_break=line_break)
118 try:
119 for event in events:
120 dumper.emit(event)
121 finally:
122 dumper.dispose()
123 if getvalue:
124 return getvalue()
125
126 def serialize_all(nodes, stream=None, Dumper=Dumper,
127 canonical=None, indent=None, width=None,
128 allow_unicode=None, line_break=None,
129 encoding=None, explicit_start=None, explicit_end=None,
130 version=None, tags=None):
131 """
132 Serialize a sequence of representation trees into a YAML stream.
133 If stream is None, return the produced string instead.
134 """
135 getvalue = None
136 if stream is None:
137 if encoding is None:
138 stream = io.StringIO()
139 else:
140 stream = io.BytesIO()
141 getvalue = stream.getvalue
142 dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
143 allow_unicode=allow_unicode, line_break=line_break,
144 encoding=encoding, version=version, tags=tags,
145 explicit_start=explicit_start, explicit_end=explicit_end)
146 try:
147 dumper.open()
148 for node in nodes:
149 dumper.serialize(node)
150 dumper.close()
151 finally:
152 dumper.dispose()
153 if getvalue:
154 return getvalue()
155
156 def serialize(node, stream=None, Dumper=Dumper, **kwds):
157 """
158 Serialize a representation tree into a YAML stream.
159 If stream is None, return the produced string instead.
160 """
161 return serialize_all([node], stream, Dumper=Dumper, **kwds)
162
163 def dump_all(documents, stream=None, Dumper=Dumper,
164 default_style=None, default_flow_style=None,
165 canonical=None, indent=None, width=None,
166 allow_unicode=None, line_break=None,
167 encoding=None, explicit_start=None, explicit_end=None,
168 version=None, tags=None):
169 """
170 Serialize a sequence of Python objects into a YAML stream.
171 If stream is None, return the produced string instead.
172 """
173 getvalue = None
174 if stream is None:
175 if encoding is None:
176 stream = io.StringIO()
177 else:
178 stream = io.BytesIO()
179 getvalue = stream.getvalue
180 dumper = Dumper(stream, default_style=default_style,
181 default_flow_style=default_flow_style,
182 canonical=canonical, indent=indent, width=width,
183 allow_unicode=allow_unicode, line_break=line_break,
184 encoding=encoding, version=version, tags=tags,
185 explicit_start=explicit_start, explicit_end=explicit_end)
186 try:
187 dumper.open()
188 for data in documents:
189 dumper.represent(data)
190 dumper.close()
191 finally:
192 dumper.dispose()
193 if getvalue:
194 return getvalue()
195
196 def dump(data, stream=None, Dumper=Dumper, **kwds):
197 """
198 Serialize a Python object into a YAML stream.
199 If stream is None, return the produced string instead.
200 """
201 return dump_all([data], stream, Dumper=Dumper, **kwds)
202
203 def safe_dump_all(documents, stream=None, **kwds):
204 """
205 Serialize a sequence of Python objects into a YAML stream.
206 Produce only basic YAML tags.
207 If stream is None, return the produced string instead.
208 """
209 return dump_all(documents, stream, Dumper=SafeDumper, **kwds)
210
211 def safe_dump(data, stream=None, **kwds):
212 """
213 Serialize a Python object into a YAML stream.
214 Produce only basic YAML tags.
215 If stream is None, return the produced string instead.
216 """
217 return dump_all([data], stream, Dumper=SafeDumper, **kwds)
218
219 def add_implicit_resolver(tag, regexp, first=None,
220 Loader=Loader, Dumper=Dumper):
221 """
222 Add an implicit scalar detector.
223 If an implicit scalar value matches the given regexp,
224 the corresponding tag is assigned to the scalar.
225 first is a sequence of possible initial characters or None.
226 """
227 Loader.add_implicit_resolver(tag, regexp, first)
228 Dumper.add_implicit_resolver(tag, regexp, first)
229
230 def add_path_resolver(tag, path, kind=None, Loader=Loader, Dumper=Dumper):
231 """
232 Add a path based resolver for the given tag.
233 A path is a list of keys that forms a path
234 to a node in the representation tree.
235 Keys can be string values, integers, or None.
236 """
237 Loader.add_path_resolver(tag, path, kind)
238 Dumper.add_path_resolver(tag, path, kind)
239
240 def add_constructor(tag, constructor, Loader=Loader):
241 """
242 Add a constructor for the given tag.
243 Constructor is a function that accepts a Loader instance
244 and a node object and produces the corresponding Python object.
245 """
246 Loader.add_constructor(tag, constructor)
247
248 def add_multi_constructor(tag_prefix, multi_constructor, Loader=Loader):
249 """
250 Add a multi-constructor for the given tag prefix.
251 Multi-constructor is called for a node if its tag starts with tag_prefix.
252 Multi-constructor accepts a Loader instance, a tag suffix,
253 and a node object and produces the corresponding Python object.
254 """
255 Loader.add_multi_constructor(tag_prefix, multi_constructor)
256
257 def add_representer(data_type, representer, Dumper=Dumper):
258 """
259 Add a representer for the given type.
260 Representer is a function accepting a Dumper instance
261 and an instance of the given data type
262 and producing the corresponding representation node.
263 """
264 Dumper.add_representer(data_type, representer)
265
266 def add_multi_representer(data_type, multi_representer, Dumper=Dumper):
267 """
268 Add a representer for the given type.
269 Multi-representer is a function accepting a Dumper instance
270 and an instance of the given data type or subtype
271 and producing the corresponding representation node.
272 """
273 Dumper.add_multi_representer(data_type, multi_representer)
274
275 class YAMLObjectMetaclass(type):
276 """
277 The metaclass for YAMLObject.
278 """
279 def __init__(cls, name, bases, kwds):
280 super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds)
281 if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None:
282 cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml)
283 cls.yaml_dumper.add_representer(cls, cls.to_yaml)
284
285 class YAMLObject(metaclass=YAMLObjectMetaclass):
286 """
287 An object that can dump itself to a YAML stream
288 and load itself from a YAML stream.
289 """
290
291 __slots__ = () # no direct instantiation, so allow immutable subclasses
292
293 yaml_loader = Loader
294 yaml_dumper = Dumper
295
296 yaml_tag = None
297 yaml_flow_style = None
298
299 @classmethod
300 def from_yaml(cls, loader, node):
301 """
302 Convert a representation node to a Python object.
303 """
304 return loader.construct_yaml_object(node, cls)
305
306 @classmethod
307 def to_yaml(cls, dumper, data):
308 """
309 Convert a Python object to a representation node.
310 """
311 return dumper.represent_yaml_object(cls.yaml_tag, data, cls,
312 flow_style=cls.yaml_flow_style)
313