root/pysyck/trunk/README.txt

Revision 124, 26.0 kB (checked in by xi, 3 years ago)

Preparing the next release.

Line 
1
2 ============================================================
3 PySyck: Python bindings for the Syck YAML parser and emitter
4 ============================================================
5
6 :Author: Kirill Simonov
7 :Contact: xi@resolvent.net
8 :Web site: http://pyyaml.org/wiki/PySyck
9
10 .. contents::
11
12
13 Overview
14 ========
15
16 YAML_ is a data serialization format designed for human readability and
17 interaction with scripting languages.
18
19 Syck_ is an extension for reading and writing YAML in scripting languages. Syck
20 provides bindings to the Python_ programming language, but they are somewhat
21 limited and leak memory.
22
23 PySyck_ is aimed to update the current Python bindings for Syck. The new
24 bindings provide a wrapper for the Syck emitter and give access to YAML
25 representation graphs.
26
27 PySyck_ may be used for various tasks, in particular, as a replacement of the
28 module pickle_.
29
30 .. _YAML: http://yaml.org/
31 .. _Syck: http://whytheluckystiff.net/syck/
32 .. _Python: http://python.org/
33 .. _PySyck: http://pyyaml.org/wiki/PySyck
34 .. _pickle: http://docs.python.org/lib/module-pickle.html
35
36
37 Requirements
38 ============
39
40 PySyck requires Syck 0.55 or higher and Python 2.3 or higher.
41
42
43 Installation
44 ============
45
46 Please note that Syck 0.55 or higher must be installed. We recommend to use
47 Syck_ from `the Syck SVN repository`_ together with `my Syck patches`_. For
48 your convenience, a tarball is provided:
49 http://pyyaml.org/download/pysyck/syck-0.61+svn232+patches.tar.gz.
50
51 If you install PySyck from source, unpack the source tarball and type::
52
53   $ python setup.py install
54
55 Windows binaries for Python 2.3 and 2.4 are provided. Windows binaries are
56 linked against Syck_ statically.
57
58 .. _the Syck SVN repository: http://code.whytheluckystiff.net/svn/syck/trunk
59 .. _my Syck patches: http://pyyaml.org/wiki/SyckPatches
60
61
62 Usage
63 =====
64
65 The documentation is still rough and incomplete. See `the source code`_ for
66 more information.
67
68 .. _the source code: http://pyyaml.org/browser/pysyck/
69
70 Quick Example
71 -------------
72
73 ::
74
75   >>> from syck import *
76   >>> print load("""
77   ... - foo
78   ... - bar
79   ... - baz
80   ... """)
81   ['foo', 'bar', 'baz']
82   >>> print dump(['foo', 'bar', 'baz'])
83   ---
84   - foo
85   - bar
86   - baz
87
88 Important notice: Do not load a YAML stream from any untrusted source.
89 Like ``pickle.load``, ``syck.load`` may call an arbitrary Python function.
90
91
92 YAML syntax
93 -----------
94
95 We do not describe the YAML syntax here. Please check http://yaml.org/ for the
96 reference.
97
98 In addition to the tags defined in `the YAML types repository`_, PySyck understands
99 the following Python-specific tags:
100
101 * ``tag:python.yaml.org,2002:none``,
102 * ``tag:python.yaml.org,2002:bool``,
103 * ``tag:python.yaml.org,2002:int``,
104 * ``tag:python.yaml.org,2002:float``,
105 * ``tag:python.yaml.org,2002:str``,
106 * ``tag:python.yaml.org,2002:unicode``,
107 * ``tag:python.yaml.org,2002:list``,
108 * ``tag:python.yaml.org,2002:tuple``,
109 * ``tag:python.yaml.org,2002:dict``,
110 * ``tag:python.yaml.org,2002:name:...``,
111 * ``tag:python.yaml.org,2002:object:...``,
112 * ``tag:python.yaml.org,2002:new:...``,
113 * ``tag:python.yaml.org,2002:apply:...``.
114
115 Most of these tags are self-explanatory. The tags ``!python/name:...``,
116 ``!python/object:...``, ``!python/new:...``, and ``!python/apply:...`` are used
117 for constructing Python functions, classes, and objects. See the sections `Use
118 Python-specific tags in YAML documents`_ and `Use Python-specific tags to
119 construct Python objects`_ for some examples.
120
121 .. _the YAML types repository: http://yaml.org/type/index.html
122
123 Common Tasks
124 ------------
125
126 Import the module
127 ~~~~~~~~~~~~~~~~~
128
129 ::
130
131   >>> from syck import *
132
133 or
134
135 ::
136
137   >>> import syck
138
139 Load a document from a string
140 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141
142 ::
143
144   >>> source = "..."
145   >>> object = load(source)
146
147 Load a document from a file
148 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
149
150 ::
151
152   >>> source = file(..., 'r')
153   >>> object = load(source)
154
155 Convert a Python object to a YAML document
156 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
157
158 ::
159
160   >>> object = ...
161   >>> document = dump(object)
162
163 Dump a Python object to a YAML stream
164 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
165
166 ::
167
168   >>> object = ...
169   >>> output = file(..., 'w')
170   >>> dump(object, output)
171
172 Format the output YAML stream
173 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
174
175 ::
176
177   >>> object = ...
178   >>> output = file(..., 'w')
179   >>> dump(object, output,
180   ...     headless=False, use_header=False, use_version=False,
181   ...     explicit_typing=True, style=None, best_width=80, indent=2)
182
183 Load several documents from a YAML stream
184 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185
186 ::
187
188   >>> source = ...
189   >>> objects = load_documents(source)
190   >>> for object in objects:
191   ...     # ...
192
193 Create several documents in a YAML stream
194 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195
196 ::
197
198   >>> objects = [...]
199   >>> output = file(..., 'w')
200   >>> dump_documents(objects, output)
201
202 Construct a representation tree of a YAML document
203 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
204
205 ::
206
207   >>> source = ...
208   >>> root_node = parse(source)
209
210 Convert a representation tree to a YAML document
211 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
212
213 ::
214
215   >>> scalar_node = Scalar('...', tag='tag:...',
216   ...     style='...', indent=.., width=..)
217   >>> sequence_node = Seq(list_of_nodes, tag='tag:...', inline=..)
218   >>> mapping_node = Map(dictionary_of_nodes, tag='tag:...', inline=..)
219   >>> root_node = ...
220   >>> output = file(..., 'w')
221   >>> emit(root_node, output)
222
223 Use PySyck as a pickle replacement
224 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
225
226 ::
227
228   >>> object = ...
229   >>> stream = ...
230   >>> dump(object, stream)
231  
232   >>> stream = ...
233   >>> object = load(stream)
234
235 Use PySyck to display the structure of a complex object
236 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
237
238 ::
239
240   >>> object = ...
241   >>> print dump(object)
242
243 Use PySyck to display a YAML representation graph
244 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
245
246 ::
247
248   >>> source = ...
249   >>> node = parse(source)
250   >>> print dump(node)
251
252 Use Python-specific tags in YAML documents
253 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
254
255 ::
256
257   --- %YAML:1.0
258   - !python/none ''       # You may also use '!null'.
259   - !python/bool 'False'  # You may also use '!bool'.
260   - !python/int '123'     # You may also use '!int'.
261   - !python/long '1234567890'
262   - !python/float '123.456789'  # Also '!float'.
263   - !python/str 'a string'      # Also '!str'.
264   - !python/unicode 'a unicode string encoded in utf-8'
265   - !python/list [1, 2, 3]      # The same as '!seq' or no tag.
266   - !python/tuple [1, 2, 3]
267   - !python/dict { 1: foo, 2: bar } # The same as '!map' or no tag.
268
269 Use Python-specific tags to construct functions or classes
270 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
271
272 ::
273
274   --- %YAML:1.0
275   - !python/name:package.module.function_name ''
276   - !python/name:package.module.class_name ''
277
278 Use Python-specific tags to construct Python objects
279 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
280
281 ::
282
283   --- %YAML:1.0
284   - !python/object:package.module.type
285     attribute1: value1
286     attribute2: value2
287     # ...
288   - !python/new:package.module.type
289     - parameter1
290     - parameter2
291     # ...
292   - !python/new:package.module.type
293     args: [parameter1, parameter2, ...]
294     kwds: {kwd1: val1, kwd2: val2, ...}
295     state: {attr1: val1, attr2: val2, ...}
296     # ...
297   - !python/apply:package.module.function
298     - parameter1
299     - parameter2
300     # ...
301   - !python/apply:package.module.function
302     args: [parameter1, parameter2, ...]
303     kwds: {kwd1: val1, kwd2: val2, ...}
304     state: {attr1: val1, attr2: val2, ...}
305     # ...
306
307 Use application specific tags
308 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
309
310 ::
311
312   >>> class MyClass:
313   ...   # ...
314
315   >>> class MyLoader(Loader):
316   ...     def construct_private_my_tag(self, node):
317   ...         # ...
318   ...         return MyClass(...)
319
320   >>> class MyDumper(Dumper):
321   ...     def represent_MyDumper(self, object):
322   ...         # ...
323   ...         return Map(...)
324
325   >>> source = """--- !!my_tag { ... }"""
326   >>> my_instance = load(source, Loader=MyLoader)
327
328   >>> my_instance = MyClass(...)
329   >>> output = dump(my_instance, Dumper=MyDumper)
330
331 Reference
332 ---------
333
334 Functions
335 ~~~~~~~~~
336
337 ``load`` : function
338   ``load(source, Loader=Loader, **parameters)``
339
340   The function ``load()`` returns a Python object corresponding to the first
341   document in the source. If the source is empty, ``load()`` returns ``None``.
342   ``source`` must be a string or a file-like object that has the method
343   ``read(max_length)``.
344
345   By default, the function ``load()`` uses an instance of the class ``Loader``
346   for parsing. You may use another class or pass additional parameters to the
347   class constructor. See the section Parser_ for more details.
348
349   Example::
350
351     >>> load("""
352     ... - foo
353     ... - bar
354     ... - baz
355     ... """)
356     ['foo', 'bar', 'baz']
357
358 ``parse`` : function
359   ``parse(source, Loader=Loader, **parameters)``
360
361   The function ``parse()`` parses the source and returns a representation tree
362   of the first document. ``source`` must be a string or a file-like object
363   that has the method ``read(max_length)``.
364
365   By default, the function ``parse()`` uses an instance of the class ``Loader``
366   for parsing. You may use another class or pass additional parameters to the
367   class constructor. See the section Parser_ for more details.
368
369   Example::
370
371     >>> parse("""
372     ... - foo
373     ... - bar
374     ... - baz
375     ... """)
376     <_syck.Seq object at 0xb7a3f2fc>
377
378 ``load_documents`` : function
379   ``load_documents(source, Loader=Loader, **parameters)``
380
381   The function ``load_documents()`` parses the source and an iterator.  The
382   iterator produces Python objects corresponding the documents of the source
383   stream. ``source`` must be a string or a file-like object that has the method
384   ``read(max_length)``.
385
386   By default, the function ``load_documents()`` uses an instance of the class
387   ``Loader`` for parsing. You may use another class or pass additional
388   parameters to the class constructor. See the section Parser_ for more
389   details.
390
391   Example::
392
393     >>> source = """
394     ... --- >
395     ... This is the
396     ... first document.
397     ... --- >
398     ... This is the
399     ... next document.
400     ... --- >
401     ... This is the
402     ... last document.
403     ... """
404     >>> for object in load_documents(source): print object
405     ...
406     This is the first document.
407
408     This is the next document.
409
410     This is the last document.
411
412 ``parse_documents`` : function
413   ``parse_documents(source, Loader=Loader, **parameters)``
414
415   The function ``parse_documents()`` is similar to ``load_documents()``, but
416   produces representation graphs for all documents in the source.
417  
418 ``dump`` : function
419   ``dump(object, output=None, Dumper=Dumper, **parameters)``
420
421   The function ``dump()`` converts ``object`` to a representation graph
422   and write it to ``output``. ``output`` must be ``None`` or a file-like
423   object that has the method ``write(data)``. If ``output`` is ``None``,
424   ``dump()`` returns the generated document.
425
426   By default, the function ``dump()`` uses an instance of the class ``Dumper``
427   for emitting. You may use another class or pass additional parameters to the
428   class constructor. See the section Emitter_ for more details.
429
430   Example::
431
432     >>> object = ['foo', 'bar', ['baz']]
433     >>> dump(object, sys.stdout)
434     ---
435     - foo
436     - bar
437     - - baz
438     >>> print dump(object)
439     ---
440     - foo
441     - bar
442     - - baz
443
444     >>> print dump(object, use_version=True, indent=5)
445     --- %YAML:1.0
446     - foo
447     - bar
448     -    - baz
449
450 ``emit`` : function
451   ``emit(node, output=None, Dumper=Dumper, **parameters)``
452
453   The function ``emit()`` write the representation graph to the output stream.
454   ``output`` must be ``None`` or a file-like object that has the method
455   ``write(data)``. If ``output`` is ``None``, ``emit()`` returns the generated
456   document.
457
458   By default, the function ``emit()`` uses an instance of the class ``Dumper``
459   for emitting. You may use another class or pass additional parameters to the
460   class constructor. See the section Emitter_ for more details.
461
462   Example::
463
464     >>> foo = Scalar('a string')
465     >>> bar = Scalar('a unicode string', tag="tag:python.yaml.org,2002:unicode")
466     >>> baz = Scalar('12345', tag="tag:yaml.org,2002:int")
467     >>> seq = Seq([foo, bar, baz], tag="tag:python.taml.org,2002:tuple")
468     >>> print emit(seq, use_version=True)
469     --- %YAML:1.0 !python.taml.org,2002/tuple
470     - a string
471     - !python/unicode a unicode string
472     - 12345
473
474 ``dump_documents`` : function
475   ``dump_documents(objects, output=None, Dumper=Dumper, **parameters)``
476
477   The function ``dump_documents()`` takes a list of objects and converts
478   each object to a YAML document. If ``output`` is ``None``, it returns
479   the produced documents. Otherwise it writes down them to ``output``,
480   which must be a file-like object with the method ``write(data)``.
481
482   By default, the function ``dump_documents()`` uses an instance of the class
483   ``Dumper`` for emitting. You may use another class or pass additional
484   parameters to the class constructor. See the section Emitter_ for more
485   details.
486
487   Example::
488
489     >>> print dump_documents(['foo', 'bar', 'baz'])
490     --- foo
491     --- bar
492     --- baz
493
494 ``emit_documents`` : function
495   ``emit_documents(nodes, output=None, Dumper=Dumper, **parameters)``
496
497   The function ``emit_documents()`` is similar to ``dump_documents()``, but
498   it requires a list of representation graphs.
499
500 Exceptions
501 ~~~~~~~~~~
502
503 ``error`` : exception
504   This exception is raised by the Syck parser when it detects a syntax error.
505
506   The attribute ``args`` of the exception is a triple: *message*, *row*,
507   *column*.
508
509   Example::
510
511     >>> load("""---
512     ... - foo
513     ... - '''
514     ... - bar
515     ... """)
516     Traceback (most recent call last):
517       File "<stdin>", line 1, in ?
518       File "build/lib.linux-i686-2.3/syck/loaders.py", line 384, in load
519       File "build/lib.linux-i686-2.3/syck/loaders.py", line 42, in load
520     _syck.error: ('syntax error', 4, 2)
521
522 Nodes
523 ~~~~~
524
525 The following four classes represents nodes in the YAML representation graph:
526
527 ``Node`` : class
528   ``Node`` is an abstract class; you cannot create an instance of the class
529   ``Node``. ``Node`` is the base class of ``Scalar``, ``Seq``, and ``Map``.
530
531 ``Scalar`` : subclass of ``Node``
532   ``Scalar`` represents a scalar node. Its value is a string.
533
534 ``Seq`` : subclass of ``Node``
535   ``Seq`` represents a sequence node. Its value is a list of nodes.
536
537 ``Map`` : subclass of ``Node``
538   ``Map`` represents a mapping node. Its value is a list of pairs or a
539   dictionary.
540
541 All instances of ``Scalar``, ``Seq``, and ``Map`` have the following
542 attributes:
543
544 ``kind`` : string
545   ``'scalar'``, ``'seq'``, or ``'map'``; read-only.
546
547 ``anchor`` : string or ``None``
548   The node anchor.
549
550 ``tag`` : string or ``None``
551   The node tag.
552
553 ``value``
554   The node value. For scalar nodes, it should be a string. For sequence nodes,
555   it should be a list. For mapping nodes, it should be a list of pairs or a
556   dictionary.
557
558 ``Scalar`` instances have additional attributes:
559
560 ``style`` : string or ``None``
561   The node style. Possible values are ``None`` (means literal or plain),
562   ``'1quote'``, ``'2quote'``, ``'fold'``, ``'literal'``, ``'plain'``.
563
564 ``indent`` : integer
565   The node indentation. ``0`` means the default value.
566
567 ``width`` : integer
568   The width of the node field. Longer scalars will be broken on several lines
569   to fit the field. ``0`` means the default value.
570
571 ``chomp`` : string or ``None``
572   The chomping method. Possible values are ``None`` (clip), ``'-'`` (strip),
573   ``'+'`` (keep).
574
575 ``Seq`` and ``Map`` instances have an additional attribute:
576
577 ``inline`` : boolean
578   The block/flow flag.
579
580 For example, let us create a representation graph and transform it into a YAML
581 stream::
582
583   >>> # Create three scalar nodes:
584   >>> foo = Scalar('foo', tag="tag:example.com,2005:foo", style='fold',
585   ...     indent=5)
586   >>> bar = Scalar('bar', style='1quote')
587   >>> baz = Scalar('baz')
588
589   >>> # Create a sequence node:
590   >>> seq = Seq([foo, bar, baz], tag="x-private:seq")
591
592   >>> # Emit it into a YAML stream:
593   >>> print emit(seq)
594   --- !!seq
595   - !example.com,2005/foo >-
596        foo
597   - 'bar'
598   - baz
599
600 Now let us construct a representation graph from a YAML document::
601
602   >>> # The function 'parse' generates a representation graph:
603   >>> root = parse("""
604   ... - foo
605   ... - bar
606   ... - baz
607   ... """)
608
609   >>> # The object 'root' is a sequence node:
610   >>> root
611   <_syck.Seq object at 0xb7e124b4>
612
613   >>> # We can transform 'root' back into a YAML stream:
614   >>> print emit(root)
615   ---
616   - foo
617   - bar
618   - baz
619
620   >>> # We can also display the structure of the representation tree using a
621   >>> # clever trick:
622   >>> print dump(root)
623   --- !python/object:_syck.Seq
624   value:
625   - !python/object:_syck.Scalar
626     value: foo
627     tag: tag:yaml.org,2002:str
628   - !python/object:_syck.Scalar
629     value: bar
630     tag: tag:yaml.org,2002:str
631   - !python/object:_syck.Scalar
632     value: baz
633     tag: tag:yaml.org,2002:str
634
635 Parser
636 ~~~~~~
637
638 ``Parser`` : class
639   The class ``Parser`` is a low-level wrapper of a Syck YAML parser. It can
640   generate a representation graph from a YAML stream.
641
642   The class constructor has the following arguments:
643
644   * ``Parser(source, implicit_typing=True, taguri_expansion=True)``.
645
646   The parameter ``source`` is a YAML stream. It must be a string
647   or a file-like object. If it is not a string, it should have a
648   method named ``read(max_length)`` that returns a string.
649
650   It is not recommended to change the default values of the parameters
651   ``implicit_typing`` and ``taguri_expansion``. See the Syck documentation
652   for more details about them.
653
654   The class defines a single method:
655
656   * ``Parser.parse()``.
657
658   It parses the source and returns the root node of the corresponding
659   representation graph. If the stream is finished, it returns ``None`` and
660   set the flag ``eof`` on.
661
662 ``GenericLoader`` : subclass of ``Parser``
663   The subclass ``GenericLoader`` defines two additional methods:
664
665   * ``GenericLoader.load()``,
666
667   * ``GenericLoader.construct(node)``.
668
669   The method ``load()`` parses the source and constructs the corresponding
670   Python object. To generate an object by a node, ``load()`` uses the
671   ``construct()`` method. The ``construct()`` method defined in
672   ``GenericLoader`` just returns the value of the node: a string, a list,
673   or a dictionary.
674
675 ``Loader`` : subclass of ``GenericLoader``
676  
677   ``Loader`` redefines the method
678
679   * ``Loader.construct(node)``,
680
681   defines an additional method:
682
683   * ``Loader.find_constructor(node)``,
684
685   and add many other auxiliary methods for constructing Python objects.
686
687   ``Loader.construct()`` calls ``find_constructor()`` for the given node,
688   and uses the returned constructor to generate a Python object.
689
690   ``Loader.find_constructor()`` determines the constructor of a node by
691   the following rules:
692
693   * If the node tag has the form ``tag:yaml.org,2002:type_id``, returns the
694     method ``Loader.construct_type_id``.
695
696   * If the node tag has the form ``tag:python.yaml.org,2002:type_id``, returns
697     the method ``Loader.construct_python_type_id``.
698
699   * If the node tag has the form ``x-private:type_id``, returns
700     ``Loader.construct_private_type_id``.
701
702   * If the node tag has the form ``tag:domain.tld,year:type_id``, returns
703     ``Loader.construct_domain_tld_year_type_id``.
704
705   See the source for more details.
706
707 Let us show how ``Parser``, ``GenericLoader``, and ``Loader`` parse the same
708 document::
709
710   >>> # The source stream includes PySyck specific tags '!python/tuple'
711   >>> # and '!python/unicode'. It also includes implicitly typed integer
712   >>> # '12345'
713   >>> source = """--- !python/tuple
714   ... - a string
715   ... - !python/unicode a unicode string
716   ... - 12345
717   ... """
718
719   >>> # 'Parser.parse()' returns the root node of the representation tree:
720   >>> p = Parser(source)
721   >>> print p.parse()
722   <_syck.Seq object at 0xb7a33f54>
723
724   >>> # 'GenericLoader.load()' returns a Python object, but ignores the tags:
725   >>> gl = GenericLoader(source)
726   >>> print gl.load()
727   ['a string', 'a unicode string', '12345']
728
729   >>> # 'Loader.load()' is aware of the tags:
730   >>> l = Loader(source)
731   >>> print l.load()
732   ('a string', u'a unicode string', 12345)
733
734 Emitter
735 ~~~~~~~
736
737 ``Emitter`` : class
738   The class ``Emitter`` is a low-level wrapper of a Syck YAML emitter. It can
739   generate a YAML stream from a representation graph.
740
741   The class constructor has the following signature:
742
743   * ``Emitter(output, headless=False, use_header=False, use_version=False,
744     explicit_typing=True, style=None, best_width=80, indent=2)``.
745
746   The parameter ``output`` must be a file-like object that provides a method
747   ``write(data)``. The other parameters describe the formatting of the output
748   document.
749
750   The class defines a single method:
751
752   * ``emit(node)``.
753
754   The parameter ``node`` must be the root node of a YAML representation graph.
755   The method ``emit()`` writes the generated YAML document to the ``output``
756   stream.
757
758 ``GenericDumper`` : subclass of ``Emitter``
759   The subclass ``GenericDumper`` adds the following methods:
760
761   * ``GenericDumper.dump(object)``,
762
763   * ``GenericDumper.represent(object)``,
764
765   * ``GenericDumper.allow_aliases(object)``.
766
767   The method ``dump()`` converts the given object into a representation graph,
768   generates a YAML document, and writes it to the ``output`` stream. It uses
769   the method ``represent()`` to convert an object to a representation node.
770   The method ``represent()`` defined in ``GenericDumper`` generates a sequence
771   node for a list object and a mapping node for a dictionary object. Otherwise
772   it generates a scalar node with the value equal to ``str(object)``.
773
774   The Syck YAML emitter automatically detects if the same object is reffered
775   from different parts of the graph and generates aliases for it. Unfortunately
776   it does not work well with immutable Python objects such as strings, numbers,
777   and tuples. To prevent generating unnecessary aliases, the method
778   ``allow_aliases()`` is used. If ``allow_aliases()`` for a given object
779   returns ``False``, the alias will never be generated.
780
781   The ``allow_aliases()`` method defined in ``GenericDumper`` always returns
782   ``True``.
783
784 ``Dumper`` : subclass of ``GenericDumper``
785   The subclass ``Dumpers`` redefines the methods:
786
787   * ``Dumper.represent(object)``,
788
789   * ``Dumper.allow_aliases(object)``,
790
791   defines the method
792
793   * ``Dumper.find_representer(object)``,
794
795   and add many other auxiliary methods for representing objects as nodes.
796
797   ``Dumper.find_representer()`` finds a method that can represent the given
798   object as a node in a representation tree. ``find_representer()`` checks the
799   class of the object. If the class has the form ``package.module.type``,
800   ``find_representer()`` returns the method
801   ``Dumper.represent_package_module_type`` if it exists. If this method does
802   not exists, ``find_representer()`` consults its base class, and so on.
803
804   ``Dumper.represent()`` calls ``Dumper.find_representer()`` for the given
805   object and uses the returned method to generate a representation node.
806
807   See the source for more details.
808
809 Let us show how ``Emitter``, ``GenericDumper``, and ``Dumper`` work::
810
811   >>> # For our demonstration, we define a representation tree named 'seq'
812   >>> # and a Python tuple named 'object':
813   >>> foo = Scalar('a string')
814   >>> bar = Scalar('a unicode string', tag="tag:python.yaml.org,2002:unicode")
815   >>> baz = Scalar('12345', tag="tag:yaml.org,2002:int")
816   >>> seq = Seq([foo, bar, baz], tag="tag:python.taml.org,2002:tuple")
817   >>> object = ('a string', u'a unicode string', 12345)
818
819   >>> # An 'Emitter' instance can dump a representation tree into a stream,
820   >>> # but obviously failed to dump a Python object:
821   >>> e = Emitter(sys.stdout)
822   >>> e.emit(seq)
823   --- !python.taml.org,2002/tuple
824   - a string
825   - !python/unicode a unicode string
826   - 12345
827   >>> e.emit(object)
828   Traceback (most recent call last):
829     File "<stdin>", line 1, in ?
830   TypeError: Node instance is required
831
832   >>> # A 'GenericDumper' instance dumps almost everything as a scalar:
833   >>> gd = GenericDumper(sys.stdout)
834   >>> gd.dump(seq)
835   --- <_syck.Seq object at 0xb7a3c2fc>
836   >>> gd.dump(object)
837   --- ('a string', u'a unicode string', 12345)
838
839   >>> # Finally, a 'Dumper' instance dumps a representation tree as a complex
840   >>> # Python object:
841   >>> d = Dumper(sys.stdout)
842   >>> d.dump(seq)
843   --- !python/object:_syck.Seq
844   value:
845   - !python/object:_syck.Scalar
846     value: a string
847   - !python/object:_syck.Scalar
848     value: a unicode string
849     tag: tag:python.yaml.org,2002:unicode
850   - !python/object:_syck.Scalar
851     value: "12345"
852     tag: tag:yaml.org,2002:int
853   tag: tag:python.taml.org,2002:tuple
854   >>> # It also dumps the 'object' object as expected:
855   >>> d.dump(object)
856   --- !python/tuple
857   - a string
858   - !python/unicode a unicode string
859   - 12345
860
861
862 Development and Bug Reports
863 ===========================
864
865 You may check out the PySyck_ source code from `PySyck SVN repository`_.
866
867 If you find a bug in PySyck_, please file a bug report to `PySyck BTS`_. You
868 may review open bugs on `the list of active tickets`_.
869
870 You may use `YAML-core mailing list`_ for discussions of PySyck_.
871
872 .. _PySyck SVN repository: http://svn.pyyaml.org/pysyck/
873 .. _PySyck BTS: http://pyyaml.org/newticket?component=pysyck
874 .. _the list of active tickets: http://pyyaml.org/query?action=view&component=pysyck&order=priority
875 .. _YAML-core mailing list: http://lists.sourceforge.net/lists/listinfo/yaml-core
876
877
878 Known Bugs
879 ==========
880
881 PySyck_ does not support Unicode for real. It is a Syck_ limitation.
882
883
884 History
885 =======
886
887 * PySyck-0.61.2 (2006-03-26):
888
889   - ``ext/_syckmodule.c``: fix a leak in the parser (thanks, jbj).
890   - ``setup.py``: set the development status to Production/Stable.
891
892 * PySyck-0.61.1 (2006-03-15):
893
894   - ``setup.py``: check if ``syck.h`` is present, complain if it doesn't.
895   - ``ext/_syckmodule.c``: release GIL_ before calling Syck_. Note that this
896     change broke Python 2.2 compatibility.
897   - ``lib/syck/loader.py``, ``lib/syck/dumper.py``: change treatment of the
898     ``!str`` tag. Now ``!str``-tagged scalars are converted to Unicode strings
899     if they are valid UTF-8, but are not valid ASCII.
900   - Windows binaries are compiled against the latest Syck_ from
901     `the Syck SVN repository`_ with `my Syck patches`_.
902   - The site is moved to http://pyyaml.org/wiki/PySyck.
903
904 * PySyck-0.55.1 (2005-08-30): Initial release.
905
906 .. _GIL: http://docs.python.org/api/threads.html
907
908
909 Author and Copyright
910 ====================
911
912 The PySyck_ module was written by `Kirill Simonov`_.
913
914 PySyck_ is released under the BSD license as Syck_ itself.
915
916 .. _Kirill Simonov: mailto:xi@resolvent.net
917
918 ..
919   vim: ft=rst:
Note: See TracBrowser for help on using the browser.