pyyaml: ConstructorError - could not determine a constructor for custom tag (5.1)
The following code was working on 3.13 but no longer works in 5.1:
import yaml
class Ref(yaml.YAMLObject):
yaml_tag = '!Ref'
def __init__(self, val):
self.val = val
@classmethod
def from_yaml(cls, loader, node):
return cls(node.value)
yaml.load('Foo: !Ref bar')
I get the following exception on 5.1:
yaml.constructor.ConstructorError: could not determine a constructor for the tag '!Ref'
in "<unicode string>", line 1, column 6:
Foo: !Ref bar
This is true whether I use yaml.load, yaml.full_load or yaml.unsafe_load.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 6
- Comments: 29 (11 by maintainers)
Commits related to this issue
- fix yaml could not determine a constructor https://github.com/yaml/pyyaml/issues/266 — committed to AnomeGAP/aztk-backup by SidWeng 4 years ago
- Fixed toolflow files to build in Ubuntu 16.04LTS The requirements.txt file has been updated with the "numpy<1.19". Version 1.18.5was the last to support Python 3.5, which we are using. The newer versi... — committed to ska-sa/mlib_devel by AdamI75 3 years ago
- Fixed toolflow files to build in Ubuntu 16.04LTS The requirements.txt file has been updated with the "numpy<1.19". Version 1.18.5was the last to support Python 3.5, which we are using. The newer vers... — committed to casper-astro/mlib_devel by AdamI75 3 years ago
- https://github.com/yaml/pyyaml/issues/266 — committed to sivanoff/rclone-changer by sivanoff 3 years ago
Try
I’m not sure though if this is intentional. Will have a closer look later.
None of the workarounds above worked for me, I had to use this loader:
Loader=yaml.BaseLoaderonPython 3.7.0PyYaml==5.1.2or== 5.2b1(edited) I reproduced using the same code:
yaml.load('Foo: !Ref bar')This worked for me :yaml.load('Foo: !Ref bar', Loader=yaml.BaseLoader)This is a breaking change, and is likely to break a ton of code out there that worked just fine: I spent myself a whole afternoon trying to figure out what I’d changed that broke all my tests.
Are you guys going to revert changes, or provide a better error message (at the very least)?
Today I encountered the same problem. Even the example straight from the documentation on the homepage does not work anymore
Backtrace:
Edit: This seems to work (why?)
I’m using version 5.3 like so:
But I still got the same error.
I resolved the issue by following https://github.com/yaml/pyyaml/issues/266#issuecomment-559116876.
ok, I think I see it now. From https://github.com/yaml/pyyaml/blob/e471e86bf6dabdad45a1438c20a4a5c033eb9034/lib/yaml/__init__.py#L386, the loader for metaclass-driven custom tags defaults to yaml.Loader. The following also works for me:
Python 3.6.10 PyYAML 5.3.1
The error is resolved when I use
yaml.BaseLoader. However,!Refis ignored and missing in the loaded content. It won’t work withoutclass Ref, like @perlpunk mentioned.@ryanbrookepayne
BaseLoaderonly works because it is ignoring theweakreferencetag. To do it correctly, you would have to use the loader for which you added the constructor.safe_loaddoesn’t work for me butLoader=yaml.Loaderdoes.To ignore all tags (not yet defined) in SafeLoader:
@vallamost I think the yaml.BaseLoader ignores 'em
@perlpunk This was a misunderstanding on my part, I hadn’t defined the Ref class in my example. So it works now! And my real code is working now too, thanks for your help.
@BonnieH @maru-podmast I can only reproduce this without using the original code at the top of the issue. Can you execute this code and show the output please?
Without that
class Refof course it can’t work. BaseLoader simply ignores the unknown tags.@maru-podmast sorry, I can’t reproduce. the original code works for me with 5.2b1 and 5.2:
@maru-podmast do you have some code to reproduce?
I created #273