New submission from Elizabeth Uselton <[email protected]>:
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 <[email protected]>
<https://bugs.python.org/issue37555>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com