summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2021-10-10 09:25:14 -0700
committerGitHub <noreply@github.com>2021-10-10 09:25:14 -0700
commit164dddf5f8c9c6b93f32c9f79b4301fc804576e9 (patch)
tree28d12e55896c5d219388fcf68cdd1dbeab82b772
parent3c270130774fa4d19fd5c2728b9309625da40b87 (diff)
downloadcpython-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.py2
-rw-r--r--Lib/test/test_asyncio/test_locks.py66
-rw-r--r--Misc/NEWS.d/next/Library/2021-10-10-09-42-34.bpo-45416.n35O0_.rst2
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