Reputation: 323
I've searched and found "similar" posts, but nothing that answers my question directly. I also found a stackoverflow post here, but no answers.
I need to write to a yaml
file using the following format:
any_value: 123.4
data_points: |-
0.0, 1.0
0.1, 1.5
0.2, 1.7
If I use a long string containing \n
in it, it will just print it as-is:
any_value: 123.4
data_points: "0.0, 1.0\n0.1, 1.5\n0.2, 1.7"
Which is not what I want. I can also pass it as a list where each item looks like this
['0.0, 1.0', '0.1, 1.5', '0.2, 1.7']
But that only results in
any_value: 123.4
data_points:
- 0.0, 1.0
- 0.1, 1.5
- 0.2, 1.7
It kinda looks like the first one, but it isn't. How do I get ruamel.yaml to dump it the way I want?
Upvotes: 9
Views: 4953
Reputation: 76812
What you want are not folded scalars (which would have >
instead of |
) but block style literal scalars.
The general way to solve this is to look at whether ruamel.yaml
can round-trip what you want:
import sys
import ruamel.yaml
yaml_str = """\
any_value: 123.4
data_points: |-
a
b
"""
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
this gives:
any_value: 123.4
data_points: |-
a
b
As the output looks like the input, examine the type that ruamel.yaml
uses to preserve the literal style information:
print(type(data['data_points']))
which shows what ruamel.yaml
uses interally:
<class 'ruamel.yaml.scalarstring.LiteralScalarString'>
With that knowledge you can do:
from ruamel.yaml.scalarstring import LiteralScalarString
data['data_points'] = LiteralScalarString("""\
0.0, 1.0
0.1, 1.5
0.2, 1.7""")
yaml.dump(data, sys.stdout)
resulting in:
any_value: 123.4
data_points: |-
0.0, 1.0
0.1, 1.5
0.2, 1.7
Please note that the dash in |-
indicates that your scalar doesn't have a final new-line. That is why your Python multi-line string should not have one either.
There is also a function walk_tree()
in ruamel/yaml/scalarstring.py
, which might be of help, it:
walks over a simple yaml tree (recursing in dict values and list items) and converts strings that have multiple lines to literal scalars
Upvotes: 18