【发布时间】:2020-05-27 10:27:02
【问题描述】:
我有一个使用 Python 3.6+ __set_name__ 的子类,以确保拥有的类已经注释了承载子类的字段的类型。如果他们没有引发异常。
但是,引发的任何异常总是被 Python 捕获,并改为引发 RuntimeError。
例如:
class Child:
def __set_name__(self, owner, name):
raise Exception("OOPS!")
class Owner():
child = Child()
结果:
Traceback (most recent call last):
File "<stdin>", line 3, in __set_name__
Exception: OOPS!
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: Error calling __set_name__ on 'Child' instance 'child' in 'Owner'
这很可能是预期的行为(找不到对__set_name__ 异常的具体引用),但也可能表明预期__set_name__ 永远不会遭受异常。
我看到的行为不是问题,因为在正确的条件下会发生异常。但是,由于我不能确定引发的异常是我的代码引发的异常,因此测试起来很棘手。
有没有更好的方法来引发一个适合测试的异常,或者确实有一种简单的方法来检查由RuntimeError 包装的异常确实是我的代码引发的那个?
【问题讨论】:
-
我真的认为这是对
__set_name__的滥用,它是描述符协议的一部分...可能有更好的方法来确保注释,例如使用静态分析工具,例如 mypy > -
注意,我不认为这是被包装的。基本上,我敢打赌
type中有一个很大的try:... except Exception as e:,如果任何属于类创建的一部分引发错误,它只会引发此运行时错误。我找不到任何官方文档,这可能都是实现细节...... -
你应该可以访问 RuntimeError 的
__cause__来测试它是否是你引发的异常。 -
@juanpa.arrivillaga - 你确实可以认为这是对
__set_name__的滥用,除了没有记录的异常不应该被提出......我正在寻找一个纯Python解决方案,所以在这个阶段不要选择采用 mypy。
标签: python python-3.x exception python-descriptors