Bug Description
ThreadingMock._increment_mock_call() is not thread-safe.
Multiple threads calling the mock simultaneously lose increments
due to race conditions on call_count and other attributes.
Reproducer
import threading import unittest.mock m = unittest.mock.ThreadingMock() LOOPS = 10000 THREADS = 50 def test_function(): for _ in range(LOOPS): m() threads = [threading.Thread(target=test_function) for _ in range(THREADS)] for t in threads: t.start() for t in threads: t.join() assert m.call_count == LOOPS * THREADS # FAILS intermittently!
Expected vs Actual
- Expected: 500000
- Got: ~460000 (missing calls lost to race condition)
Environment
- Python 3.14
- Reproducible on ARM64 and x86 under load
- Reported via Yocto Project: https://bugzilla.yoctoproject.org/show_bug.cgi?id=16213
Linked PRs
- gh-150175: Fix ThreadingMock call_count race condition #150176
- [3.13] gh-150175: Fix ThreadingMock call_count race condition (GH-150176) #150180
- [3.14] gh-150175: Fix ThreadingMock call_count race condition (GH-150176) #150181
- [3.15] gh-150175: Fix ThreadingMock call_count race condition (GH-150176) #150182