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