From 3336a28adc269cfec6ae2fa0b9fe261747c97dc4 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Tue, 10 Mar 2026 17:41:12 +0530 Subject: [PATCH] gh-142651: use `NonCallableMock._lock` for thread safety of `call_count` (GH-142922) (cherry picked from commit 728e4a075e3dae7e04edf90ad137a35073deb141) Co-authored-by: Kumar Aditya --- Lib/unittest/mock.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 1dd7735d150ebe..b6dd1c27fee169 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1178,10 +1178,16 @@ def _increment_mock_call(self, /, *args, **kwargs): # handle call_args # needs to be set here so assertions on call arguments pass before # execution in the case of awaited calls - _call = _Call((args, kwargs), two=True) - self.call_args = _call - self.call_args_list.append(_call) - self.call_count = len(self.call_args_list) + with NonCallableMock._lock: + # Lock is used here so that call_args_list and call_count are + # set atomically otherwise it is possible that by the time call_count + # is set another thread may have appended to call_args_list. + # The rest of this function relies on list.append being atomic and + # skips locking. + _call = _Call((args, kwargs), two=True) + self.call_args = _call + self.call_args_list.append(_call) + self.call_count = len(self.call_args_list) # initial stuff for method_calls: do_method_calls = self._mock_parent is not None