summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_typing.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_typing.py')
-rw-r--r--Lib/test/test_typing.py337
1 files changed, 114 insertions, 223 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 3b99060..6543005 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -9,7 +9,7 @@ from typing import Any
from typing import TypeVar, AnyStr
from typing import T, KT, VT # Not in __all__.
from typing import Union, Optional
-from typing import Tuple, List
+from typing import Tuple, List, MutableMapping
from typing import Callable
from typing import Generic, ClassVar
from typing import cast
@@ -21,6 +21,10 @@ from typing import NamedTuple
from typing import IO, TextIO, BinaryIO
from typing import Pattern, Match
import typing
+try:
+ import collections.abc as collections_abc
+except ImportError:
+ import collections as collections_abc # Fallback for PY3.2.
class BaseTestCase(TestCase):
@@ -62,18 +66,11 @@ class AnyTests(BaseTestCase):
with self.assertRaises(TypeError):
isinstance(42, Any)
- def test_any_subclass(self):
- self.assertTrue(issubclass(Employee, Any))
- self.assertTrue(issubclass(int, Any))
- self.assertTrue(issubclass(type(None), Any))
- self.assertTrue(issubclass(object, Any))
-
- def test_others_any(self):
- self.assertFalse(issubclass(Any, Employee))
- self.assertFalse(issubclass(Any, int))
- self.assertFalse(issubclass(Any, type(None)))
- # However, Any is a subclass of object (this can't be helped).
- self.assertTrue(issubclass(Any, object))
+ def test_any_subclass_type_error(self):
+ with self.assertRaises(TypeError):
+ issubclass(Employee, Any)
+ with self.assertRaises(TypeError):
+ issubclass(Any, Employee)
def test_repr(self):
self.assertEqual(repr(Any), 'typing.Any')
@@ -88,32 +85,21 @@ class AnyTests(BaseTestCase):
with self.assertRaises(TypeError):
class A(Any):
pass
+ with self.assertRaises(TypeError):
+ class A(type(Any)):
+ pass
def test_cannot_instantiate(self):
with self.assertRaises(TypeError):
Any()
+ with self.assertRaises(TypeError):
+ type(Any)()
def test_cannot_subscript(self):
with self.assertRaises(TypeError):
Any[int]
- def test_any_is_subclass(self):
- # Any should be considered a subclass of everything.
- self.assertIsSubclass(Any, Any)
- self.assertIsSubclass(Any, typing.List)
- self.assertIsSubclass(Any, typing.List[int])
- self.assertIsSubclass(Any, typing.List[T])
- self.assertIsSubclass(Any, typing.Mapping)
- self.assertIsSubclass(Any, typing.Mapping[str, int])
- self.assertIsSubclass(Any, typing.Mapping[KT, VT])
- self.assertIsSubclass(Any, Generic)
- self.assertIsSubclass(Any, Generic[T])
- self.assertIsSubclass(Any, Generic[KT, VT])
- self.assertIsSubclass(Any, AnyStr)
- self.assertIsSubclass(Any, Union)
- self.assertIsSubclass(Any, Union[int, str])
- self.assertIsSubclass(Any, typing.Match)
- self.assertIsSubclass(Any, typing.Match[str])
+ def test_any_works_with_alias(self):
# These expressions must simply not fail.
typing.Match[Any]
typing.Pattern[Any]
@@ -124,13 +110,8 @@ class TypeVarTests(BaseTestCase):
def test_basic_plain(self):
T = TypeVar('T')
- # Every class is a subclass of T.
- self.assertIsSubclass(int, T)
- self.assertIsSubclass(str, T)
# T equals itself.
self.assertEqual(T, T)
- # T is a subclass of itself.
- self.assertIsSubclass(T, T)
# T is an instance of TypeVar
self.assertIsInstance(T, TypeVar)
@@ -139,16 +120,12 @@ class TypeVarTests(BaseTestCase):
with self.assertRaises(TypeError):
isinstance(42, T)
- def test_basic_constrained(self):
- A = TypeVar('A', str, bytes)
- # Only str and bytes are subclasses of A.
- self.assertIsSubclass(str, A)
- self.assertIsSubclass(bytes, A)
- self.assertNotIsSubclass(int, A)
- # A equals itself.
- self.assertEqual(A, A)
- # A is a subclass of itself.
- self.assertIsSubclass(A, A)
+ def test_typevar_subclass_type_error(self):
+ T = TypeVar('T')
+ with self.assertRaises(TypeError):
+ issubclass(int, T)
+ with self.assertRaises(TypeError):
+ issubclass(T, int)
def test_constrained_error(self):
with self.assertRaises(TypeError):
@@ -185,19 +162,6 @@ class TypeVarTests(BaseTestCase):
self.assertNotEqual(TypeVar('T'), TypeVar('T'))
self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str))
- def test_subclass_as_unions(self):
- # None of these are true -- each type var is its own world.
- self.assertFalse(issubclass(TypeVar('T', int, str),
- TypeVar('T', int, str)))
- self.assertFalse(issubclass(TypeVar('T', int, float),
- TypeVar('T', int, float, str)))
- self.assertFalse(issubclass(TypeVar('T', int, str),
- TypeVar('T', str, int)))
- A = TypeVar('A', int, str)
- B = TypeVar('B', int, str, float)
- self.assertFalse(issubclass(A, B))
- self.assertFalse(issubclass(B, A))
-
def test_cannot_subclass_vars(self):
with self.assertRaises(TypeError):
class V(TypeVar('T')):
@@ -212,12 +176,6 @@ class TypeVarTests(BaseTestCase):
with self.assertRaises(TypeError):
TypeVar('A')()
- def test_bound(self):
- X = TypeVar('X', bound=Employee)
- self.assertIsSubclass(Employee, X)
- self.assertIsSubclass(Manager, X)
- self.assertNotIsSubclass(int, X)
-
def test_bound_errors(self):
with self.assertRaises(TypeError):
TypeVar('X', bound=42)
@@ -230,8 +188,16 @@ class UnionTests(BaseTestCase):
def test_basics(self):
u = Union[int, float]
self.assertNotEqual(u, Union)
- self.assertTrue(issubclass(int, u))
- self.assertTrue(issubclass(float, u))
+
+ def test_subclass_error(self):
+ with self.assertRaises(TypeError):
+ issubclass(int, Union)
+ with self.assertRaises(TypeError):
+ issubclass(Union, int)
+ with self.assertRaises(TypeError):
+ issubclass(int, Union[int, str])
+ with self.assertRaises(TypeError):
+ issubclass(Union[int, str], int)
def test_union_any(self):
u = Union[Any]
@@ -260,18 +226,6 @@ class UnionTests(BaseTestCase):
u2 = Union[float, int]
self.assertEqual(u1, u2)
- def test_subclass(self):
- u = Union[int, Employee]
- self.assertTrue(issubclass(Manager, u))
-
- def test_self_subclass(self):
- self.assertTrue(issubclass(Union[KT, VT], Union))
- self.assertFalse(issubclass(Union, Union[KT, VT]))
-
- def test_multiple_inheritance(self):
- u = Union[int, Employee]
- self.assertTrue(issubclass(ManagingFounder, u))
-
def test_single_class_disappears(self):
t = Union[Employee]
self.assertIs(t, Employee)
@@ -284,13 +238,6 @@ class UnionTests(BaseTestCase):
u = Union[Employee, Manager]
self.assertIs(u, Employee)
- def test_weird_subclasses(self):
- u = Union[Employee, int, float]
- v = Union[int, float]
- self.assertTrue(issubclass(v, u))
- w = Union[int, Manager]
- self.assertTrue(issubclass(w, u))
-
def test_union_union(self):
u = Union[int, float]
v = Union[u, Employee]
@@ -308,15 +255,27 @@ class UnionTests(BaseTestCase):
class C(Union):
pass
with self.assertRaises(TypeError):
+ class C(type(Union)):
+ pass
+ with self.assertRaises(TypeError):
class C(Union[int, str]):
pass
def test_cannot_instantiate(self):
with self.assertRaises(TypeError):
Union()
+ with self.assertRaises(TypeError):
+ type(Union)()
u = Union[int, float]
with self.assertRaises(TypeError):
u()
+ with self.assertRaises(TypeError):
+ type(u)()
+
+ def test_union_generalization(self):
+ self.assertFalse(Union[str, typing.Iterable[int]] == str)
+ self.assertFalse(Union[str, typing.Iterable[int]] == typing.Iterable[int])
+ self.assertTrue(Union[str, typing.Iterable] == typing.Iterable)
def test_optional(self):
o = Optional[int]
@@ -327,10 +286,6 @@ class UnionTests(BaseTestCase):
with self.assertRaises(TypeError):
Union[()]
- def test_issubclass_union(self):
- self.assertIsSubclass(Union[int, str], Union)
- self.assertNotIsSubclass(int, Union)
-
def test_union_instance_type_error(self):
with self.assertRaises(TypeError):
isinstance(42, Union[int, str])
@@ -355,43 +310,19 @@ class UnionTests(BaseTestCase):
Union[Elem, str] # Nor should this
-class TypeVarUnionTests(BaseTestCase):
-
- def test_simpler(self):
- A = TypeVar('A', int, str, float)
- B = TypeVar('B', int, str)
- self.assertIsSubclass(A, A)
- self.assertIsSubclass(B, B)
- self.assertNotIsSubclass(B, A)
- self.assertIsSubclass(A, Union[int, str, float])
- self.assertNotIsSubclass(Union[int, str, float], A)
- self.assertNotIsSubclass(Union[int, str], B)
- self.assertIsSubclass(B, Union[int, str])
- self.assertNotIsSubclass(A, B)
- self.assertNotIsSubclass(Union[int, str, float], B)
- self.assertNotIsSubclass(A, Union[int, str])
-
- def test_var_union_subclass(self):
- self.assertTrue(issubclass(T, Union[int, T]))
- self.assertTrue(issubclass(KT, Union[KT, VT]))
-
- def test_var_union(self):
- TU = TypeVar('TU', Union[int, float], None)
- self.assertIsSubclass(int, TU)
- self.assertIsSubclass(float, TU)
-
-
class TupleTests(BaseTestCase):
def test_basics(self):
- self.assertTrue(issubclass(Tuple[int, str], Tuple))
- self.assertTrue(issubclass(Tuple[int, str], Tuple[int, str]))
- self.assertFalse(issubclass(int, Tuple))
- self.assertFalse(issubclass(Tuple[float, str], Tuple[int, str]))
- self.assertFalse(issubclass(Tuple[int, str, int], Tuple[int, str]))
- self.assertFalse(issubclass(Tuple[int, str], Tuple[int, str, int]))
+ with self.assertRaises(TypeError):
+ issubclass(Tuple[int, str], Tuple)
+ with self.assertRaises(TypeError):
+ issubclass(Tuple, Tuple[int, str])
+ with self.assertRaises(TypeError):
+ issubclass(tuple, Tuple[int, str])
+
+ class TP(tuple): ...
self.assertTrue(issubclass(tuple, Tuple))
- self.assertFalse(issubclass(Tuple, tuple)) # Can't have it both ways.
+ self.assertTrue(issubclass(TP, Tuple))
def test_equality(self):
self.assertEqual(Tuple[int], Tuple[int])
@@ -407,21 +338,7 @@ class TupleTests(BaseTestCase):
def test_tuple_instance_type_error(self):
with self.assertRaises(TypeError):
isinstance((0, 0), Tuple[int, int])
- with self.assertRaises(TypeError):
- isinstance((0, 0), Tuple)
-
- def test_tuple_ellipsis_subclass(self):
-
- class B:
- pass
-
- class C(B):
- pass
-
- self.assertNotIsSubclass(Tuple[B], Tuple[B, ...])
- self.assertIsSubclass(Tuple[C, ...], Tuple[B, ...])
- self.assertNotIsSubclass(Tuple[C, ...], Tuple[B])
- self.assertNotIsSubclass(Tuple[C], Tuple[B, ...])
+ self.assertIsInstance((0, 0), Tuple)
def test_repr(self):
self.assertEqual(repr(Tuple), 'typing.Tuple')
@@ -439,17 +356,9 @@ class TupleTests(BaseTestCase):
class CallableTests(BaseTestCase):
def test_self_subclass(self):
- self.assertTrue(issubclass(Callable[[int], int], Callable))
- self.assertFalse(issubclass(Callable, Callable[[int], int]))
- self.assertTrue(issubclass(Callable[[int], int], Callable[[int], int]))
- self.assertFalse(issubclass(Callable[[Employee], int],
- Callable[[Manager], int]))
- self.assertFalse(issubclass(Callable[[Manager], int],
- Callable[[Employee], int]))
- self.assertFalse(issubclass(Callable[[int], Employee],
- Callable[[int], Manager]))
- self.assertFalse(issubclass(Callable[[int], Manager],
- Callable[[int], Employee]))
+ with self.assertRaises(TypeError):
+ self.assertTrue(issubclass(type(lambda x: x), Callable[[int], int]))
+ self.assertTrue(issubclass(type(lambda x: x), Callable))
def test_eq_hash(self):
self.assertEqual(Callable[[int], int], Callable[[int], int])
@@ -468,15 +377,24 @@ class CallableTests(BaseTestCase):
with self.assertRaises(TypeError):
+ class C(type(Callable)):
+ pass
+
+ with self.assertRaises(TypeError):
+
class C(Callable[[int], int]):
pass
def test_cannot_instantiate(self):
with self.assertRaises(TypeError):
Callable()
+ with self.assertRaises(TypeError):
+ type(Callable)()
c = Callable[[int], str]
with self.assertRaises(TypeError):
c()
+ with self.assertRaises(TypeError):
+ type(c)()
def test_callable_instance_works(self):
def f():
@@ -616,6 +534,12 @@ class GenericTests(BaseTestCase):
with self.assertRaises(TypeError):
Y[str, str]
+ def test_generic_errors(self):
+ with self.assertRaises(TypeError):
+ isinstance([], List[int])
+ with self.assertRaises(TypeError):
+ issubclass(list, List[int])
+
def test_init(self):
T = TypeVar('T')
S = TypeVar('S')
@@ -671,6 +595,42 @@ class GenericTests(BaseTestCase):
c.bar = 'abc'
self.assertEqual(c.__dict__, {'bar': 'abc'})
+ def test_false_subclasses(self):
+ class MyMapping(MutableMapping[str, str]): pass
+ self.assertNotIsInstance({}, MyMapping)
+ self.assertNotIsSubclass(dict, MyMapping)
+
+ def test_multiple_abc_bases(self):
+ class MM1(MutableMapping[str, str], collections_abc.MutableMapping):
+ def __getitem__(self, k):
+ return None
+ def __setitem__(self, k, v):
+ pass
+ def __delitem__(self, k):
+ pass
+ def __iter__(self):
+ return iter(())
+ def __len__(self):
+ return 0
+ class MM2(collections_abc.MutableMapping, MutableMapping[str, str]):
+ def __getitem__(self, k):
+ return None
+ def __setitem__(self, k, v):
+ pass
+ def __delitem__(self, k):
+ pass
+ def __iter__(self):
+ return iter(())
+ def __len__(self):
+ return 0
+ # these two should just work
+ MM1().update()
+ MM2().update()
+ self.assertIsInstance(MM1(), collections_abc.MutableMapping)
+ self.assertIsInstance(MM1(), MutableMapping)
+ self.assertIsInstance(MM2(), collections_abc.MutableMapping)
+ self.assertIsInstance(MM2(), MutableMapping)
+
def test_pickle(self):
global C # pickle wants to reference the class by name
T = TypeVar('T')
@@ -854,6 +814,8 @@ class ClassVarTests(BaseTestCase):
def test_cannot_init(self):
with self.assertRaises(TypeError):
+ ClassVar()
+ with self.assertRaises(TypeError):
type(ClassVar)()
with self.assertRaises(TypeError):
type(ClassVar[Optional[int]])()
@@ -865,52 +827,6 @@ class ClassVarTests(BaseTestCase):
issubclass(int, ClassVar)
-class VarianceTests(BaseTestCase):
-
- def test_invariance(self):
- # Because of invariance, List[subclass of X] is not a subclass
- # of List[X], and ditto for MutableSequence.
- self.assertNotIsSubclass(typing.List[Manager], typing.List[Employee])
- self.assertNotIsSubclass(typing.MutableSequence[Manager],
- typing.MutableSequence[Employee])
- # It's still reflexive.
- self.assertIsSubclass(typing.List[Employee], typing.List[Employee])
- self.assertIsSubclass(typing.MutableSequence[Employee],
- typing.MutableSequence[Employee])
-
- def test_covariance_tuple(self):
- # Check covariace for Tuple (which are really special cases).
- self.assertIsSubclass(Tuple[Manager], Tuple[Employee])
- self.assertNotIsSubclass(Tuple[Employee], Tuple[Manager])
- # And pairwise.
- self.assertIsSubclass(Tuple[Manager, Manager],
- Tuple[Employee, Employee])
- self.assertNotIsSubclass(Tuple[Employee, Employee],
- Tuple[Manager, Employee])
- # And using ellipsis.
- self.assertIsSubclass(Tuple[Manager, ...], Tuple[Employee, ...])
- self.assertNotIsSubclass(Tuple[Employee, ...], Tuple[Manager, ...])
-
- def test_covariance_sequence(self):
- # Check covariance for Sequence (which is just a generic class
- # for this purpose, but using a type variable with covariant=True).
- self.assertIsSubclass(typing.Sequence[Manager],
- typing.Sequence[Employee])
- self.assertNotIsSubclass(typing.Sequence[Employee],
- typing.Sequence[Manager])
-
- def test_covariance_mapping(self):
- # Ditto for Mapping (covariant in the value, invariant in the key).
- self.assertIsSubclass(typing.Mapping[Employee, Manager],
- typing.Mapping[Employee, Employee])
- self.assertNotIsSubclass(typing.Mapping[Manager, Employee],
- typing.Mapping[Employee, Employee])
- self.assertNotIsSubclass(typing.Mapping[Employee, Manager],
- typing.Mapping[Manager, Manager])
- self.assertNotIsSubclass(typing.Mapping[Manager, Employee],
- typing.Mapping[Manager, Manager])
-
-
class CastTests(BaseTestCase):
def test_basics(self):
@@ -1247,7 +1163,6 @@ class CollectionsAbcTests(BaseTestCase):
# path and could fail. So call this a few times.
self.assertIsInstance([], typing.Iterable)
self.assertIsInstance([], typing.Iterable)
- self.assertIsInstance([], typing.Iterable[int])
self.assertNotIsInstance(42, typing.Iterable)
# Just in case, also test issubclass() a few times.
self.assertIsSubclass(list, typing.Iterable)
@@ -1256,7 +1171,6 @@ class CollectionsAbcTests(BaseTestCase):
def test_iterator(self):
it = iter([])
self.assertIsInstance(it, typing.Iterator)
- self.assertIsInstance(it, typing.Iterator[int])
self.assertNotIsInstance(42, typing.Iterator)
@skipUnless(PY35, 'Python 3.5 required')
@@ -1268,13 +1182,8 @@ class CollectionsAbcTests(BaseTestCase):
globals(), ns)
foo = ns['foo']
g = foo()
- self.assertIsSubclass(type(g), typing.Awaitable[int])
self.assertIsInstance(g, typing.Awaitable)
self.assertNotIsInstance(foo, typing.Awaitable)
- self.assertIsSubclass(typing.Awaitable[Manager],
- typing.Awaitable[Employee])
- self.assertNotIsSubclass(typing.Awaitable[Employee],
- typing.Awaitable[Manager])
g.send(None) # Run foo() till completion, to avoid warning.
@skipUnless(PY35, 'Python 3.5 required')
@@ -1283,8 +1192,6 @@ class CollectionsAbcTests(BaseTestCase):
it = AsyncIteratorWrapper(base_it)
self.assertIsInstance(it, typing.AsyncIterable)
self.assertIsInstance(it, typing.AsyncIterable)
- self.assertIsSubclass(typing.AsyncIterable[Manager],
- typing.AsyncIterable[Employee])
self.assertNotIsInstance(42, typing.AsyncIterable)
@skipUnless(PY35, 'Python 3.5 required')
@@ -1292,8 +1199,6 @@ class CollectionsAbcTests(BaseTestCase):
base_it = range(10) # type: Iterator[int]
it = AsyncIteratorWrapper(base_it)
self.assertIsInstance(it, typing.AsyncIterator)
- self.assertIsSubclass(typing.AsyncIterator[Manager],
- typing.AsyncIterator[Employee])
self.assertNotIsInstance(42, typing.AsyncIterator)
def test_sized(self):
@@ -1457,10 +1362,6 @@ class CollectionsAbcTests(BaseTestCase):
yield 42
g = foo()
self.assertIsSubclass(type(g), typing.Generator)
- self.assertIsSubclass(typing.Generator[Manager, Employee, Manager],
- typing.Generator[Employee, Manager, Employee])
- self.assertNotIsSubclass(typing.Generator[Manager, Manager, Manager],
- typing.Generator[Employee, Employee, Employee])
def test_no_generator_instantiation(self):
with self.assertRaises(TypeError):
@@ -1511,7 +1412,6 @@ class OtherABCTests(BaseTestCase):
cm = manager()
self.assertIsInstance(cm, typing.ContextManager)
- self.assertIsInstance(cm, typing.ContextManager[int])
self.assertNotIsInstance(42, typing.ContextManager)
@@ -1653,22 +1553,16 @@ class RETests(BaseTestCase):
pat = re.compile('[a-z]+', re.I)
self.assertIsSubclass(pat.__class__, Pattern)
self.assertIsSubclass(type(pat), Pattern)
- self.assertIsSubclass(type(pat), Pattern[str])
+ self.assertIsInstance(pat, Pattern)
mat = pat.search('12345abcde.....')
self.assertIsSubclass(mat.__class__, Match)
- self.assertIsSubclass(mat.__class__, Match[str])
- self.assertIsSubclass(mat.__class__, Match[bytes]) # Sad but true.
self.assertIsSubclass(type(mat), Match)
- self.assertIsSubclass(type(mat), Match[str])
+ self.assertIsInstance(mat, Match)
+ # these should just work
p = Pattern[Union[str, bytes]]
- self.assertIsSubclass(Pattern[str], Pattern)
- self.assertIsSubclass(Pattern[str], p)
-
m = Match[Union[bytes, str]]
- self.assertIsSubclass(Match[bytes], Match)
- self.assertIsSubclass(Match[bytes], m)
def test_errors(self):
with self.assertRaises(TypeError):
@@ -1683,9 +1577,6 @@ class RETests(BaseTestCase):
m[str]
with self.assertRaises(TypeError):
# We don't support isinstance().
- isinstance(42, Pattern)
- with self.assertRaises(TypeError):
- # We don't support isinstance().
isinstance(42, Pattern[str])
def test_repr(self):
@@ -1710,7 +1601,7 @@ class RETests(BaseTestCase):
pass
self.assertEqual(str(ex.exception),
- "A type alias cannot be subclassed")
+ "Cannot subclass typing._TypeAlias")
class AllTests(BaseTestCase):