constructor.py 25 KB

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