简体   繁体   English

内嵌注释 ruamel.yaml

[英]Inline Comments ruamel.yaml

I am using ruamel.yaml to add comments to my auto-config generation functionality for my personal project.我正在使用ruamel.yaml为我的个人项目的自动配置生成功能添加注释。 Coming to the question, I am going to do this with a similar example to make it explicit.谈到这个问题,我将用一个类似的例子来说明这一点。


Say, you have a default config dictionary (auto-generated):假设您有一个默认的配置字典(自动生成):

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

Now I load this dict into a CommentedMap object in the following way:现在我通过以下方式将此 dict 加载到CommentedMap对象中:

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

Now, I have a metadata dict that includes multiline/single-line descriptions of these config values in the dict:现在,我有一个元数据字典,其中包含字典中这些配置值的多行/单行描述:

{
  "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!"
  }
}

I now want to load over these metadata items and add comments to the respective fields in the yaml_config .我现在想加载这些元数据项并向yaml_config的相应字段添加注释。 Remember, the metadata and the dump schema are the same.请记住, metadatadump模式是相同的。 The dump and metadata can be any amount of nested dicts, I only included an example above. dumpmetadata可以是任意数量的嵌套字典,我只在上面包含了一个示例。

I tried the following code to make this work, but it just didn't work... No comments at all or any errors/exceptions.我尝试了以下代码来完成这项工作,但它不起作用......根本没有评论或任何错误/异常。

previous_config[field_name].yaml_add_eol_comment(description, _field_name)

The correct output for the above example should be:上面例子的正确输出应该是:

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: ''

I recommend to always include a full working example of what fails to do what you want, as now it is not completely clear exactly where things go wrong.我建议总是包含一个完整的工作示例,说明什么不能做你想做的事,因为现在还不完全清楚哪里出了问题。 New development using ruamel.yaml should not use the old API ( round_trip_load / round_trip_dump ), but use the new API (instantiating YAML() ) That API was introduced several years ago and you give no indication that you are working with an ancient ruamel.yaml version that requires the use of the limited old API.使用ruamel.yaml新开发不应使用旧 API ( round_trip_load / round_trip_dump ),而应使用新 API (实例化YAML() ) 该 API 是几年前引入的,您没有迹象表明您正在使用古老的ruamel.yaml需要使用有限的旧 API 的ruamel.yaml版本。


What you are trying to do can be trivially checked to be possible, by round tripping the end result YAML document and see that can be preserved unchanged:您可以通过往返最终结果 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)

which gives:这使:

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: ''

You can inspect the comment attribute:您可以检查 comment 属性:

print(data['auth'].ca)

which prints:打印:

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]})

End of line comments occur, that is what the name implies.出现行尾注释,这就是名称所暗示的。 In ruamel.yaml end-of-line comments are usually associated with the key of a key-value pair (which are expected to be on one and the same line), and may extend to the following lines, may include empty lines.ruamel.yaml中,行尾注释通常与键值对的键相关联(预计在同一行上),并且可能扩展到以下行,可能包含空行。 For ruamel.yaml and end-of-line comment does not necessarily have a comment at the end-of-the starting line (ie that can be empty).对于ruamel.yaml和行尾注释不一定在起始行的末尾有注释(即可以为空)。

You should also be aware that these (internal) routines are not fixed, will change and may stop to work, hopefully not, but sometimes without warning (so fix the version number in your install).您还应该意识到这些(内部)例程不是固定的,会发生变化并且可能会停止工作,希望不会,但有时没有警告(因此请在安装中修复版本号)。

You are making things unnecessary difficult for yourself by associating the comment meta-data, that eventually has to come after the key api-key of key-value pair api_key: '' , with key api-secret in your meta-data.通过关联注释元数据,您让事情变得不必要,这最终必须在键值对api_key: ''的键api-key之后,在元数据中使用键api-secret I'll leave that self-induced problem unsolved.我不会解决这个自我引发的问题。

yaml_add_eol_comment() always adds a missing initial # , cannot add a multi-line comment of which the "real" end-of-line part is emtpy, and requires you to indent the lines of a multi-line comment yourself. yaml_add_eol_comment()总是添加缺少的首字母# ,无法添加“真实”行尾部分为空的多行注释,并且需要您自己缩进多行注释的行。

You can also see in the output above, that the comment with regards to "user name" is attached completely different from the other comment, as this comment appears between the key ( auth ) and the value associated with that key (the associated value that is a two key value).您还可以在上面的输出中看到,关于“用户名”的注释与其他注释完全不同,因为此注释出现在键 ( auth ) 和与该键关联的值(关联的值)之间是两个键值)。 Because of that, that comment needs to be added differently from the comment on key api_key :因此,需要添加与键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)

which gives your required result:这给出了您所需的结果:

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: ''

The above was done with ruamel.yaml==0.17.17 other version may need adapting.以上是用ruamel.yaml==0.17.17完成的,其他版本可能需要适配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM