您输入的内容不是有效的YAML,因为您可以轻松地进行检查,例如,在此处
您应该首先扩展
{% %}结构,然后处理YAML,或者应将文件制作为有效的YAML。这是选择jinja2的部分结果,因为jinja2的宏序列
{% ... %}以{在YAML中具有特殊含义的字符()开头。如果需要更改YAML,然后再次写出,则可以定义自己的定界符并选择它们,以便在YAML中没有特殊含义。
该
{% %}你应该把一个YAML注释块作为顶层你有一个映射,应该只具有键-值对。实现此目标的一种方法是将开始重新定义为#%%#(不必一定要更改结束,但我更喜欢对称性)。
然后,在更新之后,通过一个处理文件的小脚本运行正确的YAML,并将分隔符替换为jinja2理解的分隔符或调整环境,以更改jinja2使用的实际定义。
已更正
data.yaml:
#% set name = "abawaca" %##% set version = "1.00" %#package: name: <{ name }> version: 42source: fn: <{ name }>-<{ version }>.tar.gz url: https://github.com/CK7/abawaca/archive/v<{ version }>.tar.gz sha256: 57465bb291c3a9af93605ffb11d704324079036205e5ac279601c9e98c467529build: number: 0requirements: build: - gcc # [not osx] - llvm # [osx]可以通过以下方式处理:
import jinja2from ruamel import yamlyaml_file = 'data.yaml'tmp_file = 'tmp.yaml'data = yaml.round_trip_load(open(yaml_file))data['package']['version'] = '<{ version }>'with open(tmp_file, 'w') as fp: yaml.round_trip_dump(data, fp)environment = jinja2.Environment( loader=jinja2.FileSystemLoader(searchpath='.'), trim_blocks=True, block_start_string='#%', block_end_string='%#', variable_start_string='<{', variable_end_string='}>') print(environment.get_template(tmp_file).render())给予:
package: name: abawaca version: 1.00source: fn: abawaca-1.00.tar.gz url: https://github.com/CK7/abawaca/archive/v1.00.tar.gz sha256: 57465bb291c3a9af93605ffb11d704324079036205e5ac279601c9e98c467529build: number: 0requirements: build: - gcc # [not osx] - llvm # [osx]
请注意,您必须使用`ruamel.yaml(免责声明:我是该程序包的作者),使用PyYAML不能如此轻松地完成此操作,因为它会丢弃读取YAML文件的注释。由于注释中的所有jinja2都发生在文件的开头,因此您可以使用此特定示例来解决此问题,但通常情况并非如此。



