Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/yaml/constructor.py @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author | shellac |
---|---|
date | Sat, 02 May 2020 07:14:21 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:26e78fe6e8c4 |
---|---|
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 FullConstructor.add_multi_constructor( | |
714 'tag:yaml.org,2002:python/module:', | |
715 FullConstructor.construct_python_module) | |
716 | |
717 FullConstructor.add_multi_constructor( | |
718 'tag:yaml.org,2002:python/object:', | |
719 FullConstructor.construct_python_object) | |
720 | |
721 FullConstructor.add_multi_constructor( | |
722 'tag:yaml.org,2002:python/object/new:', | |
723 FullConstructor.construct_python_object_new) | |
724 | |
725 class UnsafeConstructor(FullConstructor): | |
726 | |
727 def find_python_module(self, name, mark): | |
728 return super(UnsafeConstructor, self).find_python_module(name, mark, unsafe=True) | |
729 | |
730 def find_python_name(self, name, mark): | |
731 return super(UnsafeConstructor, self).find_python_name(name, mark, unsafe=True) | |
732 | |
733 def make_python_instance(self, suffix, node, args=None, kwds=None, newobj=False): | |
734 return super(UnsafeConstructor, self).make_python_instance( | |
735 suffix, node, args, kwds, newobj, unsafe=True) | |
736 | |
737 def set_python_instance_state(self, instance, state): | |
738 return super(UnsafeConstructor, self).set_python_instance_state( | |
739 instance, state, unsafe=True) | |
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 |