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