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