__init__.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. from error import *
  2. from tokens import *
  3. from events import *
  4. from nodes import *
  5. from loader import *
  6. from dumper import *
  7. __version__ = '5.4.1'
  8. try:
  9. from cyaml import *
  10. __with_libyaml__ = True
  11. except ImportError:
  12. __with_libyaml__ = False
  13. #------------------------------------------------------------------------------
  14. # Warnings control
  15. #------------------------------------------------------------------------------
  16. # 'Global' warnings state:
  17. _warnings_enabled = {
  18. 'YAMLLoadWarning': True,
  19. }
  20. # Get or set global warnings' state
  21. def warnings(settings=None):
  22. if settings is None:
  23. return _warnings_enabled
  24. if type(settings) is dict:
  25. for key in settings:
  26. if key in _warnings_enabled:
  27. _warnings_enabled[key] = settings[key]
  28. # Warn when load() is called without Loader=...
  29. class YAMLLoadWarning(RuntimeWarning):
  30. pass
  31. def load_warning(method):
  32. if _warnings_enabled['YAMLLoadWarning'] is False:
  33. return
  34. import warnings
  35. message = (
  36. "calling yaml.%s() without Loader=... is deprecated, as the "
  37. "default Loader is unsafe. Please read "
  38. "https://msg.pyyaml.org/load for full details."
  39. ) % method
  40. warnings.warn(message, YAMLLoadWarning, stacklevel=3)
  41. #------------------------------------------------------------------------------
  42. def scan(stream, Loader=Loader):
  43. """
  44. Scan a YAML stream and produce scanning tokens.
  45. """
  46. loader = Loader(stream)
  47. try:
  48. while loader.check_token():
  49. yield loader.get_token()
  50. finally:
  51. loader.dispose()
  52. def parse(stream, Loader=Loader):
  53. """
  54. Parse a YAML stream and produce parsing events.
  55. """
  56. loader = Loader(stream)
  57. try:
  58. while loader.check_event():
  59. yield loader.get_event()
  60. finally:
  61. loader.dispose()
  62. def compose(stream, Loader=Loader):
  63. """
  64. Parse the first YAML document in a stream
  65. and produce the corresponding representation tree.
  66. """
  67. loader = Loader(stream)
  68. try:
  69. return loader.get_single_node()
  70. finally:
  71. loader.dispose()
  72. def compose_all(stream, Loader=Loader):
  73. """
  74. Parse all YAML documents in a stream
  75. and produce corresponding representation trees.
  76. """
  77. loader = Loader(stream)
  78. try:
  79. while loader.check_node():
  80. yield loader.get_node()
  81. finally:
  82. loader.dispose()
  83. def load(stream, Loader=None):
  84. """
  85. Parse the first YAML document in a stream
  86. and produce the corresponding Python object.
  87. """
  88. if Loader is None:
  89. load_warning('load')
  90. Loader = FullLoader
  91. loader = Loader(stream)
  92. try:
  93. return loader.get_single_data()
  94. finally:
  95. loader.dispose()
  96. def load_all(stream, Loader=None):
  97. """
  98. Parse all YAML documents in a stream
  99. and produce corresponding Python objects.
  100. """
  101. if Loader is None:
  102. load_warning('load_all')
  103. Loader = FullLoader
  104. loader = Loader(stream)
  105. try:
  106. while loader.check_data():
  107. yield loader.get_data()
  108. finally:
  109. loader.dispose()
  110. def full_load(stream):
  111. """
  112. Parse the first YAML document in a stream
  113. and produce the corresponding Python object.
  114. Resolve all tags except those known to be
  115. unsafe on untrusted input.
  116. """
  117. return load(stream, FullLoader)
  118. def full_load_all(stream):
  119. """
  120. Parse all YAML documents in a stream
  121. and produce corresponding Python objects.
  122. Resolve all tags except those known to be
  123. unsafe on untrusted input.
  124. """
  125. return load_all(stream, FullLoader)
  126. def safe_load(stream):
  127. """
  128. Parse the first YAML document in a stream
  129. and produce the corresponding Python object.
  130. Resolve only basic YAML tags. This is known
  131. to be safe for untrusted input.
  132. """
  133. return load(stream, SafeLoader)
  134. def safe_load_all(stream):
  135. """
  136. Parse all YAML documents in a stream
  137. and produce corresponding Python objects.
  138. Resolve only basic YAML tags. This is known
  139. to be safe for untrusted input.
  140. """
  141. return load_all(stream, SafeLoader)
  142. def unsafe_load(stream):
  143. """
  144. Parse the first YAML document in a stream
  145. and produce the corresponding Python object.
  146. Resolve all tags, even those known to be
  147. unsafe on untrusted input.
  148. """
  149. return load(stream, UnsafeLoader)
  150. def unsafe_load_all(stream):
  151. """
  152. Parse all YAML documents in a stream
  153. and produce corresponding Python objects.
  154. Resolve all tags, even those known to be
  155. unsafe on untrusted input.
  156. """
  157. return load_all(stream, UnsafeLoader)
  158. def emit(events, stream=None, Dumper=Dumper,
  159. canonical=None, indent=None, width=None,
  160. allow_unicode=None, line_break=None):
  161. """
  162. Emit YAML parsing events into a stream.
  163. If stream is None, return the produced string instead.
  164. """
  165. getvalue = None
  166. if stream is None:
  167. from StringIO import StringIO
  168. stream = StringIO()
  169. getvalue = stream.getvalue
  170. dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
  171. allow_unicode=allow_unicode, line_break=line_break)
  172. try:
  173. for event in events:
  174. dumper.emit(event)
  175. finally:
  176. dumper.dispose()
  177. if getvalue:
  178. return getvalue()
  179. def serialize_all(nodes, stream=None, Dumper=Dumper,
  180. canonical=None, indent=None, width=None,
  181. allow_unicode=None, line_break=None,
  182. encoding='utf-8', explicit_start=None, explicit_end=None,
  183. version=None, tags=None):
  184. """
  185. Serialize a sequence of representation trees into a YAML stream.
  186. If stream is None, return the produced string instead.
  187. """
  188. getvalue = None
  189. if stream is None:
  190. if encoding is None:
  191. from StringIO import StringIO
  192. else:
  193. from cStringIO import StringIO
  194. stream = StringIO()
  195. getvalue = stream.getvalue
  196. dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
  197. allow_unicode=allow_unicode, line_break=line_break,
  198. encoding=encoding, version=version, tags=tags,
  199. explicit_start=explicit_start, explicit_end=explicit_end)
  200. try:
  201. dumper.open()
  202. for node in nodes:
  203. dumper.serialize(node)
  204. dumper.close()
  205. finally:
  206. dumper.dispose()
  207. if getvalue:
  208. return getvalue()
  209. def serialize(node, stream=None, Dumper=Dumper, **kwds):
  210. """
  211. Serialize a representation tree into a YAML stream.
  212. If stream is None, return the produced string instead.
  213. """
  214. return serialize_all([node], stream, Dumper=Dumper, **kwds)
  215. def dump_all(documents, stream=None, Dumper=Dumper,
  216. default_style=None, default_flow_style=False,
  217. canonical=None, indent=None, width=None,
  218. allow_unicode=None, line_break=None,
  219. encoding='utf-8', explicit_start=None, explicit_end=None,
  220. version=None, tags=None, sort_keys=True):
  221. """
  222. Serialize a sequence of Python objects into a YAML stream.
  223. If stream is None, return the produced string instead.
  224. """
  225. getvalue = None
  226. if stream is None:
  227. if encoding is None:
  228. from StringIO import StringIO
  229. else:
  230. from cStringIO import StringIO
  231. stream = StringIO()
  232. getvalue = stream.getvalue
  233. dumper = Dumper(stream, default_style=default_style,
  234. default_flow_style=default_flow_style,
  235. canonical=canonical, indent=indent, width=width,
  236. allow_unicode=allow_unicode, line_break=line_break,
  237. encoding=encoding, version=version, tags=tags,
  238. explicit_start=explicit_start, explicit_end=explicit_end, sort_keys=sort_keys)
  239. try:
  240. dumper.open()
  241. for data in documents:
  242. dumper.represent(data)
  243. dumper.close()
  244. finally:
  245. dumper.dispose()
  246. if getvalue:
  247. return getvalue()
  248. def dump(data, stream=None, Dumper=Dumper, **kwds):
  249. """
  250. Serialize a Python object into a YAML stream.
  251. If stream is None, return the produced string instead.
  252. """
  253. return dump_all([data], stream, Dumper=Dumper, **kwds)
  254. def safe_dump_all(documents, stream=None, **kwds):
  255. """
  256. Serialize a sequence of Python objects into a YAML stream.
  257. Produce only basic YAML tags.
  258. If stream is None, return the produced string instead.
  259. """
  260. return dump_all(documents, stream, Dumper=SafeDumper, **kwds)
  261. def safe_dump(data, stream=None, **kwds):
  262. """
  263. Serialize a Python object into a YAML stream.
  264. Produce only basic YAML tags.
  265. If stream is None, return the produced string instead.
  266. """
  267. return dump_all([data], stream, Dumper=SafeDumper, **kwds)
  268. def add_implicit_resolver(tag, regexp, first=None,
  269. Loader=None, Dumper=Dumper):
  270. """
  271. Add an implicit scalar detector.
  272. If an implicit scalar value matches the given regexp,
  273. the corresponding tag is assigned to the scalar.
  274. first is a sequence of possible initial characters or None.
  275. """
  276. if Loader is None:
  277. loader.Loader.add_implicit_resolver(tag, regexp, first)
  278. loader.FullLoader.add_implicit_resolver(tag, regexp, first)
  279. loader.UnsafeLoader.add_implicit_resolver(tag, regexp, first)
  280. else:
  281. Loader.add_implicit_resolver(tag, regexp, first)
  282. Dumper.add_implicit_resolver(tag, regexp, first)
  283. def add_path_resolver(tag, path, kind=None, Loader=None, Dumper=Dumper):
  284. """
  285. Add a path based resolver for the given tag.
  286. A path is a list of keys that forms a path
  287. to a node in the representation tree.
  288. Keys can be string values, integers, or None.
  289. """
  290. if Loader is None:
  291. loader.Loader.add_path_resolver(tag, path, kind)
  292. loader.FullLoader.add_path_resolver(tag, path, kind)
  293. loader.UnsafeLoader.add_path_resolver(tag, path, kind)
  294. else:
  295. Loader.add_path_resolver(tag, path, kind)
  296. Dumper.add_path_resolver(tag, path, kind)
  297. def add_constructor(tag, constructor, Loader=None):
  298. """
  299. Add a constructor for the given tag.
  300. Constructor is a function that accepts a Loader instance
  301. and a node object and produces the corresponding Python object.
  302. """
  303. if Loader is None:
  304. loader.Loader.add_constructor(tag, constructor)
  305. loader.FullLoader.add_constructor(tag, constructor)
  306. loader.UnsafeLoader.add_constructor(tag, constructor)
  307. else:
  308. Loader.add_constructor(tag, constructor)
  309. def add_multi_constructor(tag_prefix, multi_constructor, Loader=None):
  310. """
  311. Add a multi-constructor for the given tag prefix.
  312. Multi-constructor is called for a node if its tag starts with tag_prefix.
  313. Multi-constructor accepts a Loader instance, a tag suffix,
  314. and a node object and produces the corresponding Python object.
  315. """
  316. if Loader is None:
  317. loader.Loader.add_multi_constructor(tag_prefix, multi_constructor)
  318. loader.FullLoader.add_multi_constructor(tag_prefix, multi_constructor)
  319. loader.UnsafeLoader.add_multi_constructor(tag_prefix, multi_constructor)
  320. else:
  321. Loader.add_multi_constructor(tag_prefix, multi_constructor)
  322. def add_representer(data_type, representer, Dumper=Dumper):
  323. """
  324. Add a representer for the given type.
  325. Representer is a function accepting a Dumper instance
  326. and an instance of the given data type
  327. and producing the corresponding representation node.
  328. """
  329. Dumper.add_representer(data_type, representer)
  330. def add_multi_representer(data_type, multi_representer, Dumper=Dumper):
  331. """
  332. Add a representer for the given type.
  333. Multi-representer is a function accepting a Dumper instance
  334. and an instance of the given data type or subtype
  335. and producing the corresponding representation node.
  336. """
  337. Dumper.add_multi_representer(data_type, multi_representer)
  338. class YAMLObjectMetaclass(type):
  339. """
  340. The metaclass for YAMLObject.
  341. """
  342. def __init__(cls, name, bases, kwds):
  343. super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds)
  344. if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None:
  345. if isinstance(cls.yaml_loader, list):
  346. for loader in cls.yaml_loader:
  347. loader.add_constructor(cls.yaml_tag, cls.from_yaml)
  348. else:
  349. cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml)
  350. cls.yaml_dumper.add_representer(cls, cls.to_yaml)
  351. class YAMLObject(object):
  352. """
  353. An object that can dump itself to a YAML stream
  354. and load itself from a YAML stream.
  355. """
  356. __metaclass__ = YAMLObjectMetaclass
  357. __slots__ = () # no direct instantiation, so allow immutable subclasses
  358. yaml_loader = [Loader, FullLoader, UnsafeLoader]
  359. yaml_dumper = Dumper
  360. yaml_tag = None
  361. yaml_flow_style = None
  362. def from_yaml(cls, loader, node):
  363. """
  364. Convert a representation node to a Python object.
  365. """
  366. return loader.construct_yaml_object(node, cls)
  367. from_yaml = classmethod(from_yaml)
  368. def to_yaml(cls, dumper, data):
  369. """
  370. Convert a Python object to a representation node.
  371. """
  372. return dumper.represent_yaml_object(cls.yaml_tag, data, cls,
  373. flow_style=cls.yaml_flow_style)
  374. to_yaml = classmethod(to_yaml)