新的 PyYAML 版本在大多数自定义 python 对象上中断 - RepresenterError [英] New PyYAML version breaks on most custom python objects - RepresenterError

查看:47
本文介绍了新的 PyYAML 版本在大多数自定义 python 对象上中断 - RepresenterError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大约 5 小时前,4.1.0 版本发布.它打破了我的单元测试.这是一个干净的 MVCE 显示:

3.12 版:

<预><代码>>>>将 numpy 导入为 np>>>导入 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- !!二进制 |\n AgAAAAAAAAA=\n'

4.1.0 版:

<预><代码>>>>将 numpy 导入为 np>>>导入 yaml>>>x = np.int64(2)>>>yaml.dump(x, Dumper=yaml.Dumper)回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中转储中的文件/foo/anaconda3/envs/bar/lib/python3.6/site-packages/yaml/__init__.py",第 217 行返回 dump_all([数据], 流, Dumper=Dumper, **kwds)文件/foo/anaconda3/envs/bar/lib/python3.6/site-packages/yaml/__init__.py",第 196 行,在 dump_alldumper.represent(数据)文件/foo/anaconda3/envs/bar/lib/python3.6/site-packages/yaml/representer.py",第26行,代表节点 = self.represent_data(data)文件/foo/anaconda3/envs/bar/lib/python3.6/site-packages/yaml/representer.py",第57行,在represent_datanode = self.yaml_representers[None](self, data)文件/foo/anaconda3/envs/bar/lib/python3.6/site-packages/yaml/representer.py",第229行,在represent_undefinedraise RepresenterError("不能代表一个对象",数据)yaml.representer.RepresenterError: ('不能代表一个对象', 2)

PyYAML 不再支持这些对象类型是否有明确的原因?

解决方案

在 PyYAML 4.x 中,dumpsafe_dump 的别名,它不会处理任意对象:

<预><代码>>>>yaml.dump 是 yaml.safe_dump真的

对旧的 3.x 行为使用 danger_dump.

<预><代码>>>>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- !!二进制 |\n AgAAAAAAAAA=\n'

load/safe_load 也是如此.找不到 4.1.0 的任何文档或发行说明,我只是通过挖掘提交才发现(这里).

<块引用>

PyYAML 不再支持这些对象类型是否有明确的原因?

是的.yaml.load 允许任意代码执行,这种危险的功能应该只选择加入,不能意外使用.可以说,从一开始就应该是这样.

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?

解决方案

In PyYAML 4.x, dump is an alias for safe_dump, which won't handle arbitrary objects:

>>> yaml.dump is yaml.safe_dump
True

Use danger_dump for the old 3.x 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 any 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.

这篇关于新的 PyYAML 版本在大多数自定义 python 对象上中断 - RepresenterError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