The call_count counter on mock.Mock is not atomic, so updates may be lost:
| asyncdeftest_to_thread_concurrent(self): |
| func=mock.Mock() |
| |
| futs= [] |
| for_inrange(10): |
| fut=asyncio.to_thread(func) |
| futs.append(fut) |
| awaitasyncio.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