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

Revision 377, 25.0 KB checked in by xi, 4 years ago (diff)

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

RevLine 
[55]1
[133]2__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
3    'ConstructorError']
[57]4
[328]5from .error import *
6from .nodes import *
[55]7
[328]8import collections, datetime, base64, binascii, re, sys, types
[55]9
10class ConstructorError(MarkedYAMLError):
11    pass
12
[328]13class BaseConstructor:
[55]14
[136]15    yaml_constructors = {}
16    yaml_multi_constructors = {}
17
18    def __init__(self):
[55]19        self.constructed_objects = {}
[142]20        self.recursive_objects = {}
[222]21        self.state_generators = []
22        self.deep_construct = False
[55]23
[136]24    def check_data(self):
[55]25        # If there are more documents available?
[136]26        return self.check_node()
[55]27
[136]28    def get_data(self):
[55]29        # Construct and return the next document.
[136]30        if self.check_node():
31            return self.construct_document(self.get_node())
[55]32
[258]33    def get_single_data(self):
34        # Ensure that the stream contains a single document and construct it.
35        node = self.get_single_node()
36        if node is not None:
37            return self.construct_document(node)
38        return None
39
[55]40    def construct_document(self, node):
[136]41        data = self.construct_object(node)
[222]42        while self.state_generators:
43            state_generators = self.state_generators
44            self.state_generators = []
45            for generator in state_generators:
46                for dummy in generator:
47                    pass
[55]48        self.constructed_objects = {}
[142]49        self.recursive_objects = {}
[222]50        self.deep_construct = False
[136]51        return data
[55]52
[222]53    def construct_object(self, node, deep=False):
[377]54        if node in self.constructed_objects:
55            return self.constructed_objects[node]
[222]56        if deep:
57            old_deep = self.deep_construct
58            self.deep_construct = True
[142]59        if node in self.recursive_objects:
60            raise ConstructorError(None, None,
[222]61                    "found unconstructable recursive node", node.start_mark)
[142]62        self.recursive_objects[node] = None
[136]63        constructor = None
[222]64        tag_suffix = None
[55]65        if node.tag in self.yaml_constructors:
[222]66            constructor = self.yaml_constructors[node.tag]
[136]67        else:
68            for tag_prefix in self.yaml_multi_constructors:
69                if node.tag.startswith(tag_prefix):
70                    tag_suffix = node.tag[len(tag_prefix):]
[222]71                    constructor = self.yaml_multi_constructors[tag_prefix]
[139]72                    break
[136]73            else:
74                if None in self.yaml_multi_constructors:
[222]75                    tag_suffix = node.tag
76                    constructor = self.yaml_multi_constructors[None]
[136]77                elif None in self.yaml_constructors:
[222]78                    constructor = self.yaml_constructors[None]
[136]79                elif isinstance(node, ScalarNode):
[222]80                    constructor = self.__class__.construct_scalar
[136]81                elif isinstance(node, SequenceNode):
[222]82                    constructor = self.__class__.construct_sequence
[136]83                elif isinstance(node, MappingNode):
[222]84                    constructor = self.__class__.construct_mapping
85        if tag_suffix is None:
86            data = constructor(self, node)
87        else:
88            data = constructor(self, tag_suffix, node)
[235]89        if isinstance(data, types.GeneratorType):
[222]90            generator = data
[328]91            data = next(generator)
[222]92            if self.deep_construct:
93                for dummy in generator:
94                    pass
95            else:
96                self.state_generators.append(generator)
[136]97        self.constructed_objects[node] = data
[142]98        del self.recursive_objects[node]
[222]99        if deep:
100            self.deep_construct = old_deep
[136]101        return data
[55]102
103    def construct_scalar(self, node):
104        if not isinstance(node, ScalarNode):
105            raise ConstructorError(None, None,
106                    "expected a scalar node, but found %s" % node.id,
[116]107                    node.start_mark)
[55]108        return node.value
109
[222]110    def construct_sequence(self, node, deep=False):
[55]111        if not isinstance(node, SequenceNode):
112            raise ConstructorError(None, None,
113                    "expected a sequence node, but found %s" % node.id,
[116]114                    node.start_mark)
[222]115        return [self.construct_object(child, deep=deep)
116                for child in node.value]
[55]117
[222]118    def construct_mapping(self, node, deep=False):
[55]119        if not isinstance(node, MappingNode):
120            raise ConstructorError(None, None,
121                    "expected a mapping node, but found %s" % node.id,
[116]122                    node.start_mark)
[55]123        mapping = {}
[222]124        for key_node, value_node in node.value:
125            key = self.construct_object(key_node, deep=deep)
[328]126            if not isinstance(key, collections.Hashable):
[222]127                raise ConstructorError("while constructing a mapping", node.start_mark,
[328]128                        "found unhashable key", key_node.start_mark)
[222]129            value = self.construct_object(value_node, deep=deep)
130            mapping[key] = value
[55]131        return mapping
132
[222]133    def construct_pairs(self, node, deep=False):
[55]134        if not isinstance(node, MappingNode):
135            raise ConstructorError(None, None,
136                    "expected a mapping node, but found %s" % node.id,
[116]137                    node.start_mark)
[55]138        pairs = []
[222]139        for key_node, value_node in node.value:
140            key = self.construct_object(key_node, deep=deep)
141            value = self.construct_object(value_node, deep=deep)
[55]142            pairs.append((key, value))
143        return pairs
144
[328]145    @classmethod
[55]146    def add_constructor(cls, tag, constructor):
147        if not 'yaml_constructors' in cls.__dict__:
148            cls.yaml_constructors = cls.yaml_constructors.copy()
149        cls.yaml_constructors[tag] = constructor
150
[328]151    @classmethod
[136]152    def add_multi_constructor(cls, tag_prefix, multi_constructor):
153        if not 'yaml_multi_constructors' in cls.__dict__:
154            cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy()
155        cls.yaml_multi_constructors[tag_prefix] = multi_constructor
[55]156
[133]157class SafeConstructor(BaseConstructor):
[55]158
[222]159    def construct_scalar(self, node):
160        if isinstance(node, MappingNode):
161            for key_node, value_node in node.value:
[328]162                if key_node.tag == 'tag:yaml.org,2002:value':
[222]163                    return self.construct_scalar(value_node)
[328]164        return super().construct_scalar(node)
[222]165
166    def flatten_mapping(self, node):
167        merge = []
168        index = 0
169        while index < len(node.value):
170            key_node, value_node = node.value[index]
[328]171            if key_node.tag == 'tag:yaml.org,2002:merge':
[222]172                del node.value[index]
173                if isinstance(value_node, MappingNode):
174                    self.flatten_mapping(value_node)
175                    merge.extend(value_node.value)
176                elif isinstance(value_node, SequenceNode):
177                    submerge = []
178                    for subnode in value_node.value:
179                        if not isinstance(subnode, MappingNode):
180                            raise ConstructorError("while constructing a mapping",
181                                    node.start_mark,
182                                    "expected a mapping for merging, but found %s"
183                                    % subnode.id, subnode.start_mark)
184                        self.flatten_mapping(subnode)
185                        submerge.append(subnode.value)
186                    submerge.reverse()
187                    for value in submerge:
188                        merge.extend(value)
189                else:
190                    raise ConstructorError("while constructing a mapping", node.start_mark,
191                            "expected a mapping or list of mappings for merging, but found %s"
192                            % value_node.id, value_node.start_mark)
[328]193            elif key_node.tag == 'tag:yaml.org,2002:value':
194                key_node.tag = 'tag:yaml.org,2002:str'
[222]195                index += 1
196            else:
197                index += 1
198        if merge:
199            node.value = merge + node.value
200
201    def construct_mapping(self, node, deep=False):
202        if isinstance(node, MappingNode):
203            self.flatten_mapping(node)
[328]204        return super().construct_mapping(node, deep=deep)
[222]205
[55]206    def construct_yaml_null(self, node):
207        self.construct_scalar(node)
208        return None
209
210    bool_values = {
[328]211        'yes':      True,
212        'no':       False,
213        'true':     True,
214        'false':    False,
215        'on':       True,
216        'off':      False,
[55]217    }
218
219    def construct_yaml_bool(self, node):
220        value = self.construct_scalar(node)
221        return self.bool_values[value.lower()]
222
223    def construct_yaml_int(self, node):
[328]224        value = self.construct_scalar(node)
[55]225        value = value.replace('_', '')
226        sign = +1
227        if value[0] == '-':
228            sign = -1
229        if value[0] in '+-':
230            value = value[1:]
231        if value == '0':
232            return 0
233        elif value.startswith('0b'):
234            return sign*int(value[2:], 2)
235        elif value.startswith('0x'):
236            return sign*int(value[2:], 16)
237        elif value[0] == '0':
238            return sign*int(value, 8)
239        elif ':' in value:
240            digits = [int(part) for part in value.split(':')]
241            digits.reverse()
242            base = 1
243            value = 0
244            for digit in digits:
245                value += digit*base
246                base *= 60
247            return sign*value
248        else:
249            return sign*int(value)
250
[168]251    inf_value = 1e300
[173]252    while inf_value != inf_value*inf_value:
[168]253        inf_value *= inf_value
[173]254    nan_value = -inf_value/inf_value   # Trying to make a quiet NaN (like C99).
[55]255
256    def construct_yaml_float(self, node):
[328]257        value = self.construct_scalar(node)
[175]258        value = value.replace('_', '').lower()
[55]259        sign = +1
260        if value[0] == '-':
[58]261            sign = -1
[55]262        if value[0] in '+-':
263            value = value[1:]
[175]264        if value == '.inf':
[55]265            return sign*self.inf_value
[175]266        elif value == '.nan':
[55]267            return self.nan_value
268        elif ':' in value:
269            digits = [float(part) for part in value.split(':')]
270            digits.reverse()
271            base = 1
272            value = 0.0
273            for digit in digits:
274                value += digit*base
275                base *= 60
276            return sign*value
277        else:
[170]278            return sign*float(value)
[55]279
280    def construct_yaml_binary(self, node):
281        try:
[328]282            value = self.construct_scalar(node).encode('ascii')
283        except UnicodeEncodeError as exc:
[55]284            raise ConstructorError(None, None,
[328]285                    "failed to convert base64 data into ascii: %s" % exc,
286                    node.start_mark)
287        try:
[361]288            if hasattr(base64, 'decodebytes'):
289                return base64.decodebytes(value)
290            else:
291                return base64.decodestring(value)
[328]292        except binascii.Error as exc:
293            raise ConstructorError(None, None,
294                    "failed to decode base64 data: %s" % exc, node.start_mark)
[55]295
[56]296    timestamp_regexp = re.compile(
[328]297            r'''^(?P<year>[0-9][0-9][0-9][0-9])
[56]298                -(?P<month>[0-9][0-9]?)
299                -(?P<day>[0-9][0-9]?)
[58]300                (?:(?:[Tt]|[ \t]+)
[56]301                (?P<hour>[0-9][0-9]?)
302                :(?P<minute>[0-9][0-9])
303                :(?P<second>[0-9][0-9])
[234]304                (?:\.(?P<fraction>[0-9]*))?
[225]305                (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
306                (?::(?P<tz_minute>[0-9][0-9]))?))?)?$''', re.X)
[56]307
308    def construct_yaml_timestamp(self, node):
309        value = self.construct_scalar(node)
[58]310        match = self.timestamp_regexp.match(node.value)
[56]311        values = match.groupdict()
[225]312        year = int(values['year'])
313        month = int(values['month'])
314        day = int(values['day'])
315        if not values['hour']:
316            return datetime.date(year, month, day)
317        hour = int(values['hour'])
318        minute = int(values['minute'])
319        second = int(values['second'])
320        fraction = 0
321        if values['fraction']:
[269]322            fraction = values['fraction'][:6]
323            while len(fraction) < 6:
324                fraction += '0'
325            fraction = int(fraction)
[225]326        delta = None
327        if values['tz_sign']:
328            tz_hour = int(values['tz_hour'])
329            tz_minute = int(values['tz_minute'] or 0)
330            delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute)
331            if values['tz_sign'] == '-':
332                delta = -delta
333        data = datetime.datetime(year, month, day, hour, minute, second, fraction)
334        if delta:
335            data -= delta
336        return data
[56]337
338    def construct_yaml_omap(self, node):
339        # Note: we do not check for duplicate keys, because it's too
340        # CPU-expensive.
[222]341        omap = []
342        yield omap
[56]343        if not isinstance(node, SequenceNode):
[116]344            raise ConstructorError("while constructing an ordered map", node.start_mark,
345                    "expected a sequence, but found %s" % node.id, node.start_mark)
[56]346        for subnode in node.value:
347            if not isinstance(subnode, MappingNode):
[116]348                raise ConstructorError("while constructing an ordered map", node.start_mark,
[56]349                        "expected a mapping of length 1, but found %s" % subnode.id,
[116]350                        subnode.start_mark)
[58]351            if len(subnode.value) != 1:
[116]352                raise ConstructorError("while constructing an ordered map", node.start_mark,
[58]353                        "expected a single mapping item, but found %d items" % len(subnode.value),
[116]354                        subnode.start_mark)
[222]355            key_node, value_node = subnode.value[0]
[58]356            key = self.construct_object(key_node)
[222]357            value = self.construct_object(value_node)
[58]358            omap.append((key, value))
[56]359
360    def construct_yaml_pairs(self, node):
361        # Note: the same code as `construct_yaml_omap`.
[222]362        pairs = []
363        yield pairs
[56]364        if not isinstance(node, SequenceNode):
[116]365            raise ConstructorError("while constructing pairs", node.start_mark,
366                    "expected a sequence, but found %s" % node.id, node.start_mark)
[56]367        for subnode in node.value:
368            if not isinstance(subnode, MappingNode):
[116]369                raise ConstructorError("while constructing pairs", node.start_mark,
[56]370                        "expected a mapping of length 1, but found %s" % subnode.id,
[116]371                        subnode.start_mark)
[58]372            if len(subnode.value) != 1:
[116]373                raise ConstructorError("while constructing pairs", node.start_mark,
[58]374                        "expected a single mapping item, but found %d items" % len(subnode.value),
[116]375                        subnode.start_mark)
[222]376            key_node, value_node = subnode.value[0]
[58]377            key = self.construct_object(key_node)
[222]378            value = self.construct_object(value_node)
[58]379            pairs.append((key, value))
[56]380
381    def construct_yaml_set(self, node):
[222]382        data = set()
383        yield data
[56]384        value = self.construct_mapping(node)
[222]385        data.update(value)
[56]386
[55]387    def construct_yaml_str(self, node):
[328]388        return self.construct_scalar(node)
[55]389
[56]390    def construct_yaml_seq(self, node):
[222]391        data = []
392        yield data
393        data.extend(self.construct_sequence(node))
[56]394
395    def construct_yaml_map(self, node):
[222]396        data = {}
397        yield data
398        value = self.construct_mapping(node)
399        data.update(value)
[56]400
[136]401    def construct_yaml_object(self, node, cls):
402        data = cls.__new__(cls)
[222]403        yield data
[136]404        if hasattr(data, '__setstate__'):
[222]405            state = self.construct_mapping(node, deep=True)
[139]406            data.__setstate__(state)
[136]407        else:
[222]408            state = self.construct_mapping(node)
[139]409            data.__dict__.update(state)
[136]410
[57]411    def construct_undefined(self, node):
412        raise ConstructorError(None, None,
[328]413                "could not determine a constructor for the tag %r" % node.tag,
[116]414                node.start_mark)
[57]415
[133]416SafeConstructor.add_constructor(
[328]417        'tag:yaml.org,2002:null',
[133]418        SafeConstructor.construct_yaml_null)
[55]419
[133]420SafeConstructor.add_constructor(
[328]421        'tag:yaml.org,2002:bool',
[133]422        SafeConstructor.construct_yaml_bool)
[55]423
[133]424SafeConstructor.add_constructor(
[328]425        'tag:yaml.org,2002:int',
[133]426        SafeConstructor.construct_yaml_int)
[55]427
[133]428SafeConstructor.add_constructor(
[328]429        'tag:yaml.org,2002:float',
[133]430        SafeConstructor.construct_yaml_float)
[55]431
[133]432SafeConstructor.add_constructor(
[328]433        'tag:yaml.org,2002:binary',
[133]434        SafeConstructor.construct_yaml_binary)
[56]435
[225]436SafeConstructor.add_constructor(
[328]437        'tag:yaml.org,2002:timestamp',
[225]438        SafeConstructor.construct_yaml_timestamp)
[58]439
[133]440SafeConstructor.add_constructor(
[328]441        'tag:yaml.org,2002:omap',
[133]442        SafeConstructor.construct_yaml_omap)
[56]443
[133]444SafeConstructor.add_constructor(
[328]445        'tag:yaml.org,2002:pairs',
[133]446        SafeConstructor.construct_yaml_pairs)
[56]447
[133]448SafeConstructor.add_constructor(
[328]449        'tag:yaml.org,2002:set',
[133]450        SafeConstructor.construct_yaml_set)
[56]451
[133]452SafeConstructor.add_constructor(
[328]453        'tag:yaml.org,2002:str',
[133]454        SafeConstructor.construct_yaml_str)
[55]455
[133]456SafeConstructor.add_constructor(
[328]457        'tag:yaml.org,2002:seq',
[133]458        SafeConstructor.construct_yaml_seq)
[56]459
[133]460SafeConstructor.add_constructor(
[328]461        'tag:yaml.org,2002:map',
[133]462        SafeConstructor.construct_yaml_map)
[56]463
[133]464SafeConstructor.add_constructor(None,
465        SafeConstructor.construct_undefined)
[57]466
[133]467class Constructor(SafeConstructor):
[55]468
[139]469    def construct_python_str(self, node):
[328]470        return self.construct_scalar(node)
[139]471
472    def construct_python_unicode(self, node):
473        return self.construct_scalar(node)
474
[328]475    def construct_python_bytes(self, node):
476        try:
477            value = self.construct_scalar(node).encode('ascii')
478        except UnicodeEncodeError as exc:
479            raise ConstructorError(None, None,
480                    "failed to convert base64 data into ascii: %s" % exc,
481                    node.start_mark)
482        try:
[361]483            if hasattr(base64, 'decodebytes'):
484                return base64.decodebytes(value)
485            else:
486                return base64.decodestring(value)
[328]487        except binascii.Error as exc:
488            raise ConstructorError(None, None,
489                    "failed to decode base64 data: %s" % exc, node.start_mark)
490
[139]491    def construct_python_long(self, node):
[328]492        return self.construct_yaml_int(node)
[139]493
494    def construct_python_complex(self, node):
495       return complex(self.construct_scalar(node))
496
497    def construct_python_tuple(self, node):
[222]498        return tuple(self.construct_sequence(node))
[139]499
500    def find_python_module(self, name, mark):
501        if not name:
502            raise ConstructorError("while constructing a Python module", mark,
503                    "expected non-empty name appended to the tag", mark)
504        try:
505            __import__(name)
[328]506        except ImportError as exc:
[139]507            raise ConstructorError("while constructing a Python module", mark,
[328]508                    "cannot find module %r (%s)" % (name, exc), mark)
[139]509        return sys.modules[name]
510
511    def find_python_name(self, name, mark):
512        if not name:
513            raise ConstructorError("while constructing a Python object", mark,
514                    "expected non-empty name appended to the tag", mark)
[328]515        if '.' in name:
516            module_name, object_name = name.rsplit('.', 1)
[139]517        else:
[329]518            module_name = 'builtins'
[139]519            object_name = name
520        try:
521            __import__(module_name)
[328]522        except ImportError as exc:
[139]523            raise ConstructorError("while constructing a Python object", mark,
[328]524                    "cannot find module %r (%s)" % (module_name, exc), mark)
[139]525        module = sys.modules[module_name]
526        if not hasattr(module, object_name):
527            raise ConstructorError("while constructing a Python object", mark,
[328]528                    "cannot find %r in the module %r"
529                    % (object_name, module.__name__), mark)
[139]530        return getattr(module, object_name)
531
532    def construct_python_name(self, suffix, node):
533        value = self.construct_scalar(node)
534        if value:
535            raise ConstructorError("while constructing a Python name", node.start_mark,
[328]536                    "expected the empty value, but found %r" % value, node.start_mark)
[139]537        return self.find_python_name(suffix, node.start_mark)
538
539    def construct_python_module(self, suffix, node):
540        value = self.construct_scalar(node)
541        if value:
542            raise ConstructorError("while constructing a Python module", node.start_mark,
[328]543                    "expected the empty value, but found %r" % value, node.start_mark)
[139]544        return self.find_python_module(suffix, node.start_mark)
545
[147]546    def make_python_instance(self, suffix, node,
547            args=None, kwds=None, newobj=False):
548        if not args:
549            args = []
550        if not kwds:
551            kwds = {}
552        cls = self.find_python_name(suffix, node.start_mark)
[328]553        if newobj and isinstance(cls, type):
[147]554            return cls.__new__(cls, *args, **kwds)
555        else:
556            return cls(*args, **kwds)
557
558    def set_python_instance_state(self, instance, state):
559        if hasattr(instance, '__setstate__'):
560            instance.__setstate__(state)
561        else:
562            slotstate = {}
563            if isinstance(state, tuple) and len(state) == 2:
564                state, slotstate = state
565            if hasattr(instance, '__dict__'):
566                instance.__dict__.update(state)
567            elif state:
568                slotstate.update(state)
569            for key, value in slotstate.items():
570                setattr(object, key, value)
571
572    def construct_python_object(self, suffix, node):
573        # Format:
574        #   !!python/object:module.name { ... state ... }
575        instance = self.make_python_instance(suffix, node, newobj=True)
[222]576        yield instance
577        deep = hasattr(instance, '__setstate__')
578        state = self.construct_mapping(node, deep=deep)
[147]579        self.set_python_instance_state(instance, state)
580
581    def construct_python_object_apply(self, suffix, node, newobj=False):
582        # Format:
583        #   !!python/object/apply       # (or !!python/object/new)
584        #   args: [ ... arguments ... ]
585        #   kwds: { ... keywords ... }
586        #   state: ... state ...
587        #   listitems: [ ... listitems ... ]
588        #   dictitems: { ... dictitems ... }
589        # or short format:
590        #   !!python/object/apply [ ... arguments ... ]
591        # The difference between !!python/object/apply and !!python/object/new
592        # is how an object is created, check make_python_instance for details.
593        if isinstance(node, SequenceNode):
[222]594            args = self.construct_sequence(node, deep=True)
[147]595            kwds = {}
596            state = {}
597            listitems = []
598            dictitems = {}
599        else:
[222]600            value = self.construct_mapping(node, deep=True)
[147]601            args = value.get('args', [])
602            kwds = value.get('kwds', {})
603            state = value.get('state', {})
604            listitems = value.get('listitems', [])
605            dictitems = value.get('dictitems', {})
606        instance = self.make_python_instance(suffix, node, args, kwds, newobj)
607        if state:
608            self.set_python_instance_state(instance, state)
609        if listitems:
610            instance.extend(listitems)
611        if dictitems:
612            for key in dictitems:
613                instance[key] = dictitems[key]
614        return instance
615
616    def construct_python_object_new(self, suffix, node):
617        return self.construct_python_object_apply(suffix, node, newobj=True)
618
[139]619Constructor.add_constructor(
[328]620    'tag:yaml.org,2002:python/none',
[139]621    Constructor.construct_yaml_null)
622
623Constructor.add_constructor(
[328]624    'tag:yaml.org,2002:python/bool',
[139]625    Constructor.construct_yaml_bool)
626
627Constructor.add_constructor(
[328]628    'tag:yaml.org,2002:python/str',
[139]629    Constructor.construct_python_str)
630
631Constructor.add_constructor(
[328]632    'tag:yaml.org,2002:python/unicode',
[139]633    Constructor.construct_python_unicode)
634
635Constructor.add_constructor(
[328]636    'tag:yaml.org,2002:python/bytes',
637    Constructor.construct_python_bytes)
638
639Constructor.add_constructor(
640    'tag:yaml.org,2002:python/int',
[139]641    Constructor.construct_yaml_int)
642
643Constructor.add_constructor(
[328]644    'tag:yaml.org,2002:python/long',
[139]645    Constructor.construct_python_long)
646
647Constructor.add_constructor(
[328]648    'tag:yaml.org,2002:python/float',
[139]649    Constructor.construct_yaml_float)
650
651Constructor.add_constructor(
[328]652    'tag:yaml.org,2002:python/complex',
[139]653    Constructor.construct_python_complex)
654
655Constructor.add_constructor(
[328]656    'tag:yaml.org,2002:python/list',
[139]657    Constructor.construct_yaml_seq)
658
659Constructor.add_constructor(
[328]660    'tag:yaml.org,2002:python/tuple',
[139]661    Constructor.construct_python_tuple)
662
663Constructor.add_constructor(
[328]664    'tag:yaml.org,2002:python/dict',
[139]665    Constructor.construct_yaml_map)
666
667Constructor.add_multi_constructor(
[328]668    'tag:yaml.org,2002:python/name:',
[139]669    Constructor.construct_python_name)
670
671Constructor.add_multi_constructor(
[328]672    'tag:yaml.org,2002:python/module:',
[139]673    Constructor.construct_python_module)
674
[147]675Constructor.add_multi_constructor(
[328]676    'tag:yaml.org,2002:python/object:',
[147]677    Constructor.construct_python_object)
678
679Constructor.add_multi_constructor(
[328]680    'tag:yaml.org,2002:python/object/apply:',
[147]681    Constructor.construct_python_object_apply)
682
683Constructor.add_multi_constructor(
[328]684    'tag:yaml.org,2002:python/object/new:',
[147]685    Constructor.construct_python_object_new)
686
Note: See TracBrowser for help on using the repository browser.