From 8e4a5dc2afbe920e6500df9da73fd57e8c5ab6f8 Mon Sep 17 00:00:00 2001 From: saisneha196 <156835592+saisneha196@users.noreply.github.com> Date: Thu, 21 May 2026 13:08:07 +0530 Subject: [PATCH] gh-150175: Fix ThreadingMock call_count race condition (GH-150176) ThreadingMock._increment_mock_call() was not thread-safe. Multiple threads calling the mock simultaneously could lose increments due to race conditions on call_count and other attributes. Fix by overriding _increment_mock_call in ThreadingMixin and wrapping it with the existing _mock_calls_events_lock. (cherry picked from commit 388e023fe1197c1ffed374520ed45df4ac72b8f5) Co-authored-by: saisneha196 <156835592+saisneha196@users.noreply.github.com> --- Lib/unittest/mock.py | 4 ++++ .../Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 1cee67fa5d7094..2f6f03c7a11ae6 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -3121,6 +3121,10 @@ def _mock_call(self, *args, **kwargs): return ret_value + def _increment_mock_call(self, /, *args, **kwargs): + with self._mock_calls_events_lock: + super()._increment_mock_call(*args, **kwargs) + def wait_until_called(self, *, timeout=_timeout_unset): """Wait until the mock object is called. diff --git a/Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst b/Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst new file mode 100644 index 00000000000000..80fc80d4d50a63 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst @@ -0,0 +1,3 @@ +Fix race condition in :class:`unittest.mock.ThreadingMock` where +concurrent calls could lose increments to ``call_count`` and other +attributes due to a missing lock in ``_increment_mock_call``.