The call_count counter on mock.Mock is not atomic, so updates may be lost:
|
async def test_to_thread_concurrent(self): |
|
func = mock.Mock() |
|
|
|
futs = [] |
|
for _ in range(10): |
|
fut = asyncio.to_thread(func) |
|
futs.append(fut) |
|
await asyncio.gather(*futs) |
|
|
|
self.assertEqual(func.call_count, 10) |
This leads to occasional errors like:
File "Lib/test/test_asyncio/test_threads.py", line 41, in test_to_thread_concurrent
self.assertEqual(func.call_count, 10)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
AssertionError: 9 != 10
I think the update is not actually atomic even with the GIL because of the use of _delegating_property in Mock, but I'm not entirely sure. The failures are definitely more likely to occur in the free-threaded build.
Linked PRs
The
call_countcounter onmock.Mockis not atomic, so updates may be lost:cpython/Lib/test/test_asyncio/test_threads.py
Lines 32 to 41 in ab094d1
This leads to occasional errors like:
I think the update is not actually atomic even with the GIL because of the use of
_delegating_propertyinMock, but I'm not entirely sure. The failures are definitely more likely to occur in the free-threaded build.Linked PRs