source: pyyaml/trunk/lib/yaml/__init__.py @ 258

Revision 258, 9.1 KB checked in by xi, 7 years ago (diff)

Make compose() and load() ensure that the input stream contains a single document. Fixes #54.

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