diff options
author | Andrew Svetlov <andrew.svetlov@gmail.com> | 2020-02-01 11:12:52 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-01 11:12:52 (GMT) |
commit | 90d9ba6ef10af32e8dfe0649789c3a8ccf419e95 (patch) | |
tree | 5cd3e31fa3f1508ff72bfa0991bcdd8eeb9e3259 /Lib | |
parent | abb9a448dee3e18c69080231fbeba980bf048211 (diff) | |
download | cpython-90d9ba6ef10af32e8dfe0649789c3a8ccf419e95.zip cpython-90d9ba6ef10af32e8dfe0649789c3a8ccf419e95.tar.gz cpython-90d9ba6ef10af32e8dfe0649789c3a8ccf419e95.tar.bz2 |
bpo-34793: Drop old-style context managers in asyncio.locks (GH-17533)
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/asyncio/locks.py | 83 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_locks.py | 165 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_pep492.py | 13 |
3 files changed, 40 insertions, 221 deletions
diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index d94daeb..f1ce732 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -3,96 +3,13 @@ __all__ = ('Lock', 'Event', 'Condition', 'Semaphore', 'BoundedSemaphore') import collections -import types import warnings from . import events -from . import futures from . import exceptions -from .import coroutines - - -class _ContextManager: - """Context manager. - - This enables the following idiom for acquiring and releasing a - lock around a block: - - with (yield from lock): - <block> - - while failing loudly when accidentally using: - - with lock: - <block> - - Deprecated, use 'async with' statement: - async with lock: - <block> - """ - - def __init__(self, lock): - self._lock = lock - - def __enter__(self): - # We have no use for the "as ..." clause in the with - # statement for locks. - return None - - def __exit__(self, *args): - try: - self._lock.release() - finally: - self._lock = None # Crudely prevent reuse. class _ContextManagerMixin: - def __enter__(self): - raise RuntimeError( - '"yield from" should be used as context manager expression') - - def __exit__(self, *args): - # This must exist because __enter__ exists, even though that - # always raises; that's how the with-statement works. - pass - - @types.coroutine - def __iter__(self): - # This is not a coroutine. It is meant to enable the idiom: - # - # with (yield from lock): - # <block> - # - # as an alternative to: - # - # yield from lock.acquire() - # try: - # <block> - # finally: - # lock.release() - # Deprecated, use 'async with' statement: - # async with lock: - # <block> - warnings.warn("'with (yield from lock)' is deprecated " - "use 'async with lock' instead", - DeprecationWarning, stacklevel=2) - yield from self.acquire() - return _ContextManager(self) - - # The flag is needed for legacy asyncio.iscoroutine() - __iter__._is_coroutine = coroutines._is_coroutine - - async def __acquire_ctx(self): - await self.acquire() - return _ContextManager(self) - - def __await__(self): - warnings.warn("'with await lock' is deprecated " - "use 'async with lock' instead", - DeprecationWarning, stacklevel=2) - # To make "with await lock" work. - return self.__acquire_ctx().__await__() - async def __aenter__(self): await self.acquire() # We have no use for the "as ..." clause in the with diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index 9468e74..8c93fae 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -47,13 +47,7 @@ class LockTests(test_utils.TestCase): self.assertTrue(repr(lock).endswith('[unlocked]>')) self.assertTrue(RGX_REPR.match(repr(lock))) - with self.assertWarns(DeprecationWarning): - @asyncio.coroutine - def acquire_lock(): - with self.assertWarns(DeprecationWarning): - yield from lock - - self.loop.run_until_complete(acquire_lock()) + self.loop.run_until_complete(lock.acquire()) self.assertTrue(repr(lock).endswith('[locked]>')) self.assertTrue(RGX_REPR.match(repr(lock))) @@ -61,18 +55,16 @@ class LockTests(test_utils.TestCase): with self.assertWarns(DeprecationWarning): lock = asyncio.Lock(loop=self.loop) - @asyncio.coroutine def acquire_lock(): - with self.assertWarns(DeprecationWarning): - return (yield from lock) - - res = self.loop.run_until_complete(acquire_lock()) + return (yield from lock) - self.assertTrue(res) - self.assertTrue(lock.locked()) + with self.assertRaisesRegex( + TypeError, + "object is not iterable" + ): + self.loop.run_until_complete(acquire_lock()) - lock.release() self.assertFalse(lock.locked()) def test_lock_by_with_statement(self): @@ -90,13 +82,13 @@ class LockTests(test_utils.TestCase): def test(lock): yield from asyncio.sleep(0.01) self.assertFalse(lock.locked()) - with self.assertWarns(DeprecationWarning): - with (yield from lock) as _lock: - self.assertIs(_lock, None) - self.assertTrue(lock.locked()) - yield from asyncio.sleep(0.01) - self.assertTrue(lock.locked()) - self.assertFalse(lock.locked()) + with self.assertRaisesRegex( + TypeError, + "object is not iterable" + ): + with (yield from lock): + pass + self.assertFalse(lock.locked()) for primitive in primitives: loop.run_until_complete(test(primitive)) @@ -302,52 +294,16 @@ class LockTests(test_utils.TestCase): self.assertFalse(lock.locked()) def test_context_manager(self): - with self.assertWarns(DeprecationWarning): - lock = asyncio.Lock(loop=self.loop) + async def f(): + lock = asyncio.Lock() + self.assertFalse(lock.locked()) - @asyncio.coroutine - def acquire_lock(): - with self.assertWarns(DeprecationWarning): - return (yield from lock) + async with lock: + self.assertTrue(lock.locked()) - with self.loop.run_until_complete(acquire_lock()): - self.assertTrue(lock.locked()) + self.assertFalse(lock.locked()) - self.assertFalse(lock.locked()) - - def test_context_manager_cant_reuse(self): - with self.assertWarns(DeprecationWarning): - lock = asyncio.Lock(loop=self.loop) - - @asyncio.coroutine - def acquire_lock(): - with self.assertWarns(DeprecationWarning): - return (yield from lock) - - # This spells "yield from lock" outside a generator. - cm = self.loop.run_until_complete(acquire_lock()) - with cm: - self.assertTrue(lock.locked()) - - self.assertFalse(lock.locked()) - - with self.assertRaises(AttributeError): - with cm: - pass - - def test_context_manager_no_yield(self): - with self.assertWarns(DeprecationWarning): - lock = asyncio.Lock(loop=self.loop) - - try: - with lock: - self.fail('RuntimeError is not raised in with expression') - except RuntimeError as err: - self.assertEqual( - str(err), - '"yield from" should be used as context manager expression') - - self.assertFalse(lock.locked()) + self.loop.run_until_complete(f()) class EventTests(test_utils.TestCase): @@ -809,33 +765,14 @@ class ConditionTests(test_utils.TestCase): self.assertTrue(RGX_REPR.match(repr(cond))) def test_context_manager(self): - with self.assertWarns(DeprecationWarning): - cond = asyncio.Condition(loop=self.loop) - - with self.assertWarns(DeprecationWarning): - @asyncio.coroutine - def acquire_cond(): - with self.assertWarns(DeprecationWarning): - return (yield from cond) - - with self.loop.run_until_complete(acquire_cond()): - self.assertTrue(cond.locked()) - - self.assertFalse(cond.locked()) - - def test_context_manager_no_yield(self): - with self.assertWarns(DeprecationWarning): - cond = asyncio.Condition(loop=self.loop) - - try: - with cond: - self.fail('RuntimeError is not raised in with expression') - except RuntimeError as err: - self.assertEqual( - str(err), - '"yield from" should be used as context manager expression') + async def f(): + cond = asyncio.Condition() + self.assertFalse(cond.locked()) + async with cond: + self.assertTrue(cond.locked()) + self.assertFalse(cond.locked()) - self.assertFalse(cond.locked()) + self.loop.run_until_complete(f()) def test_explicit_lock(self): with self.assertWarns(DeprecationWarning): @@ -920,16 +857,14 @@ class SemaphoreTests(test_utils.TestCase): with self.assertWarns(DeprecationWarning): @asyncio.coroutine def acquire_lock(): - with self.assertWarns(DeprecationWarning): - return (yield from sem) + return (yield from sem) - res = self.loop.run_until_complete(acquire_lock()) - - self.assertTrue(res) - self.assertTrue(sem.locked()) - self.assertEqual(0, sem._value) + with self.assertRaisesRegex( + TypeError, + "'Semaphore' object is not iterable", + ): + self.loop.run_until_complete(acquire_lock()) - sem.release() self.assertFalse(sem.locked()) self.assertEqual(1, sem._value) @@ -1064,38 +999,6 @@ class SemaphoreTests(test_utils.TestCase): sem.release() self.assertFalse(sem.locked()) - def test_context_manager(self): - with self.assertWarns(DeprecationWarning): - sem = asyncio.Semaphore(2, loop=self.loop) - - @asyncio.coroutine - def acquire_lock(): - with self.assertWarns(DeprecationWarning): - return (yield from sem) - - with self.loop.run_until_complete(acquire_lock()): - self.assertFalse(sem.locked()) - self.assertEqual(1, sem._value) - - with self.loop.run_until_complete(acquire_lock()): - self.assertTrue(sem.locked()) - - self.assertEqual(2, sem._value) - - def test_context_manager_no_yield(self): - with self.assertWarns(DeprecationWarning): - sem = asyncio.Semaphore(2, loop=self.loop) - - try: - with sem: - self.fail('RuntimeError is not raised in with expression') - except RuntimeError as err: - self.assertEqual( - str(err), - '"yield from" should be used as context manager expression') - - self.assertEqual(2, sem._value) - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py index a1f27dd..c5e3a5c 100644 --- a/Lib/test/test_asyncio/test_pep492.py +++ b/Lib/test/test_asyncio/test_pep492.py @@ -77,13 +77,12 @@ class LockTests(BaseTest): async def test(lock): await asyncio.sleep(0.01) self.assertFalse(lock.locked()) - with self.assertWarns(DeprecationWarning): - with await lock as _lock: - self.assertIs(_lock, None) - self.assertTrue(lock.locked()) - await asyncio.sleep(0.01) - self.assertTrue(lock.locked()) - self.assertFalse(lock.locked()) + with self.assertRaisesRegex( + TypeError, + "can't be used in 'await' expression" + ): + with await lock: + pass for primitive in primitives: self.loop.run_until_complete(test(primitive)) |