source: pyyaml/trunk/lib3/yaml/__init__.py @ 377

Revision 377, 9.4 KB checked in by xi, 3 years ago (diff)

Clear cyclic references in the parser and the emitter to avoid extra GC calls.

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