diff options
author | Guido van Rossum <guido@python.org> | 2016-08-23 18:01:50 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2016-08-23 18:01:50 (GMT) |
commit | efa798d1ba08687ff68f114e905b58686dc2e5d5 (patch) | |
tree | c39e64db5c8419b4b5ed13bddf20d37c11f8bc14 /Lib | |
parent | 83f5a3846cf67e226a13f103e0b9306e8f920f2e (diff) | |
download | cpython-efa798d1ba08687ff68f114e905b58686dc2e5d5.zip cpython-efa798d1ba08687ff68f114e905b58686dc2e5d5.tar.gz cpython-efa798d1ba08687ff68f114e905b58686dc2e5d5.tar.bz2 |
A new version of typing.py from https://github.com/python/typing.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_typing.py | 13 | ||||
-rw-r--r-- | Lib/typing.py | 68 |
2 files changed, 55 insertions, 26 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index a7f8dd5..72afe67 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -512,6 +512,10 @@ class CallableTests(BaseTestCase): 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 @@ class VarianceTests(BaseTestCase): 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 @@ class CollectionsAbcTests(BaseTestCase): 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 index 4cac66c..5573a1f 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -57,6 +57,7 @@ __all__ = [ 'DefaultDict', 'List', 'Set', + 'FrozenSet', 'NamedTuple', # Not really a type. 'Generator', @@ -160,12 +161,6 @@ class _ForwardRef(TypingMeta): 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 @@ class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True): 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 @@ class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True): 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 @@ class CallableMeta(TypingMeta): 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 @@ class GenericMeta(TypingMeta, abc.ABCMeta): 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 @@ class Container(Generic[T_co], extra=collections_abc.Container): __slots__ = () -# Callable was defined earlier. +if hasattr(collections_abc, 'Collection'): + class Collection(Sized, Iterable[T_co], Container[T_co], + extra=collections_abc.Collection): + __slots__ = () + __all__.append('Collection') -class AbstractSet(Sized, Iterable[T_co], Container[T_co], - extra=collections_abc.Set): - pass + +# Callable was defined earlier. + +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 @@ class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co], # 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:: |