首页 > 解决方案 > unittest.assertRaisesRegex 被称为上下文管理器时的不同错误消息

问题描述

上下文(可以跳过,真正的问题在后面)

整件事并不重要,但我正在进行一项让我越来越困惑的调查。

我的一个宠物项目有一些依赖 Python 异常消息(而不仅仅是类型)的逻辑。由于它非常脆弱,我确保我可以在 Travis 上运行大多数 Python 版本的东西。

最近,我意识到这段代码set.add(0)导致了一个异常,其消息应该是这样的:

描述符“add”需要一个“set”对象但收到一个“int”

然而,在 Python 3.7+ 的某些版本中,在一些测试用例中情况开始有所不同。显然消息更像是:

“‘set’对象的描述符‘add’不适用于‘int’对象”

仅仅因为我想确定这是 Python 开发人员的意图,我想找到确切的提交来改变它,git bisect并开始寻找一种简单的方法来重现这个问题。不幸的是,我无法在本地重现这种行为,一件事导致另一件事我掉进了兔子洞,以许多谜团结束,其中一个涉及unittest.assertRaisesRegex.

意外unittest.assertRaisesRegex行为

我编写了以下测试,这些测试看起来与文档中的示例惊人地相似unittest.assertRaisesRegex——一个测试提供可调用和相应的参数,另一个测试依赖于上下文管理器:

    DESCRIPT_REQUIRES_TYPE_RE = r"descriptor '\w+' requires a 'set' object but received a 'int'"

    ...

    def test_assertRaisesRegex(self):
        self.assertRaisesRegex(TypeError, DESCRIPT_REQUIRES_TYPE_RE, set.add, 0)

    def test_assertRaisesRegex_contextman(self):
        with self.assertRaisesRegex(TypeError, DESCRIPT_REQUIRES_TYPE_RE):
            set.add(0)

我希望他们两个都有完全相同的行为,但他们没有。

(版本号用python -VV和检索python -c "import sys; print(sys._git)"

当它们发生时,故障如下所示:

======================================================================
FAIL: test_assertRaisesRegex (didyoumean_sugg_tests.SetAddIntRegexpTests)
----------------------------------------------------------------------
TypeError: descriptor 'add' for 'set' objects doesn't apply to 'int' object
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/home/travis/build/.../didyoumean_sugg_tests.py", line 19, in test_assertRaisesRegex
    self.assertRaisesRegex(TypeError, DESCRIPT_REQUIRES_TYPE_RE, set.add, 0)
AssertionError: "descriptor '\w+' requires a 'set' object but received a 'int'" does not match "descriptor 'add' for 'set' objects doesn't apply to 'int' object"

======================================================================
FAIL: test_assertRaisesRegex_contextman (didyoumean_sugg_tests.SetAddIntRegexpTests)
----------------------------------------------------------------------
TypeError: descriptor 'add' for 'set' objects doesn't apply to 'int' object
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/home/travis/build/.../didyoumean/didyoumean_sugg_tests.py", line 23, in test_assertRaisesRegex_contextman
    set.add(0)
AssertionError: "descriptor '\w+' requires a 'set' object but received a 'int'" does not match "descriptor 'add' for 'set' objects doesn't apply to 'int' object"

为什么这两个外观相似的测试会有不同的行为?

让我感到困惑的其他要点

TypeError: descriptor 'add' requires a 'set' object but received a 'int'

目前状态

一切都可能归结为我缺少的一个简单细节,但我现在一无所知。欢迎任何建议。如果需要更多数据,我很乐意触发更多 Travis 构建。

标签: pythonexceptionpython-unittest

解决方案


推荐阅读