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

483 statements  

1 

2__all__ = [ 

3 'BaseConstructor', 

4 'SafeConstructor', 

5 'FullConstructor', 

6 'UnsafeConstructor', 

7 'Constructor', 

8 'ConstructorError' 

9] 

10 

11from .error import * 

12from .nodes import * 

13 

14import collections.abc, datetime, base64, binascii, re, sys, types 

15 

16class ConstructorError(MarkedYAMLError): 

17 pass 

18 

19class 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 

171class 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 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 

217 

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) 

222 

223 def construct_yaml_null(self, node): 

224 self.construct_scalar(node) 

225 return None 

226 

227 bool_values = { 

228 'yes': True, 

229 'no': False, 

230 'true': True, 

231 'false': False, 

232 'on': True, 

233 'off': False, 

234 } 

235 

236 def construct_yaml_bool(self, node): 

237 value = self.construct_scalar(node) 

238 return self.bool_values[value.lower()] 

239 

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) 

267 

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). 

272 

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) 

296 

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) 

312 

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) 

324 

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) 

355 

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)) 

377 

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)) 

398 

399 def construct_yaml_set(self, node): 

400 data = set() 

401 yield data 

402 value = self.construct_mapping(node) 

403 data.update(value) 

404 

405 def construct_yaml_str(self, node): 

406 return self.construct_scalar(node) 

407 

408 def construct_yaml_seq(self, node): 

409 data = [] 

410 yield data 

411 data.extend(self.construct_sequence(node)) 

412 

413 def construct_yaml_map(self, node): 

414 data = {} 

415 yield data 

416 value = self.construct_mapping(node) 

417 data.update(value) 

418 

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) 

428 

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) 

433 

434SafeConstructor.add_constructor( 

435 'tag:yaml.org,2002:null', 

436 SafeConstructor.construct_yaml_null) 

437 

438SafeConstructor.add_constructor( 

439 'tag:yaml.org,2002:bool', 

440 SafeConstructor.construct_yaml_bool) 

441 

442SafeConstructor.add_constructor( 

443 'tag:yaml.org,2002:int', 

444 SafeConstructor.construct_yaml_int) 

445 

446SafeConstructor.add_constructor( 

447 'tag:yaml.org,2002:float', 

448 SafeConstructor.construct_yaml_float) 

449 

450SafeConstructor.add_constructor( 

451 'tag:yaml.org,2002:binary', 

452 SafeConstructor.construct_yaml_binary) 

453 

454SafeConstructor.add_constructor( 

455 'tag:yaml.org,2002:timestamp', 

456 SafeConstructor.construct_yaml_timestamp) 

457 

458SafeConstructor.add_constructor( 

459 'tag:yaml.org,2002:omap', 

460 SafeConstructor.construct_yaml_omap) 

461 

462SafeConstructor.add_constructor( 

463 'tag:yaml.org,2002:pairs', 

464 SafeConstructor.construct_yaml_pairs) 

465 

466SafeConstructor.add_constructor( 

467 'tag:yaml.org,2002:set', 

468 SafeConstructor.construct_yaml_set) 

469 

470SafeConstructor.add_constructor( 

471 'tag:yaml.org,2002:str', 

472 SafeConstructor.construct_yaml_str) 

473 

474SafeConstructor.add_constructor( 

475 'tag:yaml.org,2002:seq', 

476 SafeConstructor.construct_yaml_seq) 

477 

478SafeConstructor.add_constructor( 

479 'tag:yaml.org,2002:map', 

480 SafeConstructor.construct_yaml_map) 

481 

482SafeConstructor.add_constructor(None, 

483 SafeConstructor.construct_undefined) 

484 

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$', '^__.*__$'] 

491 

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 

496 

497 def construct_python_str(self, node): 

498 return self.construct_scalar(node) 

499 

500 def construct_python_unicode(self, node): 

501 return self.construct_scalar(node) 

502 

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) 

518 

519 def construct_python_long(self, node): 

520 return self.construct_yaml_int(node) 

521 

522 def construct_python_complex(self, node): 

523 return complex(self.construct_scalar(node)) 

524 

525 def construct_python_tuple(self, node): 

526 return tuple(self.construct_sequence(node)) 

527 

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] 

542 

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) 

567 

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) 

574 

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) 

581 

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) 

597 

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) 

616 

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) 

625 

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 

660 

661 def construct_python_object_new(self, suffix, node): 

662 return self.construct_python_object_apply(suffix, node, newobj=True) 

663 

664FullConstructor.add_constructor( 

665 'tag:yaml.org,2002:python/none', 

666 FullConstructor.construct_yaml_null) 

667 

668FullConstructor.add_constructor( 

669 'tag:yaml.org,2002:python/bool', 

670 FullConstructor.construct_yaml_bool) 

671 

672FullConstructor.add_constructor( 

673 'tag:yaml.org,2002:python/str', 

674 FullConstructor.construct_python_str) 

675 

676FullConstructor.add_constructor( 

677 'tag:yaml.org,2002:python/unicode', 

678 FullConstructor.construct_python_unicode) 

679 

680FullConstructor.add_constructor( 

681 'tag:yaml.org,2002:python/bytes', 

682 FullConstructor.construct_python_bytes) 

683 

684FullConstructor.add_constructor( 

685 'tag:yaml.org,2002:python/int', 

686 FullConstructor.construct_yaml_int) 

687 

688FullConstructor.add_constructor( 

689 'tag:yaml.org,2002:python/long', 

690 FullConstructor.construct_python_long) 

691 

692FullConstructor.add_constructor( 

693 'tag:yaml.org,2002:python/float', 

694 FullConstructor.construct_yaml_float) 

695 

696FullConstructor.add_constructor( 

697 'tag:yaml.org,2002:python/complex', 

698 FullConstructor.construct_python_complex) 

699 

700FullConstructor.add_constructor( 

701 'tag:yaml.org,2002:python/list', 

702 FullConstructor.construct_yaml_seq) 

703 

704FullConstructor.add_constructor( 

705 'tag:yaml.org,2002:python/tuple', 

706 FullConstructor.construct_python_tuple) 

707 

708FullConstructor.add_constructor( 

709 'tag:yaml.org,2002:python/dict', 

710 FullConstructor.construct_yaml_map) 

711 

712FullConstructor.add_multi_constructor( 

713 'tag:yaml.org,2002:python/name:', 

714 FullConstructor.construct_python_name) 

715 

716class UnsafeConstructor(FullConstructor): 

717 

718 def find_python_module(self, name, mark): 

719 return super(UnsafeConstructor, self).find_python_module(name, mark, unsafe=True) 

720 

721 def find_python_name(self, name, mark): 

722 return super(UnsafeConstructor, self).find_python_name(name, mark, unsafe=True) 

723 

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) 

727 

728 def set_python_instance_state(self, instance, state): 

729 return super(UnsafeConstructor, self).set_python_instance_state( 

730 instance, state, unsafe=True) 

731 

732UnsafeConstructor.add_multi_constructor( 

733 'tag:yaml.org,2002:python/module:', 

734 UnsafeConstructor.construct_python_module) 

735 

736UnsafeConstructor.add_multi_constructor( 

737 'tag:yaml.org,2002:python/object:', 

738 UnsafeConstructor.construct_python_object) 

739 

740UnsafeConstructor.add_multi_constructor( 

741 'tag:yaml.org,2002:python/object/new:', 

742 UnsafeConstructor.construct_python_object_new) 

743 

744UnsafeConstructor.add_multi_constructor( 

745 'tag:yaml.org,2002:python/object/apply:', 

746 UnsafeConstructor.construct_python_object_apply) 

747 

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