Skip to content

bpo-37555: Update _CallList.__contains__ to respect ANY #14700

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Sep 13, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
94ddf54
Flip equality to use mock calls' __eq__
ElizabethU Jul 11, 2019
b4c7d78
bpo-37555: Regression test demonstrating assert_has_calls not working…
ElizabethU Jul 14, 2019
ad99a9d
Revert "Flip equality to use mock calls' __eq__"
ElizabethU Jul 14, 2019
49c5310
bpo-37555: Add regression tests for mock ANY ordering issues
ElizabethU Jul 15, 2019
874fb69
bpo-37555: Fix _CallList and _Call order sensitivity
ElizabethU Jul 18, 2019
d72d6f5
bpo-37555: Ensure _call_matcher returns _Call object
ElizabethU Jul 20, 2019
f0e8411
Adding ACK and news entry
ElizabethU Jul 20, 2019
f295eac
bpo-37555: Replacing __eq__ with == to sidestep NotImplemented
ElizabethU Jul 20, 2019
18e964b
bpo-37555: cleaning up changes unnecessary to the final product
ElizabethU Jul 20, 2019
883841a
bpo-37555: Fixed call on bound arguments to respect args and kwargs
ElizabethU Jul 20, 2019
f4844c7
Revert "bpo-37555: Add regression tests for mock ANY ordering issues"
ElizabethU Jul 22, 2019
84489c8
Revert "bpo-37555: cleaning up changes unnecessary to the final product"
ElizabethU Jul 22, 2019
344ef17
Revert "bpo-37555: Replacing __eq__ with == to sidestep NotImplemented"
ElizabethU Jul 22, 2019
bdf430d
Revert "bpo-37555: Fix _CallList and _Call order sensitivity"
ElizabethU Jul 22, 2019
d3522b1
Updated NEWS.d
ElizabethU Jul 22, 2019
f47699d
bpo-37555: Add tests checking every function using _call_matcher both…
ElizabethU Aug 4, 2019
38650c9
bpo-37555: Ensure all assert methods using _call_matcher are actually…
ElizabethU Aug 5, 2019
24973c0
Remove AnyCompare and use call objects everywhere.
tirkarthi Aug 19, 2019
001d708
Revert "Remove AnyCompare and use call objects everywhere."
ElizabethU Sep 13, 2019
25dec66
Check for exception in assert_any_await
ElizabethU Sep 13, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions Lib/unittest/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,13 +337,19 @@ def __contains__(self, value):

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 == other_list or other_list == self_list


def _check_and_set_parent(parent, value, name, new_name):
# function passed to create_autospec will have mock
Expand Down Expand Up @@ -814,7 +820,7 @@ def _call_matcher(self, _call):
else:
name, args, kwargs = _call
try:
return name, sig.bind(*args, **kwargs)
return call(name, sig.bind(*args, **kwargs))
except TypeError as e:
return e.with_traceback(None)
else:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -2403,8 +2408,12 @@ def __eq__(self, other):
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 == other_params
or other_params == self_params
)


__ne__ = object.__ne__
Expand Down
32 changes: 32 additions & 0 deletions Lib/unittest/test/testmock/testhelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,19 @@ def __ne__(self, other): pass
]
self.assertEqual(expected, mock.mock_calls)
self.assertEqual(mock.mock_calls, expected)
mock.assert_has_calls(expected)

def test_assert_has_calls_with_any_and_spec_set(self):
# This is a regression test for bpo-37555
class Foo(object):
def __eq__(self, other): pass
def __ne__(self, other): pass

mock = Mock(spec_set=Foo)
expected = [call(ANY)]
mock(Foo())

mock.assert_has_calls(expected)


class CallTest(unittest.TestCase):
Expand Down Expand Up @@ -310,6 +322,16 @@ def test_call_list(self):
kall = call(1).method(2)(3).foo.bar.baz(4)(5).__int__()
self.assertEqual(kall.call_list(), mock.mock_calls)

def test_call_list_with_any_comparison_order(self):
class Foo:
def __eq__(self, other): pass
def __ne__(self, other): pass

mock = MagicMock()
mock(Foo())

self.assertEqual(call(ANY).call_list(), mock.mock_calls)
self.assertEqual(mock.mock_calls, call(ANY).call_list())

def test_call_any(self):
self.assertEqual(call, ANY)
Expand All @@ -319,6 +341,16 @@ def test_call_any(self):
self.assertEqual(m.mock_calls, [ANY])
self.assertEqual([ANY], m.mock_calls)

def test_call_any_comparison_order(self):
class Foo:
def __eq__(self, other): pass
def __ne__(self, other): pass

m = MagicMock()
m(Foo())

self.assertEqual(m.mock_calls[0], call(ANY))
self.assertEqual(call(ANY), m.mock_calls[0])

def test_two_args_call(self):
args = _Call(((1, 2), {'a': 3}), two=True)
Expand Down
2 changes: 2 additions & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ Tomer Filiba
Segev Finer
Jeffrey Finkelstein
Russell Finn
Neal Finne
Dan Finnie
Nils Fischbeck
Frederik Fix
Expand Down Expand Up @@ -1699,6 +1700,7 @@ Roger Upole
Daniel Urban
Michael Urman
Hector Urtubia
Elizabeth Uselton
Lukas Vacek
Ville Vainio
Andi Vajda
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fix `NonCallableMock._call_matcher` returning tuple instead of `_Call` object
when `self._spec_signature` exists. Additionally fix `__eq__` to be
commutative on `_Call` and `_CallList`, to better account for `ANY`. Patch by
Elizabeth Uselton