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