[Python-checkins] cpython (merge 3.5 -> 3.6): Issue #28556: updates to typing.py (add Coroutine, prohibit Generic[T]())

guido.van.rossum python-checkins at python.org
Sat Oct 29 19:06:10 EDT 2016


https://hg.python.org/cpython/rev/2c2fec17247d
changeset:   104804:2c2fec17247d
branch:      3.6
parent:      104801:465b345559ea
parent:      104803:0201a87d773d
user:        Guido van Rossum <guido at python.org>
date:        Sat Oct 29 16:05:27 2016 -0700
summary:
  Issue #28556: updates to typing.py (add Coroutine, prohibit Generic[T]()) (3.5->3.6)

files:
  Lib/test/test_typing.py |  23 ++++++++++++++++++++-
  Lib/typing.py           |  31 +++++++++++++++++++++-------
  2 files changed, 45 insertions(+), 9 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
@@ -517,6 +517,9 @@
             Y[str, str]
 
     def test_generic_errors(self):
+        T = TypeVar('T')
+        with self.assertRaises(TypeError):
+            Generic[T]()
         with self.assertRaises(TypeError):
             isinstance([], List[int])
         with self.assertRaises(TypeError):
@@ -1255,7 +1258,7 @@
 ASYNCIO_TESTS = """
 import asyncio
 
-T_a = TypeVar('T')
+T_a = TypeVar('T_a')
 
 class AwaitableWrapper(typing.Awaitable[T_a]):
 
@@ -1404,6 +1407,24 @@
         g.send(None)  # Run foo() till completion, to avoid warning.
 
     @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required')
+    def test_coroutine(self):
+        ns = {}
+        exec(
+            "async def foo():\n"
+            "    return\n",
+            globals(), ns)
+        foo = ns['foo']
+        g = foo()
+        self.assertIsInstance(g, typing.Coroutine)
+        with self.assertRaises(TypeError):
+            isinstance(g, typing.Coroutine[int])
+        self.assertNotIsInstance(foo, typing.Coroutine)
+        try:
+            g.send(None)
+        except StopIteration:
+            pass
+
+    @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required')
     def test_async_iterable(self):
         base_it = range(10)  # type: Iterator[int]
         it = AsyncIteratorWrapper(base_it)
diff --git a/Lib/typing.py b/Lib/typing.py
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -29,9 +29,6 @@
 
     # ABCs (from collections.abc).
     'AbstractSet',  # collections.abc.Set.
-    'Awaitable',
-    'AsyncIterator',
-    'AsyncIterable',
     'ByteString',
     'Container',
     'Hashable',
@@ -47,6 +44,14 @@
     'Sequence',
     'Sized',
     'ValuesView',
+    # The following are added depending on presence
+    # of their non-generic counterparts in stdlib:
+    # Awaitable,
+    # AsyncIterator,
+    # AsyncIterable,
+    # Coroutine,
+    # Collection,
+    # ContextManager
 
     # Structural checks, a.k.a. protocols.
     'Reversible',
@@ -1104,6 +1109,9 @@
     __slots__ = ()
 
     def __new__(cls, *args, **kwds):
+        if _geqv(cls, Generic):
+            raise TypeError("Type Generic cannot be instantiated; "
+                            "it can be used only as a base class")
         return _generic_new(cls.__next_in_mro__, cls, *args, **kwds)
 
 
@@ -1639,8 +1647,16 @@
 if hasattr(collections_abc, 'Awaitable'):
     class Awaitable(Generic[T_co], extra=collections_abc.Awaitable):
         __slots__ = ()
-else:
-    Awaitable = None
+
+    __all__.append('Awaitable')
+
+
+if hasattr(collections_abc, 'Coroutine'):
+    class Coroutine(Awaitable[V_co], Generic[T_co, T_contra, V_co],
+                    extra=collections_abc.Coroutine):
+        __slots__ = ()
+
+    __all__.append('Coroutine')
 
 
 if hasattr(collections_abc, 'AsyncIterable'):
@@ -1652,9 +1668,8 @@
                         extra=collections_abc.AsyncIterator):
         __slots__ = ()
 
-else:
-    AsyncIterable = None
-    AsyncIterator = None
+    __all__.append('AsyncIterable')
+    __all__.append('AsyncIterator')
 
 
 class Iterable(Generic[T_co], extra=collections_abc.Iterable):

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


More information about the Python-checkins mailing list