| [898] | 1 |  | 
|---|
 | 2 | from error import * | 
|---|
 | 3 |  | 
|---|
 | 4 | from tokens import * | 
|---|
 | 5 | from events import * | 
|---|
 | 6 | from nodes import * | 
|---|
 | 7 |  | 
|---|
 | 8 | from loader import * | 
|---|
 | 9 | from dumper import * | 
|---|
 | 10 |  | 
|---|
 | 11 | try: | 
|---|
 | 12 |     from cyaml import * | 
|---|
 | 13 | except ImportError: | 
|---|
 | 14 |     pass | 
|---|
 | 15 |  | 
|---|
 | 16 | def scan(stream, Loader=Loader): | 
|---|
 | 17 |     """ | 
|---|
 | 18 |     Scan a YAML stream and produce scanning tokens. | 
|---|
 | 19 |     """ | 
|---|
 | 20 |     loader = Loader(stream) | 
|---|
 | 21 |     while loader.check_token(): | 
|---|
 | 22 |         yield loader.get_token() | 
|---|
 | 23 |  | 
|---|
 | 24 | def parse(stream, Loader=Loader): | 
|---|
 | 25 |     """ | 
|---|
 | 26 |     Parse a YAML stream and produce parsing events. | 
|---|
 | 27 |     """ | 
|---|
 | 28 |     loader = Loader(stream) | 
|---|
 | 29 |     while loader.check_event(): | 
|---|
 | 30 |         yield loader.get_event() | 
|---|
 | 31 |  | 
|---|
 | 32 | def compose(stream, Loader=Loader): | 
|---|
 | 33 |     """ | 
|---|
 | 34 |     Parse the first YAML document in a stream | 
|---|
 | 35 |     and produce the corresponding representation tree. | 
|---|
 | 36 |     """ | 
|---|
 | 37 |     loader = Loader(stream) | 
|---|
 | 38 |     if loader.check_node(): | 
|---|
 | 39 |         return loader.get_node() | 
|---|
 | 40 |  | 
|---|
 | 41 | def compose_all(stream, Loader=Loader): | 
|---|
 | 42 |     """ | 
|---|
 | 43 |     Parse all YAML documents in a stream | 
|---|
 | 44 |     and produce corresponsing representation trees. | 
|---|
 | 45 |     """ | 
|---|
 | 46 |     loader = Loader(stream) | 
|---|
 | 47 |     while loader.check_node(): | 
|---|
 | 48 |         yield loader.get_node() | 
|---|
 | 49 |  | 
|---|
 | 50 | def load_all(stream, Loader=Loader): | 
|---|
 | 51 |     """ | 
|---|
 | 52 |     Parse all YAML documents in a stream | 
|---|
 | 53 |     and produce corresponding Python objects. | 
|---|
 | 54 |     """ | 
|---|
 | 55 |     loader = Loader(stream) | 
|---|
 | 56 |     while loader.check_data(): | 
|---|
 | 57 |         yield loader.get_data() | 
|---|
 | 58 |  | 
|---|
 | 59 | def load(stream, Loader=Loader): | 
|---|
 | 60 |     """ | 
|---|
 | 61 |     Parse the first YAML document in a stream | 
|---|
 | 62 |     and produce the corresponding Python object. | 
|---|
 | 63 |     """ | 
|---|
 | 64 |     loader = Loader(stream) | 
|---|
 | 65 |     if loader.check_data(): | 
|---|
 | 66 |         return loader.get_data() | 
|---|
 | 67 |  | 
|---|
 | 68 | def safe_load_all(stream): | 
|---|
 | 69 |     """ | 
|---|
 | 70 |     Parse all YAML documents in a stream | 
|---|
 | 71 |     and produce corresponding Python objects. | 
|---|
 | 72 |     Resolve only basic YAML tags. | 
|---|
 | 73 |     """ | 
|---|
 | 74 |     return load_all(stream, SafeLoader) | 
|---|
 | 75 |  | 
|---|
 | 76 | def safe_load(stream): | 
|---|
 | 77 |     """ | 
|---|
 | 78 |     Parse the first YAML document in a stream | 
|---|
 | 79 |     and produce the corresponding Python object. | 
|---|
 | 80 |     Resolve only basic YAML tags. | 
|---|
 | 81 |     """ | 
|---|
 | 82 |     return load(stream, SafeLoader) | 
|---|
 | 83 |  | 
|---|
 | 84 | def emit(events, stream=None, Dumper=Dumper, | 
|---|
 | 85 |         canonical=None, indent=None, width=None, | 
|---|
 | 86 |         allow_unicode=None, line_break=None): | 
|---|
 | 87 |     """ | 
|---|
 | 88 |     Emit YAML parsing events into a stream. | 
|---|
 | 89 |     If stream is None, return the produced string instead. | 
|---|
 | 90 |     """ | 
|---|
 | 91 |     getvalue = None | 
|---|
 | 92 |     if stream is None: | 
|---|
 | 93 |         try: | 
|---|
 | 94 |             from cStringIO import StringIO | 
|---|
 | 95 |         except ImportError: | 
|---|
 | 96 |             from StringIO import StringIO | 
|---|
 | 97 |         stream = StringIO() | 
|---|
 | 98 |         getvalue = stream.getvalue | 
|---|
 | 99 |     dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, | 
|---|
 | 100 |             allow_unicode=allow_unicode, line_break=line_break) | 
|---|
 | 101 |     for event in events: | 
|---|
 | 102 |         dumper.emit(event) | 
|---|
 | 103 |     if getvalue: | 
|---|
 | 104 |         return getvalue() | 
|---|
 | 105 |  | 
|---|
 | 106 | def serialize_all(nodes, stream=None, Dumper=Dumper, | 
|---|
 | 107 |         canonical=None, indent=None, width=None, | 
|---|
 | 108 |         allow_unicode=None, line_break=None, | 
|---|
 | 109 |         encoding='utf-8', explicit_start=None, explicit_end=None, | 
|---|
 | 110 |         version=None, tags=None): | 
|---|
 | 111 |     """ | 
|---|
 | 112 |     Serialize a sequence of representation trees into a YAML stream. | 
|---|
 | 113 |     If stream is None, return the produced string instead. | 
|---|
 | 114 |     """ | 
|---|
 | 115 |     getvalue = None | 
|---|
 | 116 |     if stream is None: | 
|---|
 | 117 |         try: | 
|---|
 | 118 |             from cStringIO import StringIO | 
|---|
 | 119 |         except ImportError: | 
|---|
 | 120 |             from StringIO import StringIO | 
|---|
 | 121 |         stream = StringIO() | 
|---|
 | 122 |         getvalue = stream.getvalue | 
|---|
 | 123 |     dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, | 
|---|
 | 124 |             allow_unicode=allow_unicode, line_break=line_break, | 
|---|
 | 125 |             encoding=encoding, version=version, tags=tags, | 
|---|
 | 126 |             explicit_start=explicit_start, explicit_end=explicit_end) | 
|---|
 | 127 |     dumper.open() | 
|---|
 | 128 |     for node in nodes: | 
|---|
 | 129 |         dumper.serialize(node) | 
|---|
 | 130 |     dumper.close() | 
|---|
 | 131 |     if getvalue: | 
|---|
 | 132 |         return getvalue() | 
|---|
 | 133 |  | 
|---|
 | 134 | def serialize(node, stream=None, Dumper=Dumper, **kwds): | 
|---|
 | 135 |     """ | 
|---|
 | 136 |     Serialize a representation tree into a YAML stream. | 
|---|
 | 137 |     If stream is None, return the produced string instead. | 
|---|
 | 138 |     """ | 
|---|
 | 139 |     return serialize_all([node], stream, Dumper=Dumper, **kwds) | 
|---|
 | 140 |  | 
|---|
 | 141 | def dump_all(documents, stream=None, Dumper=Dumper, | 
|---|
 | 142 |         default_style=None, default_flow_style=None, | 
|---|
 | 143 |         canonical=None, indent=None, width=None, | 
|---|
 | 144 |         allow_unicode=None, line_break=None, | 
|---|
 | 145 |         encoding='utf-8', explicit_start=None, explicit_end=None, | 
|---|
 | 146 |         version=None, tags=None): | 
|---|
 | 147 |     """ | 
|---|
 | 148 |     Serialize a sequence of Python objects into a YAML stream. | 
|---|
 | 149 |     If stream is None, return the produced string instead. | 
|---|
 | 150 |     """ | 
|---|
 | 151 |     getvalue = None | 
|---|
 | 152 |     if stream is None: | 
|---|
 | 153 |         try: | 
|---|
 | 154 |             from cStringIO import StringIO | 
