From Python 3.6 the order of keyword arguments to a function is preserved. In https://bugs.python.org/issue21256 the order of keyword arguments for unittest.mock's repr were sorted to return deterministic output for usage in doctest and other use cases. This currently gives little inconsistent output where the keyword argument order in below mock call is (b=2, a=1) but it's sorted in the error message and mock_calls list to give (a=1, b=2).
I have opened https://bugs.python.org/issue37212 to preserve the order. It was recommended in the issue 21256 too at https://bugs.python.org/issue21256#msg216512 . The drawback is that it's backwards incompatible where tests that assert error messages might have used the sorted order. Due to equality implementation call(a=1, b=2) == call(b=2, a=1) is still True so assertions are not affected. There are no test failures in mock test suite except the test in the original issue where sorted output is asserted. Sorting the keyword arguments was also not documented. I propose removing this sorted order in 3.9 and to preserve the original order. The change is straightforward and I can add a PR if this change is accepted.
from unittest.mock import Mock, call m = Mock(name='m') m(b=2, a=1)
<Mock name='m()' id='4339069168'> call(a=1, b=2) == call(b=2, a=1) True m.mock_calls [call(a=1, b=2)] m.assert_called_with(c=1) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/unittest/mock.py", line 870, in assert_called_with raise AssertionError(_error_message()) from cause AssertionError: expected call not found. Expected: m(c=1) Actual: m(a=1, b=2)