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

Reply via email to