[Python-checkins] cpython (merge 3.5 -> 3.6): Issue #29198: add AsyncGenerator (Jelle Zijlstra) (3.5->3.6)

guido.van.rossum python-checkins at python.org
Wed Jan 18 16:11:42 EST 2017


https://hg.python.org/cpython/rev/5b771c662c00
changeset:   106226:5b771c662c00
branch:      3.6
parent:      106222:2159f36ccd6b
parent:      106225:87e8139420ed
user:        Guido van Rossum <guido at python.org>
date:        Wed Jan 18 13:10:34 2017 -0800
summary:
  Issue #29198: add AsyncGenerator (Jelle Zijlstra) (3.5->3.6)

files:
  Lib/test/test_typing.py |  42 +++++++++++++++++++++++++++++
  Lib/typing.py           |  10 ++++++-
  2 files changed, 51 insertions(+), 1 deletions(-)


diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -1735,6 +1735,23 @@
         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 @@
         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
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -51,7 +51,8 @@
     # AsyncIterable,
     # Coroutine,
     # Collection,
-    # ContextManager
+    # ContextManager,
+    # AsyncGenerator,
 
     # Structural checks, a.k.a. protocols.
     'Reversible',
@@ -1900,6 +1901,13 @@
                             "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)

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list