如何覆盖 pyyaml 中的基本解析器

问题描述 投票:0回答:1

我发现了一些关于如何覆盖解析器的评论和类似的问题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 }}"

所以不知道如何执行此过程

python python-3.x yaml pyyaml
1个回答
0
投票

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()
© www.soinside.com 2019 - 2024. All rights reserved.