Preserve quotes and also add data with quotes in Ruamel

旧城冷巷雨未停 提交于 2020-12-29 12:08:25

问题


I am using Ruamel to preserve quote styles in human-edited YAML files.

I have example input data as:

---
a: '1'
b: "2"
c: 3

I read in data using:

def read_file(f):
    with open(f, 'r') as _f:
        return ruamel.yaml.round_trip_load(_f.read(), preserve_quotes=True)

I then edit that data:

data = read_file('in.yaml')
data['foo'] = 'bar'

I write back to disk using:

def write_file(f, data):
    with open(f, 'w') as _f:
        _f.write(ruamel.yaml.dump(data, Dumper=ruamel.yaml.RoundTripDumper, width=1024))

write_file('out.yaml', data)

And the output file is:

a: '1'
b: "2"
c: 3
foo: bar

Is there a way I can enforce hard quoting of the string 'bar' without also enforcing that quoting style throughout the rest of the file?

(Also, can I stop it from deleting the three dashes --- ?)


回答1:


In order to preserve quotes (and literal block style) for string scalars, ruamel.yaml¹—in round-trip-mode—represents these scalars as SingleQuotedScalarString, DoubleQuotedScalarString and PreservedScalarString. The class definitions for these very thin wrappers can be found in scalarstring.py. When serializing such instances are written "as they were read", although sometimes the representer falls back to double quotes when things get difficult, as that can represent any string.

To get this behaviour when adding new key-value pairs (or when updating an existing pair), you just have to create these instances yourself:

import sys
from ruamel.yaml import YAML
from ruamel.yaml.scalarstring import SingleQuotedScalarString, DoubleQuotedScalarString

yaml_str = """\
---
a: '1'
b: "2"
c: 3
"""

yaml = YAML()
yaml.preserve_quotes = True
yaml.explicit_start = True
data = yaml.load(yaml_str)
data['foo'] = SingleQuotedScalarString('bar')
data.yaml_add_eol_comment('# <- single quotes added', 'foo', column=20)
yaml.dump(data, sys.stdout)

gives:

---
a: '1'
b: "2"
c: 3
foo: 'bar'          # <- single quotes added

the yaml.explicit_start = True recreates the (superfluous) document start marker. Whether such a marker was in the original file or not is not "known" by the top-level dictionary object, so you have to re-add it by hand.

Please note that without preserve_quotes, there would be (single) quotes around the values 1 and 2 anyway to make sure they are seen as string scalars and not as integers.


¹ Of which I am the author.




回答2:


Since Ruamel 0.15, set the preserve_quotes flag like this:

from ruamel.yaml import YAML
from pathlib import Path

yaml = YAML(typ='rt') # Round trip loading and dumping
yaml.preserve_quotes = True
data = yaml.load(Path("in.yaml"))
yaml.dump(data, Path("out.yaml"))


来源:https://stackoverflow.com/questions/39262556/preserve-quotes-and-also-add-data-with-quotes-in-ruamel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!