diff options
author | Guido van Rossum <guido@python.org> | 2017-01-18 21:10:36 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2017-01-18 21:10:36 (GMT) |
commit | c75340a8fda52007855ca143513d2252c8cb1574 (patch) | |
tree | a42b156e15813c1bc21576c819191a6add6ef555 /Lib | |
parent | fa025f112f7467b124f7ac4be5e9c7bb3cc05ad8 (diff) | |
parent | 38a49bec7a2522773f907bcee76d5b1305ef2260 (diff) | |
download | cpython-c75340a8fda52007855ca143513d2252c8cb1574.zip cpython-c75340a8fda52007855ca143513d2252c8cb1574.tar.gz cpython-c75340a8fda52007855ca143513d2252c8cb1574.tar.bz2 |
Issue #29198: add AsyncGenerator (Jelle Zijlstra) (3.6->3.7)
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_typing.py | 42 | ||||
-rw-r--r-- | 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 index 44712b6..9ab42a3 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 0aeb089..00ef440 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) |