Issue #29198: add AsyncGenerator (Jelle Zijlstra) (3.5->3.6)

This commit is contained in:
Guido van Rossum 2017-01-18 13:10:34 -08:00
commit 38a49bec7a
2 changed files with 51 additions and 1 deletions

View File

@ -1735,6 +1735,23 @@ class CollectionsAbcTests(BaseTestCase):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
typing.Generator[int, int, int]() 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): def test_subclassing(self):
class MMA(typing.MutableMapping): class MMA(typing.MutableMapping):
@ -1804,6 +1821,31 @@ class CollectionsAbcTests(BaseTestCase):
self.assertIsSubclass(G, collections.Iterable) self.assertIsSubclass(G, collections.Iterable)
self.assertNotIsSubclass(type(g), G) 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): def test_subclassing_subclasshook(self):
class Base(typing.Iterable): class Base(typing.Iterable):

View File

@ -51,7 +51,8 @@ __all__ = [
# AsyncIterable, # AsyncIterable,
# Coroutine, # Coroutine,
# Collection, # Collection,
# ContextManager # ContextManager,
# AsyncGenerator,
# Structural checks, a.k.a. protocols. # Structural checks, a.k.a. protocols.
'Reversible', 'Reversible',
@ -1900,6 +1901,13 @@ class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co],
"create a subclass instead") "create a subclass instead")
return _generic_new(_G_base, cls, *args, **kwds) 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[]. # Internal type variable used for Type[].
CT_co = TypeVar('CT_co', covariant=True, bound=type) CT_co = TypeVar('CT_co', covariant=True, bound=type)