summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_typing.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@dropbox.com>2016-09-11 22:31:27 (GMT)
committerGuido van Rossum <guido@dropbox.com>2016-09-11 22:31:27 (GMT)
commit7ac1f7d269acf4f0153c3ddfa2e578bd4bf16744 (patch)
treeac9c1907adfe71d88a54a13b367cc15ea9c59275 /Lib/test/test_typing.py
parent5fe668c6727b1301d4fbeb151d81854e74431295 (diff)
downloadcpython-7ac1f7d269acf4f0153c3ddfa2e578bd4bf16744.zip
cpython-7ac1f7d269acf4f0153c3ddfa2e578bd4bf16744.tar.gz
cpython-7ac1f7d269acf4f0153c3ddfa2e578bd4bf16744.tar.bz2
Issue #28079: Update typing and test typing from python/typing repo.
Ivan Levkivskyi (3.6 version)
Diffstat (limited to 'Lib/test/test_typing.py')
-rw-r--r--Lib/test/test_typing.py143
1 files changed, 101 insertions, 42 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index e3904b1..3b99060 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -4,8 +4,6 @@ import pickle
import re
import sys
from unittest import TestCase, main, skipUnless, SkipTest
-from collections import ChainMap
-from test import ann_module, ann_module2, ann_module3
from typing import Any
from typing import TypeVar, AnyStr
@@ -969,46 +967,6 @@ class ForwardRefTests(BaseTestCase):
right_hints = get_type_hints(t.add_right, globals(), locals())
self.assertEqual(right_hints['node'], Optional[Node[T]])
- def test_get_type_hints(self):
- gth = get_type_hints
- self.assertEqual(gth(ann_module), {'x': int, 'y': str})
- self.assertEqual(gth(ann_module.C, ann_module.__dict__),
- ChainMap({'y': Optional[ann_module.C]}, {}))
- self.assertEqual(gth(ann_module2), {})
- self.assertEqual(gth(ann_module3), {})
- 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})
-
- def testf(x, y): ...
- testf.__annotations__['x'] = 'int'
- self.assertEqual(gth(testf), {'x': int})
- self.assertEqual(gth(ann_module2.NTC.meth), {})
-
- # interactions with ClassVar
- class B:
- x: ClassVar[Optional['B']] = None
- y: int
- class C(B):
- z: ClassVar['C'] = B()
- class G(Generic[T]):
- lst: ClassVar[List[T]] = []
- self.assertEqual(gth(B, locals()),
- ChainMap({'y': int, 'x': ClassVar[Optional[B]]}, {}))
- self.assertEqual(gth(C, locals()),
- ChainMap({'z': ClassVar[C]},
- {'y': int, 'x': ClassVar[Optional[B]]}, {}))
- self.assertEqual(gth(G), ChainMap({'lst': ClassVar[List[T]]},{},{}))
-
def test_forwardref_instance_type_error(self):
fr = typing._ForwardRef('int')
with self.assertRaises(TypeError):
@@ -1198,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):
@@ -1505,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):
@@ -1542,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)])