bpo-36871: Ensure method signature is used when asserting mock calls to a method by tirkarthi · Pull Request #13261 · python/cpython

Though this is an internal method there is a note on the docstring of _call_matcher that it could be a tuple. It's not specified in docs that this could be a tuple. I haven't seen a usecase of it in other projects too. There is a test for this usecase but it's not using autospec so it didn't fail with my PR I guess. Relevant test using tuples

Given a call (or simply an (args, kwargs) tuple), return a
comparison key suitable for matching with other calls.

There could be a below test that passes with checking _call to be a tuple.

    def test_assert_has_calls_tuple(self):
        class Something:

            def __init__(self): pass
            def meth(self, a, b, c, d=None): pass

        m = create_autospec(Something)
        m.meth(1, 2, 3, 1)
        m.assert_has_calls([('meth', (1, 2, 3, 1), {})])

On having a strict check of only using _Call it will fail since it will go on to use the constructor signature.

./python.exe -m unittest Lib.unittest.test.testmock.testmock.MockTest.test_assert_has_calls_tuple
F
======================================================================
FAIL: test_assert_has_calls_tuple (Lib.unittest.test.testmock.testmock.MockTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/unittest/test/testmock/testmock.py", line 1387, in test_assert_has_calls_tuple
    m.assert_has_calls([('meth', (1, 2, 3, 1), {})])
  File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/unittest/mock.py", line 876, in assert_has_calls
    raise AssertionError(
AssertionError: Calls not found.
Expected: [('meth', (1, 2, 3, 1), {})]
Actual: [call.meth(1, 2, 3, 1)].

----------------------------------------------------------------------
Ran 1 test in 0.063s

FAILED (failures=1)

I am leaning towards removing tuple to support only _Call since the error message is also not useful. We can perhaps change it in 3.9 to accept only _Call and then revert back if someone complains that it breaks their workflow given there is plenty of time. I am not sure about backporting it to 3.8 though since beta is out. Would also like to know thoughts from @voidspace since this was added in the original commit where mock was added.