内联评论 ruamel.yaml

Inline Comments ruamel.yaml

我正在使用 ruamel.yaml 为我个人项目的自动配置生成功能添加评论。谈到这个问题,我将用一个类似的例子来说明这一点。


比如说,你有一个默认配置字典(自动生成):

{'auth': {'api_key': '', 'api_secret': ''}}

现在我按以下方式将此字典加载到 CommentedMap 对象中:

yaml_config = yaml.round_trip_load(yaml.round_trip_dump(dump))

现在,我有一个元数据字典,其中包括 multiline/single-line 字典中这些配置值的描述:

{
  "auth": {
    "api_key": "Think of this as the user name that represents your account when using the app.\n# Head over to XXX.com, register an app and get your auth keys!",
    "api_secret": "Think of this as the password that represents your account when using the app.\n# Head over to XXX.com, register an app and get your auth keys!"
  }
}

我现在想加载这些元数据项并向 yaml_config 中的各个字段添加注释。请记住,metadatadump 模式是相同的。 dumpmetadata 可以是任意数量的嵌套字典,我上面只包含了一个例子。

我尝试了以下代码来完成这项工作,但它就是行不通...根本没有评论或任何评论 errors/exceptions。

previous_config[field_name].yaml_add_eol_comment(description, _field_name)

上面例子的正确输出应该是:

auth:
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_key: ''
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_secret: ''

我建议总是包含一个完整的工作示例 什么不能做你想做的,因为现在还不完全清楚到底在哪里 事情出了问题。 使用 ruamel.yaml 的新开发不应使用旧的 API (round_trip_load/round_trip_dump),但使用新的API(实例化YAML()) API 是几年前推出的,您没有任何迹象表明您是 使用需要使用有限旧 API.

的古老 ruamel.yaml 版本

你想做的事情可以简单地检查是否可行,通过往返结束 result YAML 文件,看到可以保留不变:

import sys
import ruamel.yaml

yaml_str = """\
auth:
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_key: ''
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_secret: ''
"""

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4)
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

给出:

auth:
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_key: ''
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_secret: ''

您可以查看评论属性:

print(data['auth'].ca)

打印:

Comment(comment=[None, [CommentToken('# Think of this as the password that represents your account when using the app.\n', line: 1, col: 4), CommentToken('# Head over to XXX.com, register an app and get your auth keys!\n', line: 2, col: 4)]],
  items={'api_key': [None, None, CommentToken('\n    # Think of this as the password that represents your account when using the app.\n    # Head over to XXX.com, register an app and get your auth keys!\n', line: 4, col: 4), None]})

行尾注释出现在其他数据之后,顾名思义。在 ruamel.yaml 行尾注释通常与键关联 一个键值对,并且这些键值对应该在同一行上,彼此之间, 并且注释可以扩展到以下行,包括任何空行。为了 ruamel.yaml和行尾注释不一定有注释 在起始行的末尾(即可以为空)。

您还应该知道这些(内部)例程不是固定的,会发生变化 并且可能停止工作,希望不会,但有时没有警告(所以修复 安装中的版本号)。

你把一些不必要的事情联系起来给自己添麻烦了 评论元数据,最终必须在密钥之后 api-key 键值对 api_key: '',元数据中有键 api-secret。 我会让那个自我引发的问题悬而未决。

yaml_add_eol_comment()总是添加缺少的首字母 #,无法添加 多行注释,其中“真正的”行尾部分是空的, 并要求您自己缩进多行注释的行。

您还可以在上面的输出中看到,关于 附加的“用户名”与其他评论完全不同,因为这个评论 出现在 键 (auth) 和与该键关联的值(关联值是两个键 价值)。因此,该评论需要添加不同于 评论键 api_key:

import sys
import ruamel.yaml

yaml_str = """\
auth:
    api_key: ''
    api_secret: ''
"""

def indent_comment(s, indent):
    return s.replace('\n', '\n' + ' ' * indent)

MAPIND = 4

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=MAPIND)
data = yaml.load(yaml_str)
auth = data['auth']
auth.yaml_set_start_comment(
    "Think of this as the user name that represents your account when using the app.\n"
    "# Head over to XXX.com, register an app and get your auth keys!",
    indent=MAPIND,
)
auth.yaml_add_eol_comment('place_holder', 'api_key')
# correct the assigned comment token
cai = auth.ca.items['api_key'][2]
cai.value = indent_comment('\n# Think of this as the password that represents your account when using the app.\n# Head over to XXX.com, register an app and get your auth keys!', MAPIND)

yaml.dump(data, sys.stdout)

它给出了您需要的结果:

auth:
    # Think of this as the user name that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_key: ''
    # Think of this as the password that represents your account when using the app.
    # Head over to XXX.com, register an app and get your auth keys!
    api_secret: ''

以上是用ruamel.yaml==0.17.17完成的,其他版本可能需要适配。