-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
bpo-30241: implement contextlib.AbstractAsyncContextManager #1412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
b0f92e5
9fb1028
290802f
171c597
2a2cf36
aaa2590
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,8 @@ | |
from functools import wraps | ||
|
||
__all__ = ["asynccontextmanager", "contextmanager", "closing", | ||
"AbstractContextManager", "ContextDecorator", "ExitStack", | ||
"AbstractContextManager", "AbstractAsyncContextManager", | ||
"ContextDecorator", "ExitStack", | ||
"redirect_stdout", "redirect_stderr", "suppress"] | ||
|
||
|
||
|
@@ -31,6 +32,28 @@ def __subclasshook__(cls, C): | |
return NotImplemented | ||
|
||
|
||
class AbstractAsyncContextManager(abc.ABC): | ||
|
||
"""An abstract base class for asynchronous context managers.""" | ||
|
||
async def __aenter__(self): | ||
"""Return `self` upon entering the runtime context.""" | ||
return self | ||
|
||
@abc.abstractmethod | ||
async def __aexit__(self, exc_type, exc_value, traceback): | ||
"""Raise any exception triggered within the runtime context.""" | ||
return None | ||
|
||
@classmethod | ||
def __subclasshook__(cls, C): | ||
if cls is AbstractAsyncContextManager: | ||
if (any("__aenter__" in B.__dict__ for B in C.__mro__) and | ||
any("__aexit__" in B.__dict__ for B in C.__mro__)): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand you just copied this from above, but I think both should be updated to support the explicit "anti-registration" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe that should be a separate issue? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, a separate PR for 3.6 is needed. But I think it makes sense to already fix the async version here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Filed http://bugs.python.org/issue30266 to track that. |
||
return True | ||
return NotImplemented | ||
|
||
|
||
class ContextDecorator(object): | ||
"A base class or mixin that enables context managers to work as decorators." | ||
|
||
|
@@ -137,7 +160,8 @@ def __exit__(self, type, value, traceback): | |
raise RuntimeError("generator didn't stop after throw()") | ||
|
||
|
||
class _AsyncGeneratorContextManager(_GeneratorContextManagerBase): | ||
class _AsyncGeneratorContextManager(_GeneratorContextManagerBase, | ||
AbstractAsyncContextManager): | ||
"""Helper for @asynccontextmanager.""" | ||
|
||
async def __aenter__(self): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we could just copy the paragraph from
AbstractContextManager
doc. "similar to" isn't easy to read here.