[Python-checkins] cpython (3.5): A new version of typing.py from https://github.com/python/typing.

guido.van.rossum python-checkins at python.org
Tue Aug 23 14:06:49 EDT 2016


https://hg.python.org/cpython/rev/355fa8bd8d9d
changeset:   102867:355fa8bd8d9d
branch:      3.5
parent:      102860:e3466a556d81
user:        Guido van Rossum <guido at python.org>
date:        Tue Aug 23 11:01:50 2016 -0700
summary:
  A new version of typing.py from https://github.com/python/typing.

files:
  Lib/test/test_typing.py |  13 +++++-
  Lib/typing.py           |  68 ++++++++++++++++++----------
  Misc/NEWS               |   6 ++
  3 files changed, 61 insertions(+), 26 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
@@ -512,6 +512,10 @@
         self.assertEqual(get_type_hints(foo, globals(), locals()),
                          {'a': Callable[..., T]})
 
+    def test_ellipsis_in_generic(self):
+        # Shouldn't crash; see https://github.com/python/typing/issues/259
+        typing.List[Callable[..., str]]
+
 
 XK = TypeVar('XK', str, bytes)
 XV = TypeVar('XV')
@@ -852,7 +856,7 @@
 
     def test_covariance_sequence(self):
         # Check covariance for Sequence (which is just a generic class
