Skip to content

Allow callable mocks to make a perfect snapshot of their inputs #128254

@yanivshimoni89

Description

@yanivshimoni89

Bug report

Bug description:

Hi,
I'm experiencing an unexpected behaviour with unittest. Code example:

import unittest
from unittest.mock import MagicMock

class TestCallMutability(unittest.TestCase):
    def test_call_mutability(self):
        def side_effect(x: dict):
            x['a'] = 6

        mock_function = MagicMock()
        mock_function.side_effect = side_effect

        input_dict = {'b': 5}
        mock_function(input_dict)

        self.assertEqual(input_dict, {'b': 5, 'a': 6})
        mock_function.assert_called_once_with({'b': 5})

if __name__ == "__main__":
    unittest.main()

Expected behavior:
This test should pass.

Actual behaviour:
The test fails with the following traceback:

F
======================================================================
FAIL: test_call_mutability (tests.TestCallMutability)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pytest_bug_report/tests/__init__.py", line 16, in test_call_mutability
    mock_function.assert_called_once_with({'b': 5})
  File "/usr/lib/python3.10/unittest/mock.py", line 941, in assert_called_once_with
    return self.assert_called_with(*args, **kwargs)
  File "/usr/lib/python3.10/unittest/mock.py", line 929, in assert_called_with
    raise AssertionError(_error_message()) from cause
AssertionError: expected call not found.
Expected: mock({'b': 5})
Actual: mock({'b': 5, 'a': 6})

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

Basically, even though the call to the function for done using {'b': 5}, the call_args_list contains the value of the call after the change was done. My expected behavior is that the test would make a copy of the input, since the function was indeed called with {'b': 5}.

Thanks!

CPython versions tested on:

3.10

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions