新的PyYAML版本在大多数自定义python对象上中...

codeday· 2019-10-23
本文来自 codeday ,作者 codeday
大约5个小时前,发布了版本4.1.0.它破坏了我的单元测试.这是显示此内容的干净MVCE:

版本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
- !!python/object/apply:numpy.dtype
  args: [i8, 0, 1]
  state: !!python/tuple [3, <, null, null, null, -1, -1, 0]
- !!binary |
  AgAAAAAAAAA=
'

版本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)

为什么PyYAML不再支持这些对象类型有明确的原因?

最佳答案
现在,dump是safe_dump,它将不处理任意对象:

>>> yaml.dump is yaml.safe_dump
True

对旧的行为使用danger_dump.

>>> yaml.danger_dump(x)
'!!python/object/apply:numpy.core.multiarray.scalar
- !!python/object/apply:numpy.dtype
  args: [i8, 0, 1]
  state: !!python/tuple [3, <, null, null, null, -1, -1, 0]
- !!binary |
  AgAAAAAAAAA=
'

load / safe_load也是如此.找不到适用于4.1.0的文档或发行说明,我只是通过仔细研究提交(here)才发现的.

Is there a clear reason for why PyYAML no longer supports these object types?

是. yaml.load允许任意代码执行,而这样的危险功能应仅选择启用-不能偶然使用.可以说,从一开始就应该是这种方式,我很高兴PyYAML的新维护者已经纠正了这一点.