https://github.com/python/cpython/commit/728e4a075e3dae7e04edf90ad137a35073deb141
commit: 728e4a075e3dae7e04edf90ad137a35073deb141
branch: main
author: Kumar Aditya <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-03-10T12:11:12Z
summary:

gh-142651: use `NonCallableMock._lock` for thread safety of `call_count` 
(#142922)

files:
M Lib/unittest/mock.py

diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 34fd49bf56fbb6..64a01a0b713c61 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1184,10 +1184,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

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to