From 2565253f6b61d567280027719181c39250f8a0bb Mon Sep 17 00:00:00 2001 From: Anthon van der Neut Date: Thu, 27 Jul 2017 22:59:24 +0200 Subject: add reason for not dumping to string and "workaround" for those that think they really need this --- _doc/example.ryd | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) (limited to '_doc') diff --git a/_doc/example.ryd b/_doc/example.ryd index 11fa358..a792f48 100644 --- a/_doc/example.ryd +++ b/_doc/example.ryd @@ -122,8 +122,8 @@ 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 +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". The following program with three dumps:: @@ -170,6 +170,59 @@ The following program with three dumps:: gives as output:: --- | -The transform example was inspired by a `question posted by *nowox* +The transform example was inspired by a `question posted by *nowox* `_ 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 +realiase that ``print(round_trip_dump(dict(a=1, b=2)))`` gets you an extra, +empty, line after ``b: 2``. + +The real quesiton is why is 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') -- cgit v1.2.1