10000 Add AsyncContextManager generic class by ilevkivskyi · Pull Request #438 · python/typing · GitHub
[go: up one dir, main page]

Skip to content

Add AsyncContextManager generic class #438

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

Merged
merged 7 commits into from
Jun 9, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add AsyncContextManager
  • Loading branch information
ilevkivskyi committed Jun 9, 2017
commit 2f00d3e32af8b557040e44c46dee447bb3babee7
21 changes: 20 additions & 1 deletion src/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1552,6 +1552,12 @@ def __anext__(self) -> T_a:
return data
else:
raise StopAsyncIteration

class ACM:
async def __aenter__(self):
return self
async def __aexit__(self, etype, eval, tb):
return None
"""

if ASYNCIO:
Expand All @@ -1562,7 +1568,7 @@ def __anext__(self) -> T_a:
else:
# fake names for the sake of static analysis
asyncio = None
AwaitableWrapper = AsyncIteratorWrapper = object
AwaitableWrapper = AsyncIteratorWrapper = ACM = object

PY36 = sys.version_info[:2] >= (3, 6)

Expand Down Expand Up @@ -2165,6 +2171,19 @@ def manager():
self.assertIsInstance(cm, typing.ContextManager)
self.assertNotIsInstance(42, typing.ContextManager)

@skipUnless(ASYNCIO, 'Python 3.5 required')
def test_async_contextmanager(self):
class NotACM:
pass
self.assertIsInstance(ACM(), typing.AsyncContextManager)
self.assertNotIsInstance(NotACM(), typing.AsyncContextManager)
@contextlib.contextmanager
def manager():
yield 42

cm = manager()
self.assertNotIsInstance(cm, typing.AsyncContextManager)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a test that also serves as an example of how to use AsyncContextManager (presumably in async with ...?



class TypeTests(BaseTestCase):

Expand Down
29 changes: 29 additions & 0 deletions src/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
# Coroutine,
# Collection,
# AsyncGenerator,
# AsyncContextManager

# Structural checks, a.k.a. protocols.
'Reversible',
Expand Down Expand Up @@ -1974,6 +1975,34 @@ def __subclasshook__(cls, C):
return NotImplemented


if hasattr(contextlib, 'AbstractAsyncContextManager'):
class AsyncContextManager(Generic[T_co], extra=contextlib.AbstractAsyncContextManager):
__slots__ = ()

__all__.append('AsyncContextManager')
elif sys.version_info[:2] >= (3, 5):
exec("""
class AsyncContextManager(Generic[T_co]):
__slots__ = ()

async def __aenter__(self):
return self

@abc.abstractmethod
async def __aexit__(self, exc_type, exc_value, traceback):
return None

@classmethod
def __subclasshook__(cls, C):
if cls is AsyncContextManager:
return _collections_abc._check_methods(C, "__aenter__",
"__aexit__")
return NotImplemented

__all__.append('AsyncContextManager')
""")


class Dict(dict, MutableMapping[KT, VT], extra=dict):

__slots__ = ()
Expand Down
0