|---|
 | 155 |         except ImportError: | 
|---|
 | 156 |             from StringIO import StringIO | 
|---|
 | 157 |         stream = StringIO() | 
|---|
 | 158 |         getvalue = stream.getvalue | 
|---|
 | 159 |     dumper = Dumper(stream, default_style=default_style, | 
|---|
 | 160 |             default_flow_style=default_flow_style, | 
|---|
 | 161 |             canonical=canonical, indent=indent, width=width, | 
|---|
 | 162 |             allow_unicode=allow_unicode, line_break=line_break, | 
|---|
 | 163 |             encoding=encoding, version=version, tags=tags, | 
|---|
 | 164 |             explicit_start=explicit_start, explicit_end=explicit_end) | 
|---|
 | 165 |     dumper.open() | 
|---|
 | 166 |     for data in documents: | 
|---|
 | 167 |         dumper.represent(data) | 
|---|
 | 168 |     dumper.close() | 
|---|
 | 169 |     if getvalue: | 
|---|
 | 170 |         return getvalue() | 
|---|
 | 171 |  | 
|---|
 | 172 | def dump(data, stream=None, Dumper=Dumper, **kwds): | 
|---|
 | 173 |     """ | 
|---|
 | 174 |     Serialize a Python object into a YAML stream. | 
|---|
 | 175 |     If stream is None, return the produced string instead. | 
|---|
 | 176 |     """ | 
|---|
 | 177 |     return dump_all([data], stream, Dumper=Dumper, **kwds) | 
|---|
 | 178 |  | 
|---|
 | 179 | def safe_dump_all(documents, stream=None, **kwds): | 
|---|
 | 180 |     """ | 
|---|
 | 181 |     Serialize a sequence of Python objects into a YAML stream. | 
|---|
 | 182 |     Produce only basic YAML tags. | 
|---|
 | 183 |     If stream is None, return the produced string instead. | 
|---|
 | 184 |     """ | 
|---|
 | 185 |     return dump_all(documents, stream, Dumper=SafeDumper, **kwds) | 
|---|
 | 186 |  | 
|---|
 | 187 | def safe_dump(data, stream=None, **kwds): | 
|---|
 | 188 |     """ | 
|---|
 | 189 |     Serialize a Python object into a YAML stream. | 
|---|
 | 190 |     Produce only basic YAML tags. | 
|---|
 | 191 |     If stream is None, return the produced string instead. | 
|---|
 | 192 |     """ | 
|---|
 | 193 |     return dump_all([data], stream, Dumper=SafeDumper, **kwds) | 
|---|
 | 194 |  | 
|---|
 | 195 | def add_implicit_resolver(tag, regexp, first=None, | 
|---|
 | 196 |         Loader=Loader, Dumper=Dumper): | 
|---|
 | 197 |     """ | 
|---|
 | 198 |     Add an implicit scalar detector. | 
|---|
 | 199 |     If an implicit scalar value matches the given regexp, | 
|---|
 | 200 |     the corresponding tag is assigned to the scalar. | 
|---|
 | 201 |     first is a sequence of possible initial characters or None. | 
|---|
 | 202 |     """ | 
|---|
 | 203 |     Loader.add_implicit_resolver(tag, regexp, first) | 
|---|
 | 204 |     Dumper.add_implicit_resolver(tag, regexp, first) | 
|---|
 | 205 |  | 
|---|
 | 206 | def add_path_resolver(tag, path, kind=None, Loader=Loader, Dumper=Dumper): | 
|---|
 | 207 |     """ | 
|---|
 | 208 |     Add a path based resolver for the given tag. | 
|---|
 | 209 |     A path is a list of keys that forms a path | 
|---|
 | 210 |     to a node in the representation tree. | 
|---|
 | 211 |     Keys can be string values, integers, or None. | 
|---|
 | 212 |     """ | 
|---|
 | 213 |     Loader.add_path_resolver(tag, path, kind) | 
|---|
 | 214 |     Dumper.add_path_resolver(tag, path, kind) | 
|---|
 | 215 |  | 
|---|
 | 216 | def add_constructor(tag, constructor, Loader=Loader): | 
|---|
 | 217 |     """ | 
|---|
 | 218 |     Add a constructor for the given tag. | 
|---|
 | 219 |     Constructor is a function that accepts a Loader instance | 
|---|
 | 220 |     and a node object and produces the corresponding Python object. | 
|---|
 | 221 |     """ | 