-        # for this purpose, but using a covariant type variable).
+        # for this purpose, but using a type variable with covariant=True).
         self.assertIsSubclass(typing.Sequence[Manager],
                               typing.Sequence[Employee])
         self.assertNotIsSubclass(typing.Sequence[Employee],
@@ -1185,6 +1189,13 @@
         self.assertIsInstance([], typing.Container)
         self.assertNotIsInstance(42, typing.Container)
 
+    def test_collection(self):
+        if hasattr(typing, 'Collection'):
+            self.assertIsInstance(tuple(), typing.Collection)
+            self.assertIsInstance(frozenset(), typing.Collection)
+            self.assertIsSubclass(dict, typing.Collection)
+            self.assertNotIsInstance(42, typing.Collection)
+
     def test_abstractset(self):
         self.assertIsInstance(set(), typing.AbstractSet)
         self.assertNotIsInstance(42, typing.AbstractSet)
diff --git a/Lib/typing.py b/Lib/typing.py
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -57,6 +57,7 @@
     'DefaultDict',
     'List',
     'Set',
+    'FrozenSet',
     'NamedTuple',  # Not really a type.
     'Generator',
 
@@ -160,12 +161,6 @@
         return self
 
     def _eval_type(self, globalns, localns):
-        if not isinstance(localns, dict):
-            raise TypeError('ForwardRef localns must be a dict -- got %r' %
-                            (localns,))
-        if not isinstance(globalns, dict):
-            raise TypeError('ForwardRef globalns must be a dict -- got %r' %
-                            (globalns,))
         if not self.__forward_evaluated__:
             if globalns is None and localns is None:
                 globalns = localns = {}
@@ -388,9 +383,10 @@
     and issubclass(bytes, A) are true, and issubclass(int, A) is
     false.  (TODO: Why is this needed?  This may change.  See #136.)
 
-    Type variables may be marked covariant or contravariant by passing
-    covariant=True or contravariant=True.  See PEP 484 for more
-    details.  By default type variables are invariant.
+    Type variables defined with covariant=True or contravariant=True
+    can be used do declare covariant or contravariant generic types.
+    See PEP 484 for more details. By default generic types are invariant
+    in all type variables.
 
     Type variables can be introspected. e.g.:
 
@@ -405,7 +401,7 @@
                 covariant=False, contravariant=False):
         self = super().__new__(cls, name, (Final,), {}, _root=True)
         if covariant and contravariant:
-            raise ValueError("Bivariant type variables are not supported.")
+            raise ValueError("Bivariant types are not supported.")
         self.__covariant__ = bool(covariant)
         self.__contravariant__ = bool(contravariant)
         if constraints and bound is not None:
@@ -782,7 +778,7 @@
         return self
 
     def _get_type_vars(self, tvars):
-        if self.__args__:
+        if self.__args__ and self.__args__ is not Ellipsis:
             _get_type_vars(self.__args__, tvars)
 
     def _eval_type(self, globalns, localns):
@@ -1044,7 +1040,7 @@
         if cls is Any:
             return True
         if isinstance(cls, GenericMeta):
-            # For a class C(Generic[T]) where T is co-variant,
+            # For a covariant class C(Generic[T]),
             # C[X] is a subclass of C[Y] iff X is a subclass of Y.
             origin = self.__origin__
             if origin is not None and origin is cls.__origin__:
@@ -1434,31 +1430,53 @@
     __slots__ = ()
 
 
+if hasattr(collections_abc, 'Collection'):
+    class Collection(Sized, Iterable[T_co], Container[T_co],
+                     extra=collections_abc.Collection):
+        __slots__ = ()
+
+    __all__.append('Collection')
+
+
 # Callable was defined earlier.
 
-
-class AbstractSet(Sized, Iterable[T_co], Container[T_co],
-                  extra=collections_abc.Set):
-    pass
+if hasattr(collections_abc, 'Collection'):
+    class AbstractSet(Collection[T_co],
+                      extra=collections_abc.Set):
+        pass
+else:
+    class AbstractSet(Sized, Iterable[T_co], Container[T_co],
+                      extra=collections_abc.Set):
+        pass
 
 
 class MutableSet(AbstractSet[T], extra=collections_abc.MutableSet):
     pass
 
 
-# NOTE: Only the value type is covariant.
-class Mapping(Sized, Iterable[KT], Container[KT], Generic[KT, VT_co],
-              extra=collections_abc.Mapping):
-    pass
+# NOTE: It is only covariant in the value type.
+if hasattr(collections_abc, 'Collection'):
+    class Mapping(Collection[KT], Generic[KT, VT_co],
+                  extra=collections_abc.Mapping):
+        pass
+else:
+    class Mapping(Sized, Iterable[KT], Container[KT], Generic[KT, VT_co],
+                  extra=collections_abc.Mapping):
+        pass
 
 
 class MutableMapping(Mapping[KT, VT], extra=collections_abc.MutableMapping):
     pass
 
 if hasattr(collections_abc, 'Reversible'):
-    class Sequence(Sized, Reversible[T_co], Container[T_co],
-               extra=collections_abc.Sequence):
-        pass
+    if hasattr(collections_abc, 'Collection'):
+        class Sequence(Reversible[T_co], Collection[T_co],
+                   extra=collections_abc.Sequence):
+            pass
+    else:
+        class Sequence(Sized, Reversible[T_co], Container[T_co],
+                   extra=collections_abc.Sequence):
+            pass
 else:
     class Sequence(Sized, Iterable[T_co], Container[T_co],
                    extra=collections_abc.Sequence):
@@ -1583,11 +1601,11 @@
 
 
 # Internal type variable used for Type[].
-CT = TypeVar('CT', covariant=True, bound=type)
+CT_co = TypeVar('CT_co', covariant=True, bound=type)
 
 
 # This is not a real generic class.  Don't use outside annotations.
-class Type(type, Generic[CT], extra=type):
+class Type(type, Generic[CT_co], extra=type):
     """A special construct usable to annotate class objects.
 
     For example, suppose we have the following classes::
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -50,6 +50,12 @@
 Library
 -------
 
+- A new version of typing.py from https://github.com/python/typing:
+  - Collection (only for 3.6) (Issue #27598)
+  - Add FrozenSet to __all__ (upstream #261)
+  - fix crash in _get_type_vars() (upstream #259)
+  - Remove the dict constraint in ForwardRef._eval_type (upstream #252)
+
 - Issue #27539: Fix unnormalised ``Fraction.__pow__`` result in the case
   of negative exponent and negative base.
 

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


More information about the Python-checkins mailing list