【问题标题】:Python Dataclasses: FrozenInstanceError a subclass of AttributeError?Python Dataclasses:FrozenInstanceError 是 AttributeError 的子类?
【发布时间】:2019-05-29 13:42:53
【问题描述】:

我正在对新的 python 数据类进行一些自学。

可以传递给数据类装饰器的参数之一是frozen=True,以使对象不可变。

文档(和经验)表明:

dataclasses.FrozenInstanceError

将引发异常。

当单元测试时(使用 pytest),以下测试通过:

def test_change_page_url_values_raises_error(self, PAGE_URL):
    page_url = PageURL(PAGE_URL)
    with pytest.raises(AttributeError) as error:
        page_url.value = PAGE_URL

其中 PageURL 是具有 freeze=True 参数的数据类。

任何想法为什么 pytest 表明此操作(将值分配给 page_url.value)会引发属性错误? FrozenInstanceError 是否继承自 AttributeError?

注意:如果我更改单元测试以测试不同的异常(即 TypeError),测试会按预期失败。

【问题讨论】:

  • 签入 shell issubclass(dataclasses.FrozenInstanceError, AttributeError)
  • 啊。谢谢你。为了调查这个我一直在尝试:在单元测试本身中断言 issubclass(type(error), AttributeError) 。我刚刚意识到 pytest 正在返回一个 ExceptionInfo 类作为错误,而不是最初引发的异常... facepalm 下次返回 shell。
  • @Steven 为了将来参考,最初引发的异常被存储为ExceptionInfo 上下文管理器的value 属性,即error.value

标签: python pytest python-dataclasses


【解决方案1】:

这是一个子类,您可以使用内置函数issubclass轻松验证:

>>> issubclass(FrozenInstanceError, AttributeError)
True

如果您希望在测试中使用 exact 类型匹配(我认为这是最佳实践),那么您可以使用异常实例而不是异常类。作为一个额外的好处,这还允许您对异常上下文(即哪个字段触发了异常)进行断言。

with pytest.raises(FrozenInstanceError("cannot assign to field 'value'")):
    page_url.value = PAGE_URL

pytest.raises 的这种用法需要安装我的插件pytest-raisin

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    相关资源
    最近更新 更多