summaryrefslogtreecommitdiffstats
path: root/_doc/example.ryd
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--_doc/example.ryd255
1 files changed, 255 insertions, 0 deletions
diff --git a/_doc/example.ryd b/_doc/example.ryd
new file mode 100644
index 0000000..4b431cd
--- /dev/null
+++ b/_doc/example.ryd
@@ -0,0 +1,255 @@
+version: 0.2
+text: md
+pdf: false
+--- |
+# Examples
+
+Basic round trip of parsing YAML to Python objects, modifying and
+generating YAML:
+--- !python |
+ import sys
+ from ruamel.yaml import YAML
+
+ inp = """\
+ # example
+ name:
+ # details
+ family: Smith # very common
+ given: Alice # one of the siblings
+ """
+
+ yaml = YAML()
+ code = yaml.load(inp)
+ code['name']['given'] = 'Bob'
+
+ yaml.dump(code, sys.stdout)
+
+--- !stdout |
+Resulting in::
+--- |
+------------------------------------------------------------------------
+
+YAML handcrafted anchors and references as well as key merging are
+preserved. The merged keys can transparently be accessed using `[]` and
+`.get()`:
+--- !python |
+ from ruamel.yaml import YAML
+
+ inp = """\
+ - &CENTER {x: 1, y: 2}
+ - &LEFT {x: 0, y: 2}
+ - &BIG {r: 10}
+ - &SMALL {r: 1}
+ # All the following maps are equal:
+ # Explicit keys
+ - x: 1
+ y: 2
+ r: 10
+ label: center/big
+ # Merge one map
+ - <<: *CENTER
+ r: 10
+ label: center/big
+ # Merge multiple maps
+ - <<: [*CENTER, *BIG]
+ label: center/big
+ # Override
+ - <<: [*BIG, *LEFT, *SMALL]
+ x: 1
+ label: center/big
+ """
+
+ yaml = YAML()
+ data = yaml.load(inp)
+ assert data[7]['y'] == 2
+--- |
+The `CommentedMap`, which is the `dict` like construct one gets when
+round-trip loading, supports insertion of a key into a particular
+position, while optionally adding a comment:
+--- !python |
+ import sys
+ from ruamel.yaml import YAML
+
+ yaml_str = """\
+ first_name: Art
+ occupation: Architect # This is an occupation comment
+ about: Art Vandelay is a fictional character that George invents...
+ """
+
+ yaml = YAML()
+ data = yaml.load(yaml_str)
+ data.insert(1, 'last name', 'Vandelay', comment="new key")
+ yaml.dump(data, sys.stdout)
+
+--- !stdout |
+gives::
+--- |
+Please note that the comment is aligned with that of its neighbour (if
+available).
+
+The above was inspired by a
+[question](http://stackoverflow.com/a/36970608/1307905) posted by
+*demux* on StackOverflow.
+
+------------------------------------------------------------------------
+
+By default `ruamel.yaml` indents with two positions in block style, for
+both mappings and sequences. For sequences the indent is counted to the
+beginning of the scalar, with the dash taking the first position of the
+indented \"space\".
+
+You can change this default indentation by e.g. using `yaml.indent()`:
+--- !python |
+
+import sys
+from ruamel.yaml import YAML
+
+d = dict(a=dict(b=2),c=[3, 4])
+yaml = YAML()
+yaml.dump(d, sys.stdout)
+print('0123456789')
+yaml = YAML()
+yaml.indent(mapping=4, sequence=6, offset=3)
+yaml.dump(d, sys.stdout)
+print('0123456789')
+
+
+--- !stdout |
+
+giving::
+
+
+--- |
+If a block sequence or block mapping is the element of a sequence, the
+are, by default, displayed
+[compact](http://yaml.org/spec/1.2/spec.html#id2797686) notation. This
+means that the dash of the \"parent\" sequence is on the same line as
+the first element resp. first key/value pair of the child collection.
+
+If you want either or both of these (sequence within sequence, mapping
+within sequence) to begin on the next line use `yaml.compact()`:
+--- !python |
+
+import sys
+from ruamel.yaml import YAML
+
+d = [dict(b=2), [3, 4]]
+yaml = YAML()
+yaml.dump(d, sys.stdout)
+print('='*15)
+yaml = YAML()
+yaml.compact(seq_seq=False, seq_map=False)
+yaml.dump(d, sys.stdout)
+
+
+--- !stdout |
+
+giving::
+
+
+--- |
+------------------------------------------------------------------------
+
+The following program uses three dumps on the same data, resulting in a
+stream with three documents:
+--- !python |
+import sys
+from ruamel.yaml import YAML
+
+data = {1: {1: [{1: 1, 2: 2}, {1: 1, 2: 2}], 2: 2}, 2: 42}
+
+yaml = YAML()
+yaml.explicit_start = True
+yaml.dump(data, sys.stdout)
+yaml.indent(sequence=4, offset=2)
+yaml.dump(data, sys.stdout)
+
+
+def sequence_indent_four(s):
+ # this will fail on direclty nested lists: {1; [[2, 3], 4]}
+ levels = []
+ ret_val = ''
+ for line in s.splitlines(True):
+ ls = line.lstrip()
+ indent = len(line) - len(ls)
+ if ls.startswith('- '):
+ if not levels or indent > levels[-1]:
+ levels.append(indent)
+ elif levels:
+ if indent < levels[-1]:
+ levels = levels[:-1]
+ # same -> do nothing
+ else:
+ if levels:
+ if indent <= levels[-1]:
+ while levels and indent <= levels[-1]:
+ levels = levels[:-1]
+ ret_val += ' ' * len(levels) + line
+ return ret_val
+
+yaml = YAML()
+yaml.explicit_start = True
+yaml.dump(data, sys.stdout, transform=sequence_indent_four)
+
+--- !stdout |
+gives as output::
+
+--- |
+The transform example, in the last document, was inspired by a [question
+posted by \*nowox\*](https://stackoverflow.com/q/44388701/1307905) on
+StackOverflow.
+
+------------------------------------------------------------------------
+
+## Output of `dump()` as a string
+
+The single most abused "feature" of the old API is not providing the
+(second) stream parameter to one of the `dump()` variants, in order to
+get a monolithic string representation of the stream back.
+
+Apart from being memory inefficient and slow, quite often people using
+this did not realise that `print(round_trip_dump(dict(a=1, b=2)))` gets
+you an extra, empty, line after `b: 2`.
+
+The real question is why this functionality, which is seldom really
+necessary, is available in the old API (and in PyYAML) in the first
+place. One explanation you get by looking at what someone would need to
+do to make this available if it weren\'t there already. Apart from
+subclassing the `Serializer` and providing a new `dump` method, which
+would ten or so lines, another **hundred** lines, essentially the whole
+`dumper.py` file, would need to be copied and to make use of this
+serializer.
+
+The fact is that one should normally be doing
+`round_trip_dump(dict(a=1, b=2)), sys.stdout)` and do away with 90% of
+the cases for returning the string, and that all post-processing YAML,
+before writing to stream, can be handled by using the `transform=`
+parameter of dump, being able to handle most of the rest. But it is also
+much easier in the new API to provide that YAML output as a string if
+you really need to have it (or think you do):
+--- !python |
+import sys
+from ruamel.yaml import YAML
+from ruamel.yaml.compat import StringIO
+
+class MyYAML(YAML):
+ def dump(self, data, stream=None, **kw):
+ inefficient = False
+ if stream is None:
+ inefficient = True
+ stream = StringIO()
+ YAML.dump(self, data, stream, **kw)
+ if inefficient:
+ return stream.getvalue()
+
+yaml = MyYAML() # or typ='safe'/'unsafe' etc
+--- |
+with about one tenth of the lines needed for the old interface, you can
+once more do:
+--- !code |
+print(yaml.dump(dict(a=1, b=2)))
+--- |
+instead of:
+--- !code |
+yaml.dump((dict(a=1, b=2)), sys.stdout)
+print() # or sys.stdout.write('\n')