[New-bugs-announce] [issue37212] ordered keyword arguments in unittest.mock.call repr and error messages

Karthikeyan Singaravelan report at bugs.python.org
Mon Jun 10 03:53:37 EDT 2019


New submission from Karthikeyan Singaravelan <tir.karthi at gmail.com>:

With PEP 468 implemented in Python 3.6 the order of keyword arguments are preserved. In mock.call the arguments are sorted [0]. This makes the output different from the expectation that order should be same as the one passed. This was implemented in issue21256 where ordered kwargs was suggested but I guess it was not implemented and hence sort was used for deterministic output. The PEP also links to the discussion where ordered kwargs was discussed [1] in 2009 before ordered dict implementation.

Given that keyword argument dictionary is now deterministic is it okay to drop sorting in 3.9? This is backwards incompatible with 3.8 where code might have depended upon the sorted output so if this requires a python-dev discussion I would be happy to start one.


# (b=1, a=2) is the actual call but "actual" in error message is noted as (a=2, b=1)

>>> from unittest.mock import call, Mock
>>> call(b=1, a=2)
call(a=2, b=1)
>>> m = Mock()
>>> m(b=1, a=2)
<Mock name='mock()' id='4477750800'>
>>> m.assert_called_with(c=3)
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: mock(c=3)
Actual: mock(a=2, b=1)

# With proposed change removing sorting

>>> from unittest.mock import call, Mock
>>> call(b=1, a=2)
call(b=1, a=2)
>>> m = Mock()
>>> m(b=1, a=2)
<Mock name='mock()' id='4419010880'>
>>> m.assert_called_with(c=3)
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: mock(c=3)
Actual: mock(b=1, a=2)

[0] https://github.com/python/cpython/blob/c879ff247ae1b67a790ff98d2d59145302cd4e4e/Lib/unittest/mock.py#L2284
[1] https://mail.python.org/pipermail/python-ideas/2009-April/004163.html

----------
components: Library (Lib)
messages: 345106
nosy: cjw296, mariocj89, michael.foord, xtreak
priority: normal
severity: normal
status: open
title: ordered keyword arguments in unittest.mock.call repr and error messages
type: behavior
versions: Python 3.9

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue37212>
_______________________________________


More information about the New-bugs-announce mailing list