Commit 0a6976da authored by Guido van Rossum's avatar Guido van Rossum

Issue #28079: Update typing and test typing from python/typing repo.

Ivan Levkivskyi (3.5 version)
parent 0e0cfd71
......@@ -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)])
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment