bpo-37555: Fix _CallList and _Call order sensitivity
_Call and _CallList depend on ordering to correctly process that an object being compared to ANY with __eq__ should return True. This fix updates the comparison to check both a == b and b == a and return True if either condition is met, fixing situations from the tests in the previous two commits where assertEqual would not be commutative if checking _Call or _CallList objects. This seems like a reasonable fix considering that the Python data model specifies that if an object doesn't know how to compare itself to another object it should return NotImplemented, and that on getting NotImplemented from a == b, it should try b == a, implying that good behavior for __eq__ is commutative. This also flips the order of comparison in _CallList's __contains__ method, guaranteeing ANY will be on the left and have it's __eq__ called for equality checking, fixing the interaction between assert_has_calls and ANY. Co-author: Neal Finne <neal@neal.finne.com>
This commit is contained in:
parent
49c5310ad4
commit
874fb697b8
|
@ -337,13 +337,19 @@ class _CallList(list):
|
|||
|
||||
for i in range(0, len_self - len_value + 1):
|
||||
sub_list = self[i:i+len_value]
|
||||
if sub_list == value:
|
||||
if value == sub_list:
|
||||
return True
|
||||
return False
|
||||
|
||||
def __repr__(self):
|
||||
return pprint.pformat(list(self))
|
||||
|
||||
def __eq__(self, other):
|
||||
self_list = list(self)
|
||||
other_list = list(other)
|
||||
# checking equality both directions is necessary for ANY to work
|
||||
return self_list.__eq__(other_list) or other_list.__eq__(self_list)
|
||||
|
||||
|
||||
def _check_and_set_parent(parent, value, name, new_name):
|
||||
# function passed to create_autospec will have mock
|
||||
|
@ -2293,7 +2299,6 @@ def _format_call_signature(name, args, kwargs):
|
|||
return message % formatted_args
|
||||
|
||||
|
||||
|
||||
class _Call(tuple):
|
||||
"""
|
||||
A tuple for holding the results of a call to a mock, either in the form
|
||||
|
@ -2403,8 +2408,12 @@ class _Call(tuple):
|
|||
if self_name and other_name != self_name:
|
||||
return False
|
||||
|
||||
# this order is important for ANY to work!
|
||||
return (other_args, other_kwargs) == (self_args, self_kwargs)
|
||||
self_params = self_args, self_kwargs
|
||||
other_params = other_args, other_kwargs
|
||||
return (
|
||||
self_params.__eq__(other_params)
|
||||
or other_params.__eq__(self_params)
|
||||
)
|
||||
|
||||
|
||||
__ne__ = object.__ne__
|
||||
|
|
Loading…
Reference in New Issue