2 回答
TA贡献1777条经验 获得超3个赞
OSError有一个自定义__reduce__实现;不幸的是,对于与预期参数不匹配的子类,它不是子类友好的。__reduce__手动调用可以看到酸洗的中间状态:
>>> SubOSError.__reduce__(cce)
(modulename.SubOSError, (1, 'unittest'))
的第一个元素tuple是可调用的,第二个是tuple要传递的参数。因此,当它尝试重新创建您的课程时,它会:
modulename.SubOSError(1, 'unittest')
丢失了有关OSError您最初创建时使用的信息。
OSError.__reduce__如果您必须接受与/预期不匹配的参数OSError.__init__,您将需要编写自己的__reduce__覆盖以确保正确的信息被腌制。一个简单的版本可能是:
class SubOSError(OSError):
def __init__(self, foo, os_error):
self.foo = foo # Must preserve information for pickling later
super().__init__(os_error.errno, os_error.strerror)
def __reduce__(self):
# Pickle as type plus tuple of args expected by type
return type(self), (self.foo, OSError(*self.args))
使用该设计,SubOSError.__reduce__(cce)现在将返回:
(modulename.SubOSError, (1, PermissionError(1, 'unittest')))
其中 的第二个元素tuple是重新创建实例所需的正确参数(从OSError到的变化PermissionError是预期的;OSError实际上返回基于 的自己的子类errno)。
TA贡献1936条经验 获得超6个赞
此问题已于 2019 年 9 月 25 日修复并合并到 master 中aiohttp
。如果我注意到修复程序进入的版本,我将在未来更新此答案(请随时编辑此答案以记录包含此更新的版本) .
修复的 Git 问题:
https://github.com/aio-libs/aiohttp/issues/4077
添加回答
举报