comparison env/lib/python3.9/site-packages/yaml/constructor.py @ 0:4f3585e2f14b draft default tip

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