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.BaseLoader
onPython 3.7.0
PyYaml==5.1.2
or== 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,!Ref
is ignored and missing in the loaded content. It won’t work withoutclass Ref
, like @perlpunk mentioned.@ryanbrookepayne
BaseLoader
only works because it is ignoring theweakreference
tag. To do it correctly, you would have to use the loader for which you added the constructor.safe_load
doesn’t work for me butLoader=yaml.Loader
does.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 Ref
of 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