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