[New-bugs-announce] [issue37555] _CallList.__contains__ doesn't always respect ANY.
Elizabeth Uselton
report at bugs.python.org
Thu Jul 11 01:12:04 EDT 2019
New submission from Elizabeth Uselton <elizabeth.uselton at gmail.com>:
I have a test that goes something like:
```
@patch('a.place.to.patch')
def test_a_thing_calls_what_it_should(self, my_mock):
# Set up logic here
my_mock.assert_has_calls([
call(
ANY,
Decimal('20')
),
call(
ANY,
Decimal('10')
)
])```
Which fails, where my_mock.call_args_list looks like
```
[(<A Django Model>, Decimal('20')), (<A Django Model>, Decimal('10'))]
```
This seems like wrong behavior. ANY should be happy to be compared to anything, even a Django object. Doing some digging, I found that on line 340 of cpython/Lib/unittest/mock.py _CallList is overriding __contains__ and comparing each item in the tuples with what I'd passed in to assert_has_calls on the right, which means that instead of using ANY.__eq__, it's calling the Django model's __eq__ with ANY as an argument. Django first checks if the thing it's comparing to is another Django model, and returns False if not. So, <DjangoModel> == ANY is False, but ANY == <DjangoModel> is True. I know that this could also be considered a bug with Django, and I plan to file one with them too, but I don't see any downside to improving the mock library to be more defensive in honoring ANY over any other custom class's overridden __eq__ method.
----------
components: Tests
messages: 347652
nosy: Elizabeth Uselton
priority: normal
severity: normal
status: open
title: _CallList.__contains__ doesn't always respect ANY.
type: behavior
versions: Python 3.5, Python 3.6, Python 3.7, Python 3.8, Python 3.9
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue37555>
_______________________________________
More information about the New-bugs-announce
mailing list