问题
About 5 hours ago, version 4.1.0
was released. It is breaking my unit tests. Here is a clean MVCE displaying this:
Version 3.12:
>>> import numpy as np
>>> import yaml
>>> x = np.int64(2)
>>> yaml.dump(x, Dumper=yaml.Dumper)
'!!python/object/apply:numpy.core.multiarray.scalar\n- !!python/object/apply:numpy.dtype\n args: [i8, 0, 1]\n state: !!python/tuple [3, <, null, null, null, -1, -1, 0]\n- !!binary |\n AgAAAAAAAAA=\n'
Version 4.1.0:
>>> import numpy as np
>>> import yaml
>>> x = np.int64(2)
>>> yaml.dump(x, Dumper=yaml.Dumper)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/foo/anaconda3/envs/bar/lib/python3.6/site-packages/yaml/__init__.py", line 217, in dump
return dump_all([data], stream, Dumper=Dumper, **kwds)
File "/foo/anaconda3/envs/bar/lib/python3.6/site-packages/yaml/__init__.py", line 196, in dump_all
dumper.represent(data)
File "/foo/anaconda3/envs/bar/lib/python3.6/site-packages/yaml/representer.py", line 26, in represent
node = self.represent_data(data)
File "/foo/anaconda3/envs/bar/lib/python3.6/site-packages/yaml/representer.py", line 57, in represent_data
node = self.yaml_representers[None](self, data)
File "/foo/anaconda3/envs/bar/lib/python3.6/site-packages/yaml/representer.py", line 229, in represent_undefined
raise RepresenterError("cannot represent an object", data)
yaml.representer.RepresenterError: ('cannot represent an object', 2)
Is there a clear reason for why PyYAML
no longer supports these object types?
回答1:
dump
is now safe_dump
, which won't handle arbitrary objects:
>>> yaml.dump is yaml.safe_dump
True
Use danger_dump
for the old behaviour.
>>> yaml.danger_dump(x)
'!!python/object/apply:numpy.core.multiarray.scalar\n- !!python/object/apply:numpy.dtype\n args: [i8, 0, 1]\n state: !!python/tuple [3, <, null, null, null, -1, -1, 0]\n- !!binary |\n AgAAAAAAAAA=\n'
The same goes for load
/safe_load
. Can't find the docs or release notes for 4.1.0, I only found out by digging through the commits (here).
Is there a clear reason for why PyYAML no longer supports these object types?
Yes. yaml.load
was allowing arbitrary code execution, and such a dangerous feature should be opt-in only - not possible to use by accident. Arguably, it should have been this way from the beginning, and I'm glad the new maintainers of PyYAML have corrected that.
来源:https://stackoverflow.com/questions/51053903/new-pyyaml-version-breaks-on-most-custom-python-objects-representererror