summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_typing.py42
-rw-r--r--Lib/typing.py10
2 files changed, 51 insertions, 1 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 44712b699b..9ab42a3f6e 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -1735,6 +1735,23 @@ class CollectionsAbcTests(BaseTestCase):
with self.assertRaises(TypeError):
typing.Generator[int, int, int]()
+ @skipUnless(PY36, 'Python 3.6 required')
+ def test_async_generator(self):
+ ns = {}
+ exec("async def f():\n"
+ " yield 42\n", globals(), ns)
+ g = ns['f']()
+ self.assertIsSubclass(type(g), typing.AsyncGenerator)
+
+ @skipUnless(PY36, 'Python 3.6 required')
+ def test_no_async_generator_instantiation(self):
+ with self.assertRaises(TypeError):
+ typing.AsyncGenerator()
+ with self.assertRaises(TypeError):
+ typing.AsyncGenerator[T, T]()
+ with self.assertRaises(TypeError):
+ typing.AsyncGenerator[int, int]()
+
def test_subclassing(self):
class MMA(typing.MutableMapping):
@@ -1804,6 +1821,31 @@ class CollectionsAbcTests(BaseTestCase):
self.assertIsSubclass(G, collections.Iterable)
self.assertNotIsSubclass(type(g), G)
+ @skipUnless(PY36, 'Python 3.6 required')
+ def test_subclassing_async_generator(self):
+ class G(typing.AsyncGenerator[int, int]):
+ def asend(self, value):
+ pass
+ def athrow(self, typ, val=None, tb=None):
+ pass
+
+ ns = {}
+ exec('async def g(): yield 0', globals(), ns)
+ g = ns['g']
+ self.assertIsSubclass(G, typing.AsyncGenerator)
+ self.assertIsSubclass(G, typing.AsyncIterable)
+ self.assertIsSubclass(G, collections.AsyncGenerator)
+ self.assertIsSubclass(G, collections.AsyncIterable)
+ self.assertNotIsSubclass(type(g), G)
+
+ instance = G()
+ self.assertIsInstance(instance, typing.AsyncGenerator)
+ self.assertIsInstance(instance, typing.AsyncIterable)
+ self.assertIsInstance(instance, collections.AsyncGenerator)
+ self.assertIsInstance(instance, collections.AsyncIterable)
+ self.assertNotIsInstance(type(g), G)
+ self.assertNotIsInstance(g, G)
+
def test_subclassing_subclasshook(self):
class Base(typing.Iterable):
diff --git a/Lib/typing.py b/Lib/typing.py
index 0aeb089d5d..00ef440101 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -51,7 +51,8 @@ __all__ = [
# AsyncIterable,
# Coroutine,
# Collection,
- # ContextManager
+ # ContextManager,
+ # AsyncGenerator,
# Structural checks, a.k.a. protocols.
'Reversible',
@@ -1900,6 +1901,13 @@ class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co],
"create a subclass instead")
return _generic_new(_G_base, cls, *args, **kwds)
+if hasattr(collections_abc, 'AsyncGenerator'):
+ class AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra],
+ extra=collections_abc.AsyncGenerator):
+ __slots__ = ()
+
+ __all__.append('AsyncGenerator')
+
# Internal type variable used for Type[].
CT_co = TypeVar('CT_co', covariant=True, bound=type)