使用 ruamel.yaml 和 preserve_quotes=True 时,有没有办法强制往返 yaml 使用单引号?
When using ruamel.yaml and preserve_quotes=True is there a way to force roundtriped yaml to use single quotes?
[已更新问题,preserve_quotes
按预期工作]
无论输入中使用何种类型的引号,我如何强制输出使用单引号,但前提是使用了引号?
注意:我的项目的(简陋)源代码使用 ruamel.yaml =>
- https://github.com/looztra/yamkix(自以为是的 yaml 格式化程序)
- https://github.com/looztra/kubesplit/tree/v0_scooter(旨在将单个流中的一组 kubernetes 资源拆分为一组文件的工具)
您的示例输出更改了单引号,即未保留
一个最小的例子表明事情不是这样运作的。
import sys
import ruamel.yaml
yaml_str = """---
metadata:
annotations:
first: '1'
second: any string
"""
yaml = ruamel.yaml.YAML(typ='rt')
data = list(yaml.load_all(yaml_str))
yaml.preserve_quotes = True
yaml.explicit_start = True
yaml.dump_all(data, sys.stdout)
给出:
---
metadata:
annotations:
first: '1'
second: any string
使用您的 format_yaml
例程:
import sys
import pathlib
import ruamel.yaml
YAML = ruamel.yaml.YAML
yaml_file = pathlib.Path("temp.yaml")
yaml_file.write_text("""---
metadata:
annotations:
first: '1'
second: any string
""")
def format_yaml(input_file,
output_file,
explicit_start=True,
explicit_end=False,
default_flow_style=False,
dash_inwards=True,
quotes_preserved=True,
parsing_mode='rt'):
"""
Load a file and save it formated :
:param input_file: the input file
:param output_file: the output file
:param explicit_start: write the start of the yaml doc even when there is \
only one done in the file
:param default_flow_style: if False, block style will be used for nested \
arrays/maps
:param dash_inwards: push dash inwards if True
:param quotes_preserved: preserve quotes if True
:param parsing_typ: safe or roundtrip (rt) more
"""
yaml = YAML(typ=parsing_mode)
yaml.explicit_start = explicit_start
yaml.explicit_end = explicit_end
yaml.default_flow_style = default_flow_style
yaml.preserve_quotes = quotes_preserved
if dash_inwards:
yaml.indent(mapping=2, sequence=4, offset=2)
if input_file is not None:
with open(input_file, 'rt') as f_input:
parsed = yaml.load_all(f_input.read())
else:
parsed = yaml.load_all(sys.stdin.read())
ready_for_dump = []
try:
# Read the parsed content to force the scanner to issue errors if any
for data in parsed:
ready_for_dump.append(data)
except ScannerError as e:
print("Something is wrong in the input file, got error from Scanner")
print(e)
return
if output_file is not None:
with open(output_file, 'wt') as out:
yaml.dump_all(ready_for_dump, out)
else:
yaml.dump_all(ready_for_dump, sys.stdout)
format_yaml(yaml_file, None)
这也给出了:
---
metadata:
annotations:
first: '1'
second: any string
如果您在输入中使用双引号,您将在输出中得到双引号。
所以请提供一个 minimal 完整的示例程序来展示行为
你得到的,加上 ruamel.yaml 和 python 版本以及你测试过的平台(上面是在 Python 3.7.3 和 Python 上用 0.15.97 测试的Linux 上的 2.7.15(安装了 pathlib2
)。
顺便说一句,将所有单引号字符串转储为双引号字符串的最简单方法
round-trip 模式是重写 represent_single_quoted_scalarstring
方法
在 yaml.representer
上(例如,通过将 represent_double_quoted_scalarstring
方法分配给它)。
[已更新问题,preserve_quotes
按预期工作]
无论输入中使用何种类型的引号,我如何强制输出使用单引号,但前提是使用了引号?
注意:我的项目的(简陋)源代码使用 ruamel.yaml =>
- https://github.com/looztra/yamkix(自以为是的 yaml 格式化程序)
- https://github.com/looztra/kubesplit/tree/v0_scooter(旨在将单个流中的一组 kubernetes 资源拆分为一组文件的工具)
您的示例输出更改了单引号,即未保留 一个最小的例子表明事情不是这样运作的。
import sys
import ruamel.yaml
yaml_str = """---
metadata:
annotations:
first: '1'
second: any string
"""
yaml = ruamel.yaml.YAML(typ='rt')
data = list(yaml.load_all(yaml_str))
yaml.preserve_quotes = True
yaml.explicit_start = True
yaml.dump_all(data, sys.stdout)
给出:
---
metadata:
annotations:
first: '1'
second: any string
使用您的 format_yaml
例程:
import sys
import pathlib
import ruamel.yaml
YAML = ruamel.yaml.YAML
yaml_file = pathlib.Path("temp.yaml")
yaml_file.write_text("""---
metadata:
annotations:
first: '1'
second: any string
""")
def format_yaml(input_file,
output_file,
explicit_start=True,
explicit_end=False,
default_flow_style=False,
dash_inwards=True,
quotes_preserved=True,
parsing_mode='rt'):
"""
Load a file and save it formated :
:param input_file: the input file
:param output_file: the output file
:param explicit_start: write the start of the yaml doc even when there is \
only one done in the file
:param default_flow_style: if False, block style will be used for nested \
arrays/maps
:param dash_inwards: push dash inwards if True
:param quotes_preserved: preserve quotes if True
:param parsing_typ: safe or roundtrip (rt) more
"""
yaml = YAML(typ=parsing_mode)
yaml.explicit_start = explicit_start
yaml.explicit_end = explicit_end
yaml.default_flow_style = default_flow_style
yaml.preserve_quotes = quotes_preserved
if dash_inwards:
yaml.indent(mapping=2, sequence=4, offset=2)
if input_file is not None:
with open(input_file, 'rt') as f_input:
parsed = yaml.load_all(f_input.read())
else:
parsed = yaml.load_all(sys.stdin.read())
ready_for_dump = []
try:
# Read the parsed content to force the scanner to issue errors if any
for data in parsed:
ready_for_dump.append(data)
except ScannerError as e:
print("Something is wrong in the input file, got error from Scanner")
print(e)
return
if output_file is not None:
with open(output_file, 'wt') as out:
yaml.dump_all(ready_for_dump, out)
else:
yaml.dump_all(ready_for_dump, sys.stdout)
format_yaml(yaml_file, None)
这也给出了:
---
metadata:
annotations:
first: '1'
second: any string
如果您在输入中使用双引号,您将在输出中得到双引号。
所以请提供一个 minimal 完整的示例程序来展示行为
你得到的,加上 ruamel.yaml 和 python 版本以及你测试过的平台(上面是在 Python 3.7.3 和 Python 上用 0.15.97 测试的Linux 上的 2.7.15(安装了 pathlib2
)。
顺便说一句,将所有单引号字符串转储为双引号字符串的最简单方法
round-trip 模式是重写 represent_single_quoted_scalarstring
方法
在 yaml.representer
上(例如,通过将 represent_double_quoted_scalarstring
方法分配给它)。