gpt4 book ai didi

python - 如何为 __getitem__() 调用执行 assert_has_calls?

转载 作者:太空宇宙 更新时间:2023-11-04 01:52:44 26 4
gpt4 key购买 nike

代码:

from unittest.mock import MagicMock, call

mm = MagicMock()
mm().foo()['bar']

print(mm.mock_calls)
print()

mm.assert_has_calls([call(), call().foo(), call().foo().__getitem__('bar')])

输出:

[call(), call().foo(), call().foo().__getitem__('bar')]

Traceback (most recent call last):
File "foo.py", line 9, in <module>
mm.assert_has_calls([call(), call().foo(), call().foo().__getitem__('bar')])
TypeError: tuple indices must be integers or slices, not str

如何修复这个断言?

最佳答案

这是一个错误,因为您应该始终能够使用 call 对象的 repr 输出来重新创建新的 call 相同值的对象。

这里的问题是调用unittest.mock._Call 的一个实例, 依赖于 __getattr__方法来实现其链式调用注释魔术,其中在给出不存在的属性名称时返回另一个 _Call 对象。但是由于 _Calltuple 的子类,它确实定义了 __getitem__ 属性,所以 _Call.__getattr__ 方法将当请求属性 __getitem__ 时,只需返回 tuple.__getitem__ 而不是 _Call 对象。由于 tuple.__getitem__ 不接受字符串作为参数,因此您会收到上述错误。

要解决此问题,因为确定是否定义属性是通过调用 __getattribute__ 来完成的方法,当找不到给定的属性名称时引发 AttributeError,我们可以重写 _Call.__getattribute__ 以便在给定的属性名称为 时引发此类异常>'__getitem__',以有效地使 __getitem__ “不存在”并将其解析传递给 __getattr__ 方法,然后该方法将返回一个 _Call 对象就像调用任何其他不存在的属性一样:

def __getattribute__(self, attr):
if attr == '__getitem__':
raise AttributeError
return tuple.__getattribute__(self, attr)

call.__class__.__getattribute__ = __getattribute__ # call.__class__ is _Call

这样:

mm = MagicMock()
mm().foo()['bar']
mm.assert_has_calls([call(), call().foo(), call().foo().__getitem__('bar')])

不会引发异常,而:

mm.assert_has_calls([call(), call().foo(), call().foo().__getitem__('foo')])

会提高:

AssertionError: Calls not found.
Expected: [call(), call().foo(), call().foo().__getitem__('foo')]
Actual: [call(), call().foo(), call().foo().__getitem__('bar')]

演示:https://repl.it/repls/StrikingRedundantAngle

请注意,我已经提交了 bug在 Python bug tracker 上提交了我的修复程序 pull request到 CPython,希望您在不久的将来不再需要执行上述操作。

关于python - 如何为 __getitem__() 调用执行 assert_has_calls?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57636747/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com