mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
Issue #28079: Update typing and test typing from python/typing repo.
Ivan Levkivskyi (3.5 version)
This commit is contained in:
parent
0e0cfd7135
commit
0a6976da10
2 changed files with 409 additions and 65 deletions
|
@ -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)])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue