Skip to content

Commit 04b3013

Browse files
committed
add AsyncGenerator
1 parent 60c8fc7 commit 04b3013

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

src/test_typing.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,7 @@ def blah():
13201320

13211321

13221322
ASYNCIO = sys.version_info[:2] >= (3, 5)
1323+
ASYNC_GENERATOR = sys.version_info[:2] >= (3, 6)
13231324

13241325
ASYNCIO_TESTS = """
13251326
import asyncio
@@ -1696,6 +1697,23 @@ def test_no_generator_instantiation(self):
16961697
with self.assertRaises(TypeError):
16971698
typing.Generator[int, int, int]()
16981699

1700+
@skipUnless(PY36, 'Python 3.6 required')
1701+
def test_async_generator(self):
1702+
ns = {}
1703+
exec("async def f():\n"
1704+
" yield 42\n", globals(), ns)
1705+
g = ns['f']()
1706+
self.assertIsSubclass(type(g), typing.AsyncGenerator)
1707+
1708+
@skipUnless(PY36, 'Python 3.6 required')
1709+
def test_no_async_generator_instantiation(self):
1710+
with self.assertRaises(TypeError):
1711+
typing.AsyncGenerator()
1712+
with self.assertRaises(TypeError):
1713+
typing.AsyncGenerator[T, T]()
1714+
with self.assertRaises(TypeError):
1715+
typing.AsyncGenerator[int, int]()
1716+
16991717
def test_subclassing(self):
17001718

17011719
class MMA(typing.MutableMapping):
@@ -1765,6 +1783,18 @@ def g(): yield 0
17651783
self.assertIsSubclass(G, collections.Iterable)
17661784
self.assertNotIsSubclass(type(g), G)
17671785

1786+
@skipUnless(PY36, 'Python 3.6 required')
1787+
def test_subclassing_async_generator(self):
1788+
class G(typing.AsyncGenerator[int, int]): ...
1789+
ns = {}
1790+
exec('async def g(): yield 0', globals(), ns)
1791+
g = ns['g']
1792+
self.assertIsSubclass(G, typing.AsyncGenerator)
1793+
self.assertIsSubclass(G, typing.AsyncIterable)
1794+
self.assertIsSubclass(G, collections.AsyncGenerator)
1795+
self.assertIsSubclass(G, collections.AsyncIterable)
1796+
self.assertNotIsSubclass(type(g), G)
1797+
17681798
def test_subclassing_subclasshook(self):
17691799

17701800
class Base(typing.Iterable):

src/typing.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
# AsyncIterable,
5050
# Coroutine,
5151
# Collection,
52-
# ContextManager
52+
# ContextManager,
53+
# AsyncGenerator,
5354

5455
# Structural checks, a.k.a. protocols.
5556
'Reversible',
@@ -1859,6 +1860,21 @@ def __new__(cls, *args, **kwds):
18591860
"create a subclass instead")
18601861
return _generic_new(_G_base, cls, *args, **kwds)
18611862

1863+
if hasattr(collections_abc, 'AsyncGenerator'):
1864+
_AG_base = collections_abc.AsyncGenerator
1865+
1866+
class AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra],
1867+
extra=_AG_base):
1868+
__slots__ = ()
1869+
1870+
def __new__(cls, *args, **kwds):
1871+
if _geqv(cls, AsyncGenerator):
1872+
raise TypeError("Type AsyncGenerator cannot be instantiated; "
1873+
"create a subclass instead")
1874+
return _generic_new(_AG_base, cls, *args, **kwds)
1875+
1876+
__all__.append('AsyncGenerator')
1877+
18621878

18631879
# Internal type variable used for Type[].
18641880
CT_co = TypeVar('CT_co', covariant=True, bound=type)

0 commit comments

Comments
 (0)