ruamel.yaml.round_trip_dump预期为4,但发现为2(缩进)

时间:2018-07-04 18:51:23

标签: yaml ruamel.yaml

代码:

#!/usr/bin/env python2

import sys
import ruamel.yaml

yaml_str = '''
---
project: ''
project_lead: &ptl
    name: ''
    company: ''
    email: ''
    id: ''
    timezone: ''
primary_contact: *ptl
committers:
    - <<: *ptl
    - name: ''
      email: ''
      company: ''
      id: ''
      timezone: ''
    - name: ''
      email: ''
      company: ''
      id: ''
      timezone: ''
'''


DATA = ruamel.yaml.round_trip_load(yaml_str, version=None, preserve_quotes=True)
indent = 4
block_seq_indent = 2
ruamel.yaml.round_trip_dump(DATA, sys.stdout, default_flow_style=True, indent=indent,
                            block_seq_indent=block_seq_indent)

输出:

project: ''
project_lead: &ptl
    name: ''
    company: ''
    email: ''
    id: ''
    timezone: ''
primary_contact: *ptl
committers:
  - <<: *ptl
  - name: ''
    email: ''
    company: ''
    id: ''
    timezone: ''
  - name: ''
    email: ''
    company: ''
    id: ''
    timezone: ''

问题:

foo.yaml|10 col 3 error| wrong indentation: expected 4 but found 2 (indentation)

如果我增加

block_seq_indent = 4

其后的值(电子邮件,公司,ID,时区)不遵循其缩进。

我的来源YAML是否“错误”?我可以解决这个问题吗? ruamel模块很棒,而且我可以通过编程方式添加值,但我似乎无法在输出中获得有效的YAML。

1 个答案:

答案 0 :(得分:2)

您的输入在(嵌套的)块映射上有四个位置缩进,即project_lead的值,在序列上有六个缩进,即committers的值,且偏移量为破折号四(按顺序,缩进被计入序列元素的开头)。

如果您像以前那样使用旧的API,这确实会出错,但是使用新的API(以及适当的值),您可以执行以下操作:

import sys
import ruamel.yaml
from cStringIO import StringIO

yaml_str = '''\
---
project: ''
project_lead: &ptl
    name: ''
    company: ''
    email: ''
    id: ''
    timezone: ''
primary_contact: *ptl
committers:
    - <<: *ptl
    - name: ''
      email: ''
      company: ''
      id: ''
      timezone: ''
    - name: ''
      email: ''
      company: ''
      id: ''
      timezone: ''
'''

yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yaml.indent(mapping=4, sequence=6, offset=4)
yaml.explicit_start = True
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
buf = StringIO()
yaml.dump(data, buf)
assert buf.getvalue() == yaml_str

没有出现错误。

请注意:

  • default_flow_style=True在您的示例中无效,它们只会影响新的映射和列表,我不确定您是否想对所有添加的值都这样做。
  • 我添加了yaml.explicit_start = True以取得领先的---
  • 您的示例以空换行符开头(紧接在'''之后,就像您执行yaml_str = '\n---\nproject: .....'一样)。您无法真正通过数据结构中的ruamel.yaml()获得该输出,因此在我的yaml_str中使用反斜杠。
  • 尽管这可能是旧API中的错误,但我无意修复它。