我发现了一些关于如何覆盖解析器的评论和类似的问题。 https://github.com/yaml/pyyaml/issues/376#issuecomment-576821252
@StrayDragon 实际上,如果您愿意,可以通过覆盖基本解析器中的 bool 标记正则表达式来更改此行为(https://github.com/yaml/pyyaml/blob/master/lib/yaml/resolver.py#L170- L175),然后连接解析器而不是新加载器实例上的默认解析器(该实例被传递给 yaml.load()。
理论上我明白了,但是当尝试实施时却不起作用。
这是我的Python代码
import yaml
import re
class CustomLoader(yaml.FullLoader):
pass
# Override the boolean tag regex
yaml.resolver.BaseResolver.add_implicit_resolver(
'tag:yaml.org,2002:bool',
re.compile(
r'''^(?:yes|Yes|YES|no|No|NO
|true|True|TRUE|false|False|FALSE
|off|Off|OFF)$''',
re.X
),
list('yYnNtTfFoO')
)
# Read the workflow YAML file using the custom loader
with open(file_path, 'r') as file:
yaml_content = yaml.load(file, Loader=CustomLoader)
我认为它会起作用,但我原来的 YML 文件
name: cloud
on:
push:
workflow_dispatch:
concurrency:
group: "${{ github.ref }}"
还在更换中
name: cloud-cicd-ghc-test/diego-test-migrate-to-github-ci
True:
push: null
workflow_dispatch: null
concurrency:
group: "${{ github.ref }}"
所以不知道如何执行此过程
yaml.loader.FullLoader
是 yaml.resolver.Resolver
的子类,它为标签配置默认的隐式解析器。
BaseResolver.add_implicit_resolver 函数附加到标签的列表解析器。
我们的目标是替换
tag:yaml.org,2002:bool
的解析器,而不添加到配置列表中。
在配置我们的自定义正则表达式之前,我们可以访问此列表并过滤掉
tag:yaml.org,2002:bool
的配置条目。
import re
from typing import Type
import yaml
class CustomLoader(yaml.FullLoader):
pass
def modify_implicit_resolver(loader_cls: Type[yaml.resolver.BaseResolver],
tag: str, regexp: re.Pattern, first: list[str]):
""" Modifies the regexp for the provided tag
in the implicit resolvers configuration.
"""
ref = loader_cls.yaml_implicit_resolvers
# Reset to empty state
for key in first:
# Exclude bool tags from default implicit resolvers
ref[key] = [(_tag, _regexp) for _tag, _regexp in ref[key]
if _tag != tag]
loader_cls.add_implicit_resolver(tag, regexp, first)
# Override the boolean tag regex
modify_implicit_resolver(
CustomLoader, 'tag:yaml.org,2002:bool',
re.compile(
r'''^(?:yes|Yes|YES|no|No|NO
|true|True|TRUE|false|False|FALSE
|off|Off|OFF)$''', re.X), list('yYnNtTfFoO'))
def main():
# Read the workflow YAML file using the custom loader
file_path = './sample.yaml'
with open(file_path, 'r') as file:
yaml_content = yaml.load(file, Loader=CustomLoader)
print(yaml.dump(yaml_content))
main()