From 4e332464b4f4e0f877bf91aca19d11b9ebe80c86 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 10 Mar 2026 13:34:37 +0100 Subject: [PATCH] [3.13] gh-142651: use `NonCallableMock._lock` for thread safety of `call_count` (GH-142922) (#145740) 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 1dd7735d150e..b6dd1c27fee1 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1178,10 +1178,16 @@ class CallableMixin(Base): # 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 -- 2.47.3