summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_typing.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@dropbox.com>2016-09-11 22:34:56 (GMT)
committerGuido van Rossum <guido@dropbox.com>2016-09-11 22:34:56 (GMT)
commit0a6976da105a5be76a6a342c7eb978c82b2fd4d2 (patch)
treed3d60fc2ca6ed86b1705a8edbbe6f2cfd64fbb8e /Lib/test/test_typing.py
parent0e0cfd71355accafd009916472ebb4d4fe0ab4ec (diff)
downloadcpython-0a6976da105a5be76a6a342c7eb978c82b2fd4d2.zip
cpython-0a6976da105a5be76a6a342c7eb978c82b2fd4d2.tar.gz
cpython-0a6976da105a5be76a6a342c7eb978c82b2fd4d2.tar.bz2
Issue #28079: Update typing and test typing from python/typing repo.
Ivan Levkivskyi (3.5 version)
Diffstat (limited to 'Lib/test/test_typing.py')
-rw-r--r--Lib/test/test_typing.py142
1 files changed, 140 insertions, 2 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 72afe67..3b99060 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -9,9 +9,9 @@ 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
+from typing import Tuple, List
from typing import Callable
-from typing import Generic
+from typing import Generic, ClassVar
from typing import cast
from typing import get_type_hints
from typing import no_type_check, no_type_check_decorator
@@ -827,6 +827,43 @@ class GenericTests(BaseTestCase):
with self.assertRaises(Exception):
D[T]
+class ClassVarTests(BaseTestCase):
+
+ def test_basics(self):
+ with self.assertRaises(TypeError):
+ ClassVar[1]
+ with self.assertRaises(TypeError):
+ ClassVar[int, str]
+ with self.assertRaises(TypeError):
+ ClassVar[int][str]
+
+ def test_repr(self):
+ self.assertEqual(repr(ClassVar), 'typing.ClassVar')
+ cv = ClassVar[int]
+ self.assertEqual(repr(cv), 'typing.ClassVar[int]')
+ cv = ClassVar[Employee]
+ self.assertEqual(repr(cv), 'typing.ClassVar[%s.Employee]' % __name__)
+
+ def test_cannot_subclass(self):
+ with self.assertRaises(TypeError):
+ class C(type(ClassVar)):
+ pass
+ with self.assertRaises(TypeError):
+ class C(type(ClassVar[int])):
+ pass
+
+ def test_cannot_init(self):
+ with self.assertRaises(TypeError):
+ type(ClassVar)()
+ with self.assertRaises(TypeError):
+ type(ClassVar[Optional[int]])()
+
+ def test_no_isinstance(self):
+ with self.assertRaises(TypeError):
+ isinstance(1, ClassVar[int])
+ with self.assertRaises(TypeError):
+ issubclass(int, ClassVar)
+
class VarianceTests(BaseTestCase):
@@ -1119,6 +1156,84 @@ class AsyncIteratorWrapper(typing.AsyncIterator[T_a]):
if PY35:
exec(PY35_TESTS)
+PY36 = sys.version_info[:2] >= (3, 6)
+
+PY36_TESTS = """
+from test import ann_module, ann_module2, ann_module3
+from collections import ChainMap
+
+class B:
+ x: ClassVar[Optional['B']] = None
+ y: int
+class CSub(B):
+ z: ClassVar['CSub'] = B()
+class G(Generic[T]):
+ lst: ClassVar[List[T]] = []
+
+class CoolEmployee(NamedTuple):
+ name: str
+ cool: int
+"""
+
+if PY36:
+ exec(PY36_TESTS)
+
+gth = get_type_hints
+
+class GetTypeHintTests(BaseTestCase):
+ @skipUnless(PY36, 'Python 3.6 required')
+ def test_get_type_hints_modules(self):
+ self.assertEqual(gth(ann_module), {'x': int, 'y': str})
+ self.assertEqual(gth(ann_module2), {})
+ self.assertEqual(gth(ann_module3), {})
+
+ @skipUnless(PY36, 'Python 3.6 required')
+ def test_get_type_hints_classes(self):
+ self.assertEqual(gth(ann_module.C, ann_module.__dict__),
+ ChainMap({'y': Optional[ann_module.C]}, {}))
+ self.assertEqual(repr(gth(ann_module.j_class)), 'ChainMap({}, {})')
+ self.assertEqual(gth(ann_module.M), ChainMap({'123': 123, 'o': type},
+ {}, {}))
+ self.assertEqual(gth(ann_module.D),
+ ChainMap({'j': str, 'k': str,
+ 'y': Optional[ann_module.C]}, {}))
+ self.assertEqual(gth(ann_module.Y), ChainMap({'z': int}, {}))
+ self.assertEqual(gth(ann_module.h_class),
+ ChainMap({}, {'y': Optional[ann_module.C]}, {}))
+ self.assertEqual(gth(ann_module.S), ChainMap({'x': str, 'y': str},
+ {}))
+ self.assertEqual(gth(ann_module.foo), {'x': int})
+
+ @skipUnless(PY36, 'Python 3.6 required')
+ def test_respect_no_type_check(self):
+ @no_type_check
+ class NoTpCheck:
+ class Inn:
+ def __init__(self, x: 'not a type'): ...
+ self.assertTrue(NoTpCheck.__no_type_check__)
+ self.assertTrue(NoTpCheck.Inn.__init__.__no_type_check__)
+ self.assertEqual(gth(ann_module2.NTC.meth), {})
+ class ABase(Generic[T]):
+ def meth(x: int): ...
+ @no_type_check
+ class Der(ABase): ...
+ self.assertEqual(gth(ABase.meth), {'x': int})
+
+
+ def test_previous_behavior(self):
+ def testf(x, y): ...
+ testf.__annotations__['x'] = 'int'
+ self.assertEqual(gth(testf), {'x': int})
+
+ @skipUnless(PY36, 'Python 3.6 required')
+ def test_get_type_hints_ClassVar(self):
+ self.assertEqual(gth(B, globals()),
+ ChainMap({'y': int, 'x': ClassVar[Optional[B]]}, {}))
+ self.assertEqual(gth(CSub, globals()),
+ ChainMap({'z': ClassVar[CSub]},
+ {'y': int, 'x': ClassVar[Optional[B]]}, {}))
+ self.assertEqual(gth(G), ChainMap({'lst': ClassVar[List[T]]},{},{}))
+
class CollectionsAbcTests(BaseTestCase):
@@ -1426,6 +1541,18 @@ class TypeTests(BaseTestCase):
joe = new_user(BasicUser)
+ def test_type_optional(self):
+ A = Optional[Type[BaseException]]
+
+ def foo(a: A) -> Optional[BaseException]:
+ if a is None:
+ return None
+ else:
+ return a()
+
+ assert isinstance(foo(KeyboardInterrupt), KeyboardInterrupt)
+ assert foo(None) is None
+
class NewTypeTests(BaseTestCase):
@@ -1463,6 +1590,17 @@ class NamedTupleTests(BaseTestCase):
self.assertEqual(Emp._fields, ('name', 'id'))
self.assertEqual(Emp._field_types, dict(name=str, id=int))
+ @skipUnless(PY36, 'Python 3.6 required')
+ def test_annotation_usage(self):
+ tim = CoolEmployee('Tim', 9000)
+ self.assertIsInstance(tim, CoolEmployee)
+ self.assertIsInstance(tim, tuple)
+ self.assertEqual(tim.name, 'Tim')
+ self.assertEqual(tim.cool, 9000)
+ self.assertEqual(CoolEmployee.__name__, 'CoolEmployee')
+ self.assertEqual(CoolEmployee._fields, ('name', 'cool'))
+ self.assertEqual(CoolEmployee._field_types, dict(name=str, cool=int))
+
def test_pickle(self):
global Emp # pickle wants to reference the class by name
Emp = NamedTuple('Emp', [('name', str), ('id', int)])