diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2021-10-10 09:25:14 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-10 09:25:14 -0700 |
commit | 164dddf5f8c9c6b93f32c9f79b4301fc804576e9 (patch) | |
tree | 28d12e55896c5d219388fcf68cdd1dbeab82b772 | |
parent | 3c270130774fa4d19fd5c2728b9309625da40b87 (diff) | |
download | cpython-git-164dddf5f8c9c6b93f32c9f79b4301fc804576e9.tar.gz |
bpo-45416: Fix use of asyncio.Condition() with explicit Lock objects (GH-28850)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
(cherry picked from commit 1a7892414e654aa5c99efa31db767baba7f4a424)
Co-authored-by: Joongi Kim <joongi@lablup.com>
-rw-r--r-- | Lib/asyncio/locks.py | 2 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_locks.py | 66 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2021-10-10-09-42-34.bpo-45416.n35O0_.rst | 2 |
3 files changed, 57 insertions, 13 deletions
diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index a7453fb1c7..4fef64e392 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -230,8 +230,6 @@ class Condition(_ContextManagerMixin, mixins._LoopBoundMixin): super().__init__(loop=loop) if lock is None: lock = Lock() - elif lock._loop is not self._get_loop(): - raise ValueError("loop argument must agree with lock") self._lock = lock # Export the lock's locked(), acquire() and release() methods. diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index 6194cd0617..623db5fda6 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -724,24 +724,68 @@ class ConditionTests(test_utils.TestCase): self.loop.run_until_complete(f()) def test_explicit_lock(self): - lock = asyncio.Lock() - cond = asyncio.Condition(lock) + async def f(lock=None, cond=None): + if lock is None: + lock = asyncio.Lock() + if cond is None: + cond = asyncio.Condition(lock) + self.assertIs(cond._lock, lock) + self.assertFalse(lock.locked()) + self.assertFalse(cond.locked()) + async with cond: + self.assertTrue(lock.locked()) + self.assertTrue(cond.locked()) + self.assertFalse(lock.locked()) + self.assertFalse(cond.locked()) + async with lock: + self.assertTrue(lock.locked()) + self.assertTrue(cond.locked()) + self.assertFalse(lock.locked()) + self.assertFalse(cond.locked()) - self.assertIs(cond._lock, lock) - self.assertIs(cond._loop, lock._loop) + # All should work in the same way. + self.loop.run_until_complete(f()) + self.loop.run_until_complete(f(asyncio.Lock())) + lock = asyncio.Lock() + self.loop.run_until_complete(f(lock, asyncio.Condition(lock))) def test_ambiguous_loops(self): - loop = self.new_test_loop() + loop = asyncio.new_event_loop() self.addCleanup(loop.close) - lock = asyncio.Lock() - lock._loop = loop + async def wrong_loop_in_lock(): + with self.assertRaises(TypeError): + asyncio.Lock(loop=loop) # actively disallowed since 3.10 + lock = asyncio.Lock() + lock._loop = loop # use private API for testing + async with lock: + # acquired immediately via the fast-path + # without interaction with any event loop. + cond = asyncio.Condition(lock) + # cond.acquire() will trigger waiting on the lock + # and it will discover the event loop mismatch. + with self.assertRaisesRegex( + RuntimeError, + "is bound to a different event loop", + ): + await cond.acquire() - async def _create_condition(): - with self.assertRaises(ValueError): - asyncio.Condition(lock) + async def wrong_loop_in_cond(): + # Same analogy here with the condition's loop. + lock = asyncio.Lock() + async with lock: + with self.assertRaises(TypeError): + asyncio.Condition(lock, loop=loop) + cond = asyncio.Condition(lock) + cond._loop = loop + with self.assertRaisesRegex( + RuntimeError, + "is bound to a different event loop", + ): + await cond.wait() - self.loop.run_until_complete(_create_condition()) + self.loop.run_until_complete(wrong_loop_in_lock()) + self.loop.run_until_complete(wrong_loop_in_cond()) def test_timeout_in_block(self): loop = asyncio.new_event_loop() diff --git a/Misc/NEWS.d/next/Library/2021-10-10-09-42-34.bpo-45416.n35O0_.rst b/Misc/NEWS.d/next/Library/2021-10-10-09-42-34.bpo-45416.n35O0_.rst new file mode 100644 index 0000000000..cf335d1bcd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-10-10-09-42-34.bpo-45416.n35O0_.rst @@ -0,0 +1,2 @@ +Fix use of :class:`asyncio.Condition` with explicit :class:`asyncio.Lock` objects, which was a regression due to removal of explicit loop arguments.
+Patch by Joongi Kim.
\ No newline at end of file |