yaml / pyyaml

Canonical source repository for PyYAML
MIT License
2.55k stars 518 forks source link

Plain equal sign (=) as node content results in an error #89

Open rdn32 opened 7 years ago

rdn32 commented 7 years ago

Running this code:

import yaml
print(yaml.load("="))

Gives this error: ` yaml.constructor.ConstructorError: could not determine a constructor for the tag 'tag:yaml.org,2002:value' in "", line 1, column 1:

^

`

There was, in the past, a ticket against PyYAML; but I suspect it got lost in a migration. See https://web.archive.org/web/20100707124750/http://pyyaml.org:80/ticket/140

The SnakeYAML people had a discussion of correct behaviour in this sort of situation at https://code.google.com/archive/p/snakeyaml/issues/192, the conclusion of which was (loosely paraphrased) "an equals sign is unambiguously a string value, and so doesn't need quoting, provided that you ignore the Value Key Language-Independent Type facility which never really worked anyway."

The equivalent fix to the one in SnakeYAML would be to remove the following lines from resolver.py:

Resolver.add_implicit_resolver(
        u'tag:yaml.org,2002:value',
        re.compile(ur'^(?:=)$'),
        [u'='])

I've also found it is possible to work around the issue with the following:

def construct_value(load, node):
    if not isinstance(node, yaml.ScalarNode):
        raise yaml.constructor.ConstructorError(
            "while constructing a value",
            node.start_mark,
            "expected a scalar, but found %s" % node.id, node.start_mark
        )
    yield str(node.value)

yaml.Loader.add_constructor(u'tag:yaml.org,2002:value', construct_value)
stuart-warren commented 5 years ago

we are hitting this too

jonapich commented 2 years ago

Since the bug is that = is assigned tag:yaml.org,2002:value even though there's no constructor for it, a simple fix is to pop that one from your loader:

Loader.yaml_implicit_resolvers.pop("=")

You can isolate the fix to your own loader too:

class PatchedFullLoader(FullLoader):
    yaml_implicit_resolvers = FullLoader.yaml_implicit_resolvers.copy()
    yaml_implicit_resolvers.pop("=")
krichter722 commented 9 months ago

Has someone bisected this issue yet and can share a range of versions which are affected (probably open end because the issues isn't fixed yet)? I see this issue is being referenced as upstream issue by a lot of bugs, among them some Helm Charts rolled out with Ansible. The version range helps in mitigating downstream issues - a fix is very welcome as well of course. I guess they affected pyyaml version has made it in a lot of downstream tools. In there environment it's impossible or hard to apply the workaround (thanks) without ugly patches.