-
Notifications
You must be signed in to change notification settings - Fork 575
Description
The issue is about the following lines in construct_object method of BaseConstructor class
pyyaml/lib/yaml/constructor.py
Lines 76 to 84 in 5986257
| for tag_prefix in self.yaml_multi_constructors: | |
| if node.tag.startswith(tag_prefix): | |
| tag_suffix = node.tag[len(tag_prefix):] | |
| constructor = self.yaml_multi_constructors[tag_prefix] | |
| break | |
| else: | |
| if None in self.yaml_multi_constructors: | |
| tag_suffix = node.tag | |
| constructor = self.yaml_multi_constructors[None] |
I wanted to set up a multiconstructor for unknows tags. It seems like these lines are responsible for picking a default multiconstructor and therefore to define one I had to add a multiconstructor for None value as a tag_prefix
pyyaml/lib/yaml/constructor.py
Lines 82 to 84 in 5986257
| if None in self.yaml_multi_constructors: | |
| tag_suffix = node.tag | |
| constructor = self.yaml_multi_constructors[None] |
At the very least the lines hint that None is considered a valid key for self.yaml_multi_constructors. But the only way the execution can reach these lines is by traversing all the keys in self.yaml_multi_constructors first.
Now, if None is one of the keys, we get an exception TypeError: startswith first arg must be str, unicode, or tuple, not NoneType on line 77 making lines 83-84 effectively unreachable
pyyaml/lib/yaml/constructor.py
Line 77 in 5986257
| if node.tag.startswith(tag_prefix): |
Minimal non-working example:
import yaml
class MyLoader(yaml.loader.Loader):
pass
def default_multi_constructor(loader, tag_suffix, node):
return node.tag
MyLoader.add_multi_constructor(None, default_multi_constructor)
if __name__ == '__main__':
print yaml.load('''!som:multitag {}''', MyLoader)