|---|
 | 222 |     Loader.add_constructor(tag, constructor) | 
|---|
 | 223 |  | 
|---|
 | 224 | def add_multi_constructor(tag_prefix, multi_constructor, Loader=Loader): | 
|---|
 | 225 |     """ | 
|---|
 | 226 |     Add a multi-constructor for the given tag prefix. | 
|---|
 | 227 |     Multi-constructor is called for a node if its tag starts with tag_prefix. | 
|---|
 | 228 |     Multi-constructor accepts a Loader instance, a tag suffix, | 
|---|
 | 229 |     and a node object and produces the corresponding Python object. | 
|---|
 | 230 |     """ | 
|---|
 | 231 |     Loader.add_multi_constructor(tag_prefix, multi_constructor) | 
|---|
 | 232 |  | 
|---|
 | 233 | def add_representer(data_type, representer, Dumper=Dumper): | 
|---|
 | 234 |     """ | 
|---|
 | 235 |     Add a representer for the given type. | 
|---|
 | 236 |     Representer is a function accepting a Dumper instance | 
|---|
 | 237 |     and an instance of the given data type | 
|---|
 | 238 |     and producing the corresponding representation node. | 
|---|
 | 239 |     """ | 
|---|
 | 240 |     Dumper.add_representer(data_type, representer) | 
|---|
 | 241 |  | 
|---|
 | 242 | def add_multi_representer(data_type, multi_representer, Dumper=Dumper): | 
|---|
 | 243 |     """ | 
|---|
 | 244 |     Add a representer for the given type. | 
|---|
 | 245 |     Multi-representer is a function accepting a Dumper instance | 
|---|
 | 246 |     and an instance of the given data type or subtype | 
|---|
 | 247 |     and producing the corresponding representation node. | 
|---|
 | 248 |     """ | 
|---|
 | 249 |     Dumper.add_multi_representer(data_type, multi_representer) | 
|---|
 | 250 |  | 
|---|
 | 251 | class YAMLObjectMetaclass(type): | 
|---|
 | 252 |     """ | 
|---|
 | 253 |     The metaclass for YAMLObject. | 
|---|
 | 254 |     """ | 
|---|
 | 255 |     def __init__(cls, name, bases, kwds): | 
|---|
 | 256 |         super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds) | 
|---|
 | 257 |         if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None: | 
|---|
 | 258 |             cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml) | 
|---|
 | 259 |             cls.yaml_dumper.add_representer(cls, cls.to_yaml) | 
|---|
 | 260 |  | 
|---|
 | 261 | class YAMLObject(object): | 
|---|
 | 262 |     """ | 
|---|
 | 263 |     An object that can dump itself to a YAML stream | 
|---|
 | 264 |     and load itself from a YAML stream. | 
|---|
 | 265 |     """ | 
|---|
 | 266 |  | 
|---|
 | 267 |     __metaclass__ = YAMLObjectMetaclass | 
|---|
 | 268 |     __slots__ = ()  # no direct instantiation, so allow immutable subclasses | 
|---|
 | 269 |  | 
|---|
 | 270 |     yaml_loader = Loader | 
|---|
 | 271 |     yaml_dumper = Dumper | 
|---|
 | 272 |  | 
|---|
 | 273 |     yaml_tag = None | 
|---|
 | 274 |     yaml_flow_style = None | 
|---|
 | 275 |  | 
|---|
 | 276 |     def from_yaml(cls, loader, node): | 
|---|
 | 277 |         """ | 
|---|
 | 278 |         Convert a representation node to a Python object. | 
|---|
 | 279 |         """ | 
|---|
 | 280 |         return loader.construct_yaml_object(node, cls) | 
|---|
 | 281 |     from_yaml = classmethod(from_yaml) | 
|---|
 | 282 |  | 
|---|
 | 283 |     def to_yaml(cls, dumper, data): | 
|---|
 | 284 |         """ | 
|---|
 | 285 |         Convert a Python object to a representation node. | 
|---|
 | 286 |         """ | 
|---|
 | 287 |         return dumper.represent_yaml_object(cls.yaml_tag, data, cls, | 
|---|
 | 288 |                 flow_style=cls.yaml_flow_style) | 
|---|
 | 289 |     to_yaml = classmethod(to_yaml) | 
|---|
 | 290 |  | 
|---|