mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
bpo-40816 Add AsyncContextDecorator class (GH-20516)
Co-authored-by: Yury Selivanov <yury@edgedb.com>
This commit is contained in:
parent
048a35659a
commit
178695b7ae
4 changed files with 114 additions and 1 deletions
|
@ -80,6 +80,22 @@ class ContextDecorator(object):
|
|||
return inner
|
||||
|
||||
|
||||
class AsyncContextDecorator(object):
|
||||
"A base class or mixin that enables async context managers to work as decorators."
|
||||
|
||||
def _recreate_cm(self):
|
||||
"""Return a recreated instance of self.
|
||||
"""
|
||||
return self
|
||||
|
||||
def __call__(self, func):
|
||||
@wraps(func)
|
||||
async def inner(*args, **kwds):
|
||||
async with self._recreate_cm():
|
||||
return await func(*args, **kwds)
|
||||
return inner
|
||||
|
||||
|
||||
class _GeneratorContextManagerBase:
|
||||
"""Shared functionality for @contextmanager and @asynccontextmanager."""
|
||||
|
||||
|
@ -167,9 +183,16 @@ class _GeneratorContextManager(_GeneratorContextManagerBase,
|
|||
|
||||
|
||||
class _AsyncGeneratorContextManager(_GeneratorContextManagerBase,
|
||||
AbstractAsyncContextManager):
|
||||
AbstractAsyncContextManager,
|
||||
AsyncContextDecorator):
|
||||
"""Helper for @asynccontextmanager."""
|
||||
|
||||
def _recreate_cm(self):
|
||||
# _AGCM instances are one-shot context managers, so the
|
||||
# ACM must be recreated each time a decorated function is
|
||||
# called
|
||||
return self.__class__(self.func, self.args, self.kwds)
|
||||
|
||||
async def __aenter__(self):
|
||||
try:
|
||||
return await self.gen.__anext__()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue