source: pysyck/trunk/README.txt @ 66

Revision 66, 25.8 KB checked in by xi, 8 years ago (diff)

Add a warning regarding untrusted sources.

RevLine 
[26]1
2============================================================
3PySyck: Python bindings for the Syck YAML parser and emitter
4============================================================
5
6:Author: Kirill Simonov
7:Contact: xi@resolvent.net
[64]8:Web site: http://pyyaml.org/wiki/PySyck
[26]9
10.. contents::
11
[29]12
[26]13Overview
14========
15
16YAML_ is a data serialization format designed for human readability and
17interaction with scripting languages.
18
19Syck_ is an extension for reading and writing YAML in scripting languages. Syck
20provides bindings to the Python_ programming language, but they are somewhat
21limited and leak memory.
22
23PySyck_ is aimed to update the current Python bindings for Syck. The new
[30]24bindings provide a wrapper for the Syck emitter and give access to YAML
25representation graphs. Hopefully it will not leak memory as well.
[26]26
[29]27PySyck_ may be used for various tasks, in particular, as a replacement of the
[64]28module pickle_.
[29]29
[26]30.. _YAML: http://yaml.org/
31.. _Syck: http://whytheluckystiff.net/syck/
32.. _Python: http://python.org/
[64]33.. _PySyck: http://pyyaml.org/wiki/PySyck
[29]34.. _pickle: http://docs.python.org/lib/module-pickle.html
[26]35
[64]36
[26]37Requirements
38============
39
[64]40PySyck requires Syck 0.55 or higher and Python 2.3 or higher.
[26]41
[29]42
[26]43Installation
44============
45
[64]46Please note that Syck 0.55 or higher must be installed. We recommend to use
47Syck_ from `the Syck SVN repository`_ together with `my Syck patches`_. For
48your convenience, a tarball is provided:
49http://pyyaml.org/download/pysyck/syck-0.61+svn232+patches.tar.gz.
[26]50
[64]51If you install PySyck from source, unpack the source tarball and type::
52
[29]53  $ python setup.py install
[26]54
[64]55Windows binaries for Python 2.3 and 2.4 are provided. Windows binaries are
56linked against Syck_ statically.
[26]57
[64]58.. _the Syck SVN repository: http://code.whytheluckystiff.net/svn/syck/trunk
59.. _my Syck patches: http://pyyaml.org/wiki/SyckPatches
[29]60
[64]61
[26]62Usage
63=====
64
[30]65The documentation is still rough and incomplete. See `the source code`_ for
66more information.
[26]67
[65]68.. _the source code: http://pyyaml.org/browser/pysyck/
[29]69
70Quick 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
[66]88Important notice: Do not load a YAML stream from any untrusted source.
89Like ``pickle.load``, ``syck.load`` may call an arbitrary Python function.
90
91
[29]92YAML syntax
93-----------
94
95We do not describe the YAML syntax here. Please check http://yaml.org/ for the
96reference.
97
98In addition to the tags defined in `the YAML types repository`_, PySyck understands
99the 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
115Most of these tags are self-explanatory. The tags ``!python/name:...``,
116``!python/object:...``, ``!python/new:...``, and ``!python/apply:...`` are used
117for constructing Python functions, classes, and objects. See the sections `Use
[30]118Python-specific tags in YAML documents`_ and `Use Python-specific tags to
[29]119construct Python objects`_ for some examples.
120
121.. _the YAML types repository: http://yaml.org/type/index.html
122
123Common Tasks
124------------
125
126Import the module
127~~~~~~~~~~~~~~~~~
128
129::
130
131  >>> from syck import *
132
133or
134
135::
136
137  >>> import syck
138
139Load a document from a string
140~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141
142::
143
144  >>> source = "..."
145  >>> object = load(source)
146
147Load a document from a file
148~~~~~~~~~~~~~~~~~~~~~~~~~~~
149
150::
151
152  >>> source = file(..., 'r')
153  >>> object = load(source)
154
155Convert a Python object to a YAML document
156~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
157
158::
159
160  >>> object = ...
161  >>> document = dump(object)
162
163Dump a Python object to a YAML stream
164~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
165
166::
167
168  >>> object = ...
169  >>> output = file(..., 'w')
170  >>> dump(object, output)
171
172Format 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
183Load several documents from a YAML stream
184~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185
186::
187
188  >>> source = ...
189  >>> objects = load_documents(source)
190  >>> for object in objects:
191  ...     # ...
192
193Create several documents in a YAML stream
194~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195
196::
197
198  >>> objects = [...]
199  >>> output = file(..., 'w')
200  >>> dump_documents(objects, output)
201
[30]202Construct a representation tree of a YAML document
203~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[29]204
205::
206
207  >>> source = ...
208  >>> root_node = parse(source)
209
210Convert 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
223Use 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
235Use PySyck to display the structure of a complex object
236~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
237
238::
239
240  >>> object = ...
241  >>> print dump(object)
242
243Use PySyck to display a YAML representation graph
244~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
245
246::
247
248  >>> source = ...
249  >>> node = parse(source)
250  >>> print dump(node)
251
[30]252Use Python-specific tags in YAML documents
253~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[29]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
269Use 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
278Use 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
307Use 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
331Reference
332---------
333
334Functions
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
500Exceptions
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
522Nodes
523~~~~~
524
525The 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
541All instances of ``Scalar``, ``Seq``, and ``Map`` have the following
542attributes:
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
580For example, let us create a representation graph and transform it into a YAML
581stream::
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
600Now 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
635Parser
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
707Let us show how ``Parser``, ``GenericLoader``, and ``Loader`` parse the same
708document::
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
734Emitter
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
809Let 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
[26]862Development and Bug Reports
863===========================
864
865You may check out the PySyck_ source code from `PySyck SVN repository`_.
866
867If you find a bug in PySyck_, please file a bug report to `PySyck BTS`_. You
868may review open bugs on `the list of active tickets`_.
869
[29]870You may use `YAML-core mailing list`_ for discussions of PySyck_.
871
[64]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
[29]875.. _YAML-core mailing list: http://lists.sourceforge.net/lists/listinfo/yaml-core
[26]876
[29]877
878Known Bugs
879==========
880
[64]881PySyck_ does not support Unicode for real. It is a Syck_ limitation.
[29]882
883
884History
885=======
886
[65]887* PySyck-0.61.1 (2006-03-XX):
[64]888
889  - ``setup.py``: check if ``syck.h`` is present, complain if it doesn't.
890  - ``ext/_syckmodule.c``: release GIL_ before calling Syck_. Note that this
891    change broke Python 2.2 compatibility.
892  - ``lib/syck/loader.py``, ``lib/syck/dumper.py``: change treatment of the
893    ``!str`` tag. Now ``!str``-tagged scalars are converted to Unicode strings
894    if they are valid UTF-8, but are not valid ASCII.
895  - Windows binaries are compiled against the latest Syck_ from
896    `the Syck SVN repository`_ with `my Syck patches`_.
897  - The site is moved to http://pyyaml.org/wiki/PySyck.
898
[30]899* PySyck-0.55.1 (2005-08-30): Initial release.
[29]900
[64]901.. _GIL: http://docs.python.org/api/threads.html
[29]902
[64]903
[26]904Author and Copyright
905====================
906
907The PySyck_ module was written by `Kirill Simonov`_.
908
909PySyck_ is released under the BSD license as Syck_ itself.
910
911.. _Kirill Simonov: mailto:xi@resolvent.net
912
[29]913..
914  vim: ft=rst:
Note: See TracBrowser for help on using the repository browser.