mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Issue #29198: add AsyncGenerator (Jelle Zijlstra) (3.6->3.7)
This commit is contained in:
		
						commit
						c75340a8fd
					
				
					 2 changed files with 51 additions and 1 deletions
				
			
		| 
						 | 
					@ -1735,6 +1735,23 @@ def test_no_generator_instantiation(self):
 | 
				
			||||||
        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 @@ def g(): yield 0
 | 
				
			||||||
        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):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,8 @@
 | 
				
			||||||
    # 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 @@ def __new__(cls, *args, **kwds):
 | 
				
			||||||
                            "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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue