You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ruamel.yaml与yamllint序列缩进冲突问题求解

解决ruamel.yaml与yamllint的缩进兼容问题

问题重现

原始YAML内容:

root:
  - foo:
    - bar: 1
    - baz: 2

用配置offset=2、sequence=4的ruamel.yaml读写后,输出变为:

root:
  - foo:
      - bar: 1
      - baz: 2

该格式不符合预期,且yamllint报错:

error wrong indentation: expected 4 but found 6 (indentation)

原因解析

  1. ruamel.yaml的缩进计数逻辑和常规解析器(如PyYAML)存在差异:sequence=4指定序列元素相对于父节点的缩进为4个空格,offset=2指定键值对的缩进为2个空格。嵌套序列时,ruamel会将两个缩进值叠加,导致子序列元素总缩进达到6个空格,触发yamllint的缩进规则报错。
  2. 额外说明:如果你的原始YAML意图是让foo的值包含bar和baz的列表,那原始缩进其实不符合YAML规范——子序列元素必须比父键(foo)有更大的缩进,ruamel输出的格式才是合法结构;但如果需要保留原始格式,就得调整ruamel的配置。

解决方案

方案1:合规格式+yamllint兼容

如果目标是结构合法且通过yamllint检查,将ruamel.yaml的sequence缩进调整为和offset一致的2:

from ruamel.yaml import YAML

yaml = YAML()
# 让sequence缩进与offset匹配,避免嵌套时缩进叠加
yaml.indent(offset=2, sequence=2)

# 读写示例
with open("input.yaml", "r") as f:
    data = yaml.load(f)
with open("output.yaml", "w") as f:
    yaml.dump(data, f)

生成的输出会和原始格式一致:

root:
  - foo:
    - bar: 1
    - baz: 2

同时修改yamllint的配置文件(.yamllint),将序列缩进设为2:

rules:
  indentation:
    sequences: 2

方案2:强制保留原始非规范缩进

如果必须保留原始的非规范缩进(即使存在结构解析风险),可以开启ruamel的格式保留配置:

from ruamel.yaml import YAML

yaml = YAML()
yaml.preserve_quotes = True
# 缩进配置匹配原始格式
yaml.indent(offset=2, sequence=2)
yaml.default_flow_style = False

# 读写操作
with open("input.yaml", "r") as f:
    data = yaml.load(f)
with open("output.yaml", "w") as f:
    yaml.dump(data, f)

⚠️ 注意:这种方式可能导致不同解析器解析出不同结构,因为原始缩进不符合YAML规范,谨慎使用。

内容的提问来源于stack exchange,提问作者Avl8

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 09:45:28