1import contextlib 2import collections 3import pickle 4import re 5import sys 6from unittest import TestCase, main, skipUnless, SkipTest 7from copy import copy, deepcopy 8 9from typing import Any 10from typing import TypeVar, AnyStr 11from typing import T, KT, VT # Not in __all__. 12from typing import Union, Optional 13from typing import Tuple, List, MutableMapping 14from typing import Callable 15from typing import Generic, ClassVar, GenericMeta 16from typing import cast 17from typing import get_type_hints 18from typing import no_type_check, no_type_check_decorator 19from typing import Type 20from typing import NewType 21from typing import NamedTuple 22from typing import IO, TextIO, BinaryIO 23from typing import Pattern, Match 24import abc 25import typing 26import weakref 27try: 28 import collections.abc as collections_abc 29except ImportError: 30 import collections as collections_abc # Fallback for PY3.2. 31 32 33class BaseTestCase(TestCase): 34 35 def assertIsSubclass(self, cls, class_or_tuple, msg=None): 36 if not issubclass(cls, class_or_tuple): 37 message = '%r is not a subclass of %r' % (cls, class_or_tuple) 38 if msg is not None: 39 message += ' : %s' % msg 40 raise self.failureException(message) 41 42 def assertNotIsSubclass(self, cls, class_or_tuple, msg=None): 43 if issubclass(cls, class_or_tuple): 44 message = '%r is a subclass of %r' % (cls, class_or_tuple) 45 if msg is not None: 46 message += ' : %s' % msg 47 raise self.failureException(message) 48 49 def clear_caches(self): 50 for f in typing._cleanups: 51 f() 52 53 54class Employee: 55 pass 56 57 58class Manager(Employee): 59 pass 60 61 62class Founder(Employee): 63 pass 64 65 66class ManagingFounder(Manager, Founder): 67 pass 68 69 70class AnyTests(BaseTestCase): 71 72 def test_any_instance_type_error(self): 73 with self.assertRaises(TypeError): 74 isinstance(42, Any) 75 76 def test_any_subclass_type_error(self): 77 with self.assertRaises(TypeError): 78 issubclass(Employee, Any) 79 with self.assertRaises(TypeError): 80 issubclass(Any, Employee) 81 82 def test_repr(self): 83 self.assertEqual(repr(Any), 'typing.Any') 84 85 def test_errors(self): 86 with self.assertRaises(TypeError): 87 issubclass(42, Any) 88 with self.assertRaises(TypeError): 89 Any[int] # Any is not a generic type. 90 91 def test_cannot_subclass(self): 92 with self.assertRaises(TypeError): 93 class A(Any): 94 pass 95 with self.assertRaises(TypeError): 96 class A(type(Any)): 97 pass 98 99 def test_cannot_instantiate(self): 100 with self.assertRaises(TypeError): 101 Any() 102 with self.assertRaises(TypeError): 103 type(Any)() 104 105 def test_cannot_subscript(self): 106 with self.assertRaises(TypeError): 107 Any[int] 108 109 def test_any_works_with_alias(self): 110 # These expressions must simply not fail. 111 typing.Match[Any] 112 typing.Pattern[Any] 113 typing.IO[Any] 114 115 116class TypeVarTests(BaseTestCase): 117 118 def test_basic_plain(self): 119 T = TypeVar('T') 120 # T equals itself. 121 self.assertEqual(T, T) 122 # T is an instance of TypeVar 123 self.assertIsInstance(T, TypeVar) 124 125 def test_typevar_instance_type_error(self): 126 T = TypeVar('T') 127 with self.assertRaises(TypeError): 128 isinstance(42, T) 129 130 def test_typevar_subclass_type_error(self): 131 T = TypeVar('T') 132 with self.assertRaises(TypeError): 133 issubclass(int, T) 134 with self.assertRaises(TypeError): 135 issubclass(T, int) 136 137 def test_constrained_error(self): 138 with self.assertRaises(TypeError): 139 X = TypeVar('X', int) 140 X 141 142 def test_union_unique(self): 143 X = TypeVar('X') 144 Y = TypeVar('Y') 145 self.assertNotEqual(X, Y) 146 self.assertEqual(Union[X], X) 147 self.assertNotEqual(Union[X], Union[X, Y]) 148 self.assertEqual(Union[X, X], X) 149 self.assertNotEqual(Union[X, int], Union[X]) 150 self.assertNotEqual(Union[X, int], Union[int]) 151 self.assertEqual(Union[X, int].__args__, (X, int)) 152 self.assertEqual(Union[X, int].__parameters__, (X,)) 153 self.assertIs(Union[X, int].__origin__, Union) 154 155 def test_union_constrained(self): 156 A = TypeVar('A', str, bytes) 157 self.assertNotEqual(Union[A, str], Union[A]) 158 159 def test_repr(self): 160 self.assertEqual(repr(T), '~T') 161 self.assertEqual(repr(KT), '~KT') 162 self.assertEqual(repr(VT), '~VT') 163 self.assertEqual(repr(AnyStr), '~AnyStr') 164 T_co = TypeVar('T_co', covariant=True) 165 self.assertEqual(repr(T_co), '+T_co') 166 T_contra = TypeVar('T_contra', contravariant=True) 167 self.assertEqual(repr(T_contra), '-T_contra') 168 169 def test_no_redefinition(self): 170 self.assertNotEqual(TypeVar('T'), TypeVar('T')) 171 self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str)) 172 173 def test_cannot_subclass_vars(self): 174 with self.assertRaises(TypeError): 175 class V(TypeVar('T')): 176 pass 177 178 def test_cannot_subclass_var_itself(self): 179 with self.assertRaises(TypeError): 180 class V(TypeVar): 181 pass 182 183 def test_cannot_instantiate_vars(self): 184 with self.assertRaises(TypeError): 185 TypeVar('A')() 186 187 def test_bound_errors(self): 188 with self.assertRaises(TypeError): 189 TypeVar('X', bound=42) 190 with self.assertRaises(TypeError): 191 TypeVar('X', str, float, bound=Employee) 192 193 def test_no_bivariant(self): 194 with self.assertRaises(ValueError): 195 TypeVar('T', covariant=True, contravariant=True) 196 197 198class UnionTests(BaseTestCase): 199 200 def test_basics(self): 201 u = Union[int, float] 202 self.assertNotEqual(u, Union) 203 204 def test_subclass_error(self): 205 with self.assertRaises(TypeError): 206 issubclass(int, Union) 207 with self.assertRaises(TypeError): 208 issubclass(Union, int) 209 with self.assertRaises(TypeError): 210 issubclass(int, Union[int, str]) 211 with self.assertRaises(TypeError): 212 issubclass(Union[int, str], int) 213 214 def test_union_any(self): 215 u = Union[Any] 216 self.assertEqual(u, Any) 217 u1 = Union[int, Any] 218 u2 = Union[Any, int] 219 u3 = Union[Any, object] 220 self.assertEqual(u1, u2) 221 self.assertNotEqual(u1, Any) 222 self.assertNotEqual(u2, Any) 223 self.assertNotEqual(u3, Any) 224 225 def test_union_object(self): 226 u = Union[object] 227 self.assertEqual(u, object) 228 u = Union[int, object] 229 self.assertEqual(u, object) 230 u = Union[object, int] 231 self.assertEqual(u, object) 232 233 def test_unordered(self): 234 u1 = Union[int, float] 235 u2 = Union[float, int] 236 self.assertEqual(u1, u2) 237 238 def test_single_class_disappears(self): 239 t = Union[Employee] 240 self.assertIs(t, Employee) 241 242 def test_base_class_disappears(self): 243 u = Union[Employee, Manager, int] 244 self.assertEqual(u, Union[int, Employee]) 245 u = Union[Manager, int, Employee] 246 self.assertEqual(u, Union[int, Employee]) 247 u = Union[Employee, Manager] 248 self.assertIs(u, Employee) 249 250 def test_union_union(self): 251 u = Union[int, float] 252 v = Union[u, Employee] 253 self.assertEqual(v, Union[int, float, Employee]) 254 255 def test_repr(self): 256 self.assertEqual(repr(Union), 'typing.Union') 257 u = Union[Employee, int] 258 self.assertEqual(repr(u), 'typing.Union[%s.Employee, int]' % __name__) 259 u = Union[int, Employee] 260 self.assertEqual(repr(u), 'typing.Union[int, %s.Employee]' % __name__) 261 T = TypeVar('T') 262 u = Union[T, int][int] 263 self.assertEqual(repr(u), repr(int)) 264 u = Union[List[int], int] 265 self.assertEqual(repr(u), 'typing.Union[typing.List[int], int]') 266 267 def test_cannot_subclass(self): 268 with self.assertRaises(TypeError): 269 class C(Union): 270 pass 271 with self.assertRaises(TypeError): 272 class C(type(Union)): 273 pass 274 with self.assertRaises(TypeError): 275 class C(Union[int, str]): 276 pass 277 278 def test_cannot_instantiate(self): 279 with self.assertRaises(TypeError): 280 Union() 281 with self.assertRaises(TypeError): 282 type(Union)() 283 u = Union[int, float] 284 with self.assertRaises(TypeError): 285 u() 286 with self.assertRaises(TypeError): 287 type(u)() 288 289 def test_union_generalization(self): 290 self.assertFalse(Union[str, typing.Iterable[int]] == str) 291 self.assertFalse(Union[str, typing.Iterable[int]] == typing.Iterable[int]) 292 self.assertTrue(Union[str, typing.Iterable] == typing.Iterable) 293 294 def test_union_compare_other(self): 295 self.assertNotEqual(Union, object) 296 self.assertNotEqual(Union, Any) 297 self.assertNotEqual(ClassVar, Union) 298 self.assertNotEqual(Optional, Union) 299 self.assertNotEqual([None], Optional) 300 self.assertNotEqual(Optional, typing.Mapping) 301 self.assertNotEqual(Optional[typing.MutableMapping], Union) 302 303 def test_optional(self): 304 o = Optional[int] 305 u = Union[int, None] 306 self.assertEqual(o, u) 307 308 def test_empty(self): 309 with self.assertRaises(TypeError): 310 Union[()] 311 312 def test_union_instance_type_error(self): 313 with self.assertRaises(TypeError): 314 isinstance(42, Union[int, str]) 315 316 def test_no_eval_union(self): 317 u = Union[int, str] 318 def f(x: u): ... 319 self.assertIs(get_type_hints(f)['x'], u) 320 321 def test_function_repr_union(self): 322 def fun() -> int: ... 323 self.assertEqual(repr(Union[fun, int]), 'typing.Union[fun, int]') 324 325 def test_union_str_pattern(self): 326 # Shouldn't crash; see http://bugs.python.org/issue25390 327 A = Union[str, Pattern] 328 A 329 330 def test_etree(self): 331 # See https://github.com/python/typing/issues/229 332 # (Only relevant for Python 2.) 333 try: 334 from xml.etree.cElementTree import Element 335 except ImportError: 336 raise SkipTest("cElementTree not found") 337 Union[Element, str] # Shouldn't crash 338 339 def Elem(*args): 340 return Element(*args) 341 342 Union[Elem, str] # Nor should this 343 344 345class TupleTests(BaseTestCase): 346 347 def test_basics(self): 348 with self.assertRaises(TypeError): 349 issubclass(Tuple, Tuple[int, str]) 350 with self.assertRaises(TypeError): 351 issubclass(tuple, Tuple[int, str]) 352 353 class TP(tuple): ... 354 self.assertTrue(issubclass(tuple, Tuple)) 355 self.assertTrue(issubclass(TP, Tuple)) 356 357 def test_equality(self): 358 self.assertEqual(Tuple[int], Tuple[int]) 359 self.assertEqual(Tuple[int, ...], Tuple[int, ...]) 360 self.assertNotEqual(Tuple[int], Tuple[int, int]) 361 self.assertNotEqual(Tuple[int], Tuple[int, ...]) 362 363 def test_tuple_subclass(self): 364 class MyTuple(tuple): 365 pass 366 self.assertTrue(issubclass(MyTuple, Tuple)) 367 368 def test_tuple_instance_type_error(self): 369 with self.assertRaises(TypeError): 370 isinstance((0, 0), Tuple[int, int]) 371 self.assertIsInstance((0, 0), Tuple) 372 373 def test_repr(self): 374 self.assertEqual(repr(Tuple), 'typing.Tuple') 375 self.assertEqual(repr(Tuple[()]), 'typing.Tuple[()]') 376 self.assertEqual(repr(Tuple[int, float]), 'typing.Tuple[int, float]') 377 self.assertEqual(repr(Tuple[int, ...]), 'typing.Tuple[int, ...]') 378 379 def test_errors(self): 380 with self.assertRaises(TypeError): 381 issubclass(42, Tuple) 382 with self.assertRaises(TypeError): 383 issubclass(42, Tuple[int]) 384 385 386class CallableTests(BaseTestCase): 387 388 def test_self_subclass(self): 389 with self.assertRaises(TypeError): 390 self.assertTrue(issubclass(type(lambda x: x), Callable[[int], int])) 391 self.assertTrue(issubclass(type(lambda x: x), Callable)) 392 393 def test_eq_hash(self): 394 self.assertEqual(Callable[[int], int], Callable[[int], int]) 395 self.assertEqual(len({Callable[[int], int], Callable[[int], int]}), 1) 396 self.assertNotEqual(Callable[[int], int], Callable[[int], str]) 397 self.assertNotEqual(Callable[[int], int], Callable[[str], int]) 398 self.assertNotEqual(Callable[[int], int], Callable[[int, int], int]) 399 self.assertNotEqual(Callable[[int], int], Callable[[], int]) 400 self.assertNotEqual(Callable[[int], int], Callable) 401 402 def test_cannot_instantiate(self): 403 with self.assertRaises(TypeError): 404 Callable() 405 with self.assertRaises(TypeError): 406 type(Callable)() 407 c = Callable[[int], str] 408 with self.assertRaises(TypeError): 409 c() 410 with self.assertRaises(TypeError): 411 type(c)() 412 413 def test_callable_wrong_forms(self): 414 with self.assertRaises(TypeError): 415 Callable[[...], int] 416 with self.assertRaises(TypeError): 417 Callable[(), int] 418 with self.assertRaises(TypeError): 419 Callable[[()], int] 420 with self.assertRaises(TypeError): 421 Callable[[int, 1], 2] 422 with self.assertRaises(TypeError): 423 Callable[int] 424 425 def test_callable_instance_works(self): 426 def f(): 427 pass 428 self.assertIsInstance(f, Callable) 429 self.assertNotIsInstance(None, Callable) 430 431 def test_callable_instance_type_error(self): 432 def f(): 433 pass 434 with self.assertRaises(TypeError): 435 self.assertIsInstance(f, Callable[[], None]) 436 with self.assertRaises(TypeError): 437 self.assertIsInstance(f, Callable[[], Any]) 438 with self.assertRaises(TypeError): 439 self.assertNotIsInstance(None, Callable[[], None]) 440 with self.assertRaises(TypeError): 441 self.assertNotIsInstance(None, Callable[[], Any]) 442 443 def test_repr(self): 444 ct0 = Callable[[], bool] 445 self.assertEqual(repr(ct0), 'typing.Callable[[], bool]') 446 ct2 = Callable[[str, float], int] 447 self.assertEqual(repr(ct2), 'typing.Callable[[str, float], int]') 448 ctv = Callable[..., str] 449 self.assertEqual(repr(ctv), 'typing.Callable[..., str]') 450 451 def test_callable_with_ellipsis(self): 452 453 def foo(a: Callable[..., T]): 454 pass 455 456 self.assertEqual(get_type_hints(foo, globals(), locals()), 457 {'a': Callable[..., T]}) 458 459 def test_ellipsis_in_generic(self): 460 # Shouldn't crash; see https://github.com/python/typing/issues/259 461 typing.List[Callable[..., str]] 462 463 464XK = TypeVar('XK', str, bytes) 465XV = TypeVar('XV') 466 467 468class SimpleMapping(Generic[XK, XV]): 469 470 def __getitem__(self, key: XK) -> XV: 471 ... 472 473 def __setitem__(self, key: XK, value: XV): 474 ... 475 476 def get(self, key: XK, default: XV = None) -> XV: 477 ... 478 479 480class MySimpleMapping(SimpleMapping[XK, XV]): 481 482 def __init__(self): 483 self.store = {} 484 485 def __getitem__(self, key: str): 486 return self.store[key] 487 488 def __setitem__(self, key: str, value): 489 self.store[key] = value 490 491 def get(self, key: str, default=None): 492 try: 493 return self.store[key] 494 except KeyError: 495 return default 496 497 498class ProtocolTests(BaseTestCase): 499 500 def test_supports_int(self): 501 self.assertIsSubclass(int, typing.SupportsInt) 502 self.assertNotIsSubclass(str, typing.SupportsInt) 503 504 def test_supports_float(self): 505 self.assertIsSubclass(float, typing.SupportsFloat) 506 self.assertNotIsSubclass(str, typing.SupportsFloat) 507 508 def test_supports_complex(self): 509 510 # Note: complex itself doesn't have __complex__. 511 class C: 512 def __complex__(self): 513 return 0j 514 515 self.assertIsSubclass(C, typing.SupportsComplex) 516 self.assertNotIsSubclass(str, typing.SupportsComplex) 517 518 def test_supports_bytes(self): 519 520 # Note: bytes itself doesn't have __bytes__. 521 class B: 522 def __bytes__(self): 523 return b'' 524 525 self.assertIsSubclass(B, typing.SupportsBytes) 526 self.assertNotIsSubclass(str, typing.SupportsBytes) 527 528 def test_supports_abs(self): 529 self.assertIsSubclass(float, typing.SupportsAbs) 530 self.assertIsSubclass(int, typing.SupportsAbs) 531 self.assertNotIsSubclass(str, typing.SupportsAbs) 532 533 def test_supports_round(self): 534 issubclass(float, typing.SupportsRound) 535 self.assertIsSubclass(float, typing.SupportsRound) 536 self.assertIsSubclass(int, typing.SupportsRound) 537 self.assertNotIsSubclass(str, typing.SupportsRound) 538 539 def test_reversible(self): 540 self.assertIsSubclass(list, typing.Reversible) 541 self.assertNotIsSubclass(int, typing.Reversible) 542 543 def test_protocol_instance_type_error(self): 544 with self.assertRaises(TypeError): 545 isinstance(0, typing.SupportsAbs) 546 class C1(typing.SupportsInt): 547 def __int__(self) -> int: 548 return 42 549 class C2(C1): 550 pass 551 c = C2() 552 self.assertIsInstance(c, C1) 553 554 555class GenericTests(BaseTestCase): 556 557 def test_basics(self): 558 X = SimpleMapping[str, Any] 559 self.assertEqual(X.__parameters__, ()) 560 with self.assertRaises(TypeError): 561 X[str] 562 with self.assertRaises(TypeError): 563 X[str, str] 564 Y = SimpleMapping[XK, str] 565 self.assertEqual(Y.__parameters__, (XK,)) 566 Y[str] 567 with self.assertRaises(TypeError): 568 Y[str, str] 569 self.assertIsSubclass(SimpleMapping[str, int], SimpleMapping) 570 571 def test_generic_errors(self): 572 T = TypeVar('T') 573 S = TypeVar('S') 574 with self.assertRaises(TypeError): 575 Generic[T]() 576 with self.assertRaises(TypeError): 577 Generic[T][T] 578 with self.assertRaises(TypeError): 579 Generic[T][S] 580 with self.assertRaises(TypeError): 581 isinstance([], List[int]) 582 with self.assertRaises(TypeError): 583 issubclass(list, List[int]) 584 with self.assertRaises(TypeError): 585 class NewGeneric(Generic): ... 586 with self.assertRaises(TypeError): 587 class MyGeneric(Generic[T], Generic[S]): ... 588 with self.assertRaises(TypeError): 589 class MyGeneric(List[T], Generic[S]): ... 590 591 def test_init(self): 592 T = TypeVar('T') 593 S = TypeVar('S') 594 with self.assertRaises(TypeError): 595 Generic[T, T] 596 with self.assertRaises(TypeError): 597 Generic[T, S, T] 598 599 def test_repr(self): 600 self.assertEqual(repr(SimpleMapping), 601 __name__ + '.' + 'SimpleMapping') 602 self.assertEqual(repr(MySimpleMapping), 603 __name__ + '.' + 'MySimpleMapping') 604 605 def test_chain_repr(self): 606 T = TypeVar('T') 607 S = TypeVar('S') 608 609 class C(Generic[T]): 610 pass 611 612 X = C[Tuple[S, T]] 613 self.assertEqual(X, C[Tuple[S, T]]) 614 self.assertNotEqual(X, C[Tuple[T, S]]) 615 616 Y = X[T, int] 617 self.assertEqual(Y, X[T, int]) 618 self.assertNotEqual(Y, X[S, int]) 619 self.assertNotEqual(Y, X[T, str]) 620 621 Z = Y[str] 622 self.assertEqual(Z, Y[str]) 623 self.assertNotEqual(Z, Y[int]) 624 self.assertNotEqual(Z, Y[T]) 625 626 self.assertTrue(str(Z).endswith( 627 '.C[typing.Tuple[str, int]]')) 628 629 def test_new_repr(self): 630 T = TypeVar('T') 631 U = TypeVar('U', covariant=True) 632 S = TypeVar('S') 633 634 self.assertEqual(repr(List), 'typing.List') 635 self.assertEqual(repr(List[T]), 'typing.List[~T]') 636 self.assertEqual(repr(List[U]), 'typing.List[+U]') 637 self.assertEqual(repr(List[S][T][int]), 'typing.List[int]') 638 self.assertEqual(repr(List[int]), 'typing.List[int]') 639 640 def test_new_repr_complex(self): 641 T = TypeVar('T') 642 TS = TypeVar('TS') 643 644 self.assertEqual(repr(typing.Mapping[T, TS][TS, T]), 'typing.Mapping[~TS, ~T]') 645 self.assertEqual(repr(List[Tuple[T, TS]][int, T]), 646 'typing.List[typing.Tuple[int, ~T]]') 647 self.assertEqual( 648 repr(List[Tuple[T, T]][List[int]]), 649 'typing.List[typing.Tuple[typing.List[int], typing.List[int]]]' 650 ) 651 652 def test_new_repr_bare(self): 653 T = TypeVar('T') 654 self.assertEqual(repr(Generic[T]), 'typing.Generic[~T]') 655 self.assertEqual(repr(typing._Protocol[T]), 'typing.Protocol[~T]') 656 class C(typing.Dict[Any, Any]): ... 657 # this line should just work 658 repr(C.__mro__) 659 660 def test_dict(self): 661 T = TypeVar('T') 662 663 class B(Generic[T]): 664 pass 665 666 b = B() 667 b.foo = 42 668 self.assertEqual(b.__dict__, {'foo': 42}) 669 670 class C(B[int]): 671 pass 672 673 c = C() 674 c.bar = 'abc' 675 self.assertEqual(c.__dict__, {'bar': 'abc'}) 676 677 def test_subscripted_generics_as_proxies(self): 678 T = TypeVar('T') 679 class C(Generic[T]): 680 x = 'def' 681 self.assertEqual(C[int].x, 'def') 682 self.assertEqual(C[C[int]].x, 'def') 683 C[C[int]].x = 'changed' 684 self.assertEqual(C.x, 'changed') 685 self.assertEqual(C[str].x, 'changed') 686 C[List[str]].z = 'new' 687 self.assertEqual(C.z, 'new') 688 self.assertEqual(C[Tuple[int]].z, 'new') 689 690 self.assertEqual(C().x, 'changed') 691 self.assertEqual(C[Tuple[str]]().z, 'new') 692 693 class D(C[T]): 694 pass 695 self.assertEqual(D[int].x, 'changed') 696 self.assertEqual(D.z, 'new') 697 D.z = 'from derived z' 698 D[int].x = 'from derived x' 699 self.assertEqual(C.x, 'changed') 700 self.assertEqual(C[int].z, 'new') 701 self.assertEqual(D.x, 'from derived x') 702 self.assertEqual(D[str].z, 'from derived z') 703 704 def test_abc_registry_kept(self): 705 T = TypeVar('T') 706 class C(Generic[T]): ... 707 C.register(int) 708 self.assertIsInstance(1, C) 709 C[int] 710 self.assertIsInstance(1, C) 711 712 def test_false_subclasses(self): 713 class MyMapping(MutableMapping[str, str]): pass 714 self.assertNotIsInstance({}, MyMapping) 715 self.assertNotIsSubclass(dict, MyMapping) 716 717 def test_abc_bases(self): 718 class MM(MutableMapping[str, str]): 719 def __getitem__(self, k): 720 return None 721 def __setitem__(self, k, v): 722 pass 723 def __delitem__(self, k): 724 pass 725 def __iter__(self): 726 return iter(()) 727 def __len__(self): 728 return 0 729 # this should just work 730 MM().update() 731 self.assertIsInstance(MM(), collections_abc.MutableMapping) 732 self.assertIsInstance(MM(), MutableMapping) 733 self.assertNotIsInstance(MM(), List) 734 self.assertNotIsInstance({}, MM) 735 736 def test_multiple_bases(self): 737 class MM1(MutableMapping[str, str], collections_abc.MutableMapping): 738 pass 739 with self.assertRaises(TypeError): 740 # consistent MRO not possible 741 class MM2(collections_abc.MutableMapping, MutableMapping[str, str]): 742 pass 743 744 def test_orig_bases(self): 745 T = TypeVar('T') 746 class C(typing.Dict[str, T]): ... 747 self.assertEqual(C.__orig_bases__, (typing.Dict[str, T],)) 748 749 def test_naive_runtime_checks(self): 750 def naive_dict_check(obj, tp): 751 # Check if a dictionary conforms to Dict type 752 if len(tp.__parameters__) > 0: 753 raise NotImplementedError 754 if tp.__args__: 755 KT, VT = tp.__args__ 756 return all( 757 isinstance(k, KT) and isinstance(v, VT) 758 for k, v in obj.items() 759 ) 760 self.assertTrue(naive_dict_check({'x': 1}, typing.Dict[str, int])) 761 self.assertFalse(naive_dict_check({1: 'x'}, typing.Dict[str, int])) 762 with self.assertRaises(NotImplementedError): 763 naive_dict_check({1: 'x'}, typing.Dict[str, T]) 764 765 def naive_generic_check(obj, tp): 766 # Check if an instance conforms to the generic class 767 if not hasattr(obj, '__orig_class__'): 768 raise NotImplementedError 769 return obj.__orig_class__ == tp 770 class Node(Generic[T]): ... 771 self.assertTrue(naive_generic_check(Node[int](), Node[int])) 772 self.assertFalse(naive_generic_check(Node[str](), Node[int])) 773 self.assertFalse(naive_generic_check(Node[str](), List)) 774 with self.assertRaises(NotImplementedError): 775 naive_generic_check([1, 2, 3], Node[int]) 776 777 def naive_list_base_check(obj, tp): 778 # Check if list conforms to a List subclass 779 return all(isinstance(x, tp.__orig_bases__[0].__args__[0]) 780 for x in obj) 781 class C(List[int]): ... 782 self.assertTrue(naive_list_base_check([1, 2, 3], C)) 783 self.assertFalse(naive_list_base_check(['a', 'b'], C)) 784 785 def test_multi_subscr_base(self): 786 T = TypeVar('T') 787 U = TypeVar('U') 788 V = TypeVar('V') 789 class C(List[T][U][V]): ... 790 class D(C, List[T][U][V]): ... 791 self.assertEqual(C.__parameters__, (V,)) 792 self.assertEqual(D.__parameters__, (V,)) 793 self.assertEqual(C[int].__parameters__, ()) 794 self.assertEqual(D[int].__parameters__, ()) 795 self.assertEqual(C[int].__args__, (int,)) 796 self.assertEqual(D[int].__args__, (int,)) 797 self.assertEqual(C.__bases__, (List,)) 798 self.assertEqual(D.__bases__, (C, List)) 799 self.assertEqual(C.__orig_bases__, (List[T][U][V],)) 800 self.assertEqual(D.__orig_bases__, (C, List[T][U][V])) 801 802 def test_subscript_meta(self): 803 T = TypeVar('T') 804 self.assertEqual(Type[GenericMeta], Type[GenericMeta]) 805 self.assertEqual(Union[T, int][GenericMeta], Union[GenericMeta, int]) 806 self.assertEqual(Callable[..., GenericMeta].__args__, (Ellipsis, GenericMeta)) 807 808 def test_generic_hashes(self): 809 try: 810 from test import mod_generics_cache 811 except ImportError: # for Python 3.4 and previous versions 812 import mod_generics_cache 813 class A(Generic[T]): 814 ... 815 816 class B(Generic[T]): 817 class A(Generic[T]): 818 ... 819 820 self.assertEqual(A, A) 821 self.assertEqual(mod_generics_cache.A[str], mod_generics_cache.A[str]) 822 self.assertEqual(B.A, B.A) 823 self.assertEqual(mod_generics_cache.B.A[B.A[str]], 824 mod_generics_cache.B.A[B.A[str]]) 825 826 self.assertNotEqual(A, B.A) 827 self.assertNotEqual(A, mod_generics_cache.A) 828 self.assertNotEqual(A, mod_generics_cache.B.A) 829 self.assertNotEqual(B.A, mod_generics_cache.A) 830 self.assertNotEqual(B.A, mod_generics_cache.B.A) 831 832 self.assertNotEqual(A[str], B.A[str]) 833 self.assertNotEqual(A[List[Any]], B.A[List[Any]]) 834 self.assertNotEqual(A[str], mod_generics_cache.A[str]) 835 self.assertNotEqual(A[str], mod_generics_cache.B.A[str]) 836 self.assertNotEqual(B.A[int], mod_generics_cache.A[int]) 837 self.assertNotEqual(B.A[List[Any]], mod_generics_cache.B.A[List[Any]]) 838 839 self.assertNotEqual(Tuple[A[str]], Tuple[B.A[str]]) 840 self.assertNotEqual(Tuple[A[List[Any]]], Tuple[B.A[List[Any]]]) 841 self.assertNotEqual(Union[str, A[str]], Union[str, mod_generics_cache.A[str]]) 842 self.assertNotEqual(Union[A[str], A[str]], 843 Union[A[str], mod_generics_cache.A[str]]) 844 self.assertNotEqual(typing.FrozenSet[A[str]], 845 typing.FrozenSet[mod_generics_cache.B.A[str]]) 846 847 if sys.version_info[:2] > (3, 2): 848 self.assertTrue(repr(Tuple[A[str]]).endswith('<locals>.A[str]]')) 849 self.assertTrue(repr(Tuple[B.A[str]]).endswith('<locals>.B.A[str]]')) 850 self.assertTrue(repr(Tuple[mod_generics_cache.A[str]]) 851 .endswith('mod_generics_cache.A[str]]')) 852 self.assertTrue(repr(Tuple[mod_generics_cache.B.A[str]]) 853 .endswith('mod_generics_cache.B.A[str]]')) 854 855 def test_extended_generic_rules_eq(self): 856 T = TypeVar('T') 857 U = TypeVar('U') 858 self.assertEqual(Tuple[T, T][int], Tuple[int, int]) 859 self.assertEqual(typing.Iterable[Tuple[T, T]][T], typing.Iterable[Tuple[T, T]]) 860 with self.assertRaises(TypeError): 861 Tuple[T, int][()] 862 with self.assertRaises(TypeError): 863 Tuple[T, U][T, ...] 864 865 self.assertEqual(Union[T, int][int], int) 866 self.assertEqual(Union[T, U][int, Union[int, str]], Union[int, str]) 867 class Base: ... 868 class Derived(Base): ... 869 self.assertEqual(Union[T, Base][Derived], Base) 870 with self.assertRaises(TypeError): 871 Union[T, int][1] 872 873 self.assertEqual(Callable[[T], T][KT], Callable[[KT], KT]) 874 self.assertEqual(Callable[..., List[T]][int], Callable[..., List[int]]) 875 with self.assertRaises(TypeError): 876 Callable[[T], U][..., int] 877 with self.assertRaises(TypeError): 878 Callable[[T], U][[], int] 879 880 def test_extended_generic_rules_repr(self): 881 T = TypeVar('T') 882 self.assertEqual(repr(Union[Tuple, Callable]).replace('typing.', ''), 883 'Union[Tuple, Callable]') 884 self.assertEqual(repr(Union[Tuple, Tuple[int]]).replace('typing.', ''), 885 'Tuple') 886 self.assertEqual(repr(Callable[..., Optional[T]][int]).replace('typing.', ''), 887 'Callable[..., Union[int, NoneType]]') 888 self.assertEqual(repr(Callable[[], List[T]][int]).replace('typing.', ''), 889 'Callable[[], List[int]]') 890 891 def test_generic_forward_ref(self): 892 def foobar(x: List[List['CC']]): ... 893 class CC: ... 894 self.assertEqual( 895 get_type_hints(foobar, globals(), locals()), 896 {'x': List[List[CC]]} 897 ) 898 T = TypeVar('T') 899 AT = Tuple[T, ...] 900 def barfoo(x: AT): ... 901 self.assertIs(get_type_hints(barfoo, globals(), locals())['x'], AT) 902 CT = Callable[..., List[T]] 903 def barfoo2(x: CT): ... 904 self.assertIs(get_type_hints(barfoo2, globals(), locals())['x'], CT) 905 906 def test_extended_generic_rules_subclassing(self): 907 class T1(Tuple[T, KT]): ... 908 class T2(Tuple[T, ...]): ... 909 class C1(Callable[[T], T]): ... 910 class C2(Callable[..., int]): 911 def __call__(self): 912 return None 913 914 self.assertEqual(T1.__parameters__, (T, KT)) 915 self.assertEqual(T1[int, str].__args__, (int, str)) 916 self.assertEqual(T1[int, T].__origin__, T1) 917 918 self.assertEqual(T2.__parameters__, (T,)) 919 with self.assertRaises(TypeError): 920 T1[int] 921 with self.assertRaises(TypeError): 922 T2[int, str] 923 924 self.assertEqual(repr(C1[int]).split('.')[-1], 'C1[int]') 925 self.assertEqual(C2.__parameters__, ()) 926 self.assertIsInstance(C2(), collections_abc.Callable) 927 self.assertIsSubclass(C2, collections_abc.Callable) 928 self.assertIsSubclass(C1, collections_abc.Callable) 929 self.assertIsInstance(T1(), tuple) 930 self.assertIsSubclass(T2, tuple) 931 self.assertIsSubclass(Tuple[int, ...], typing.Sequence) 932 self.assertIsSubclass(Tuple[int, ...], typing.Iterable) 933 934 def test_fail_with_bare_union(self): 935 with self.assertRaises(TypeError): 936 List[Union] 937 with self.assertRaises(TypeError): 938 Tuple[Optional] 939 with self.assertRaises(TypeError): 940 ClassVar[ClassVar] 941 with self.assertRaises(TypeError): 942 List[ClassVar[int]] 943 944 def test_fail_with_bare_generic(self): 945 T = TypeVar('T') 946 with self.assertRaises(TypeError): 947 List[Generic] 948 with self.assertRaises(TypeError): 949 Tuple[Generic[T]] 950 with self.assertRaises(TypeError): 951 List[typing._Protocol] 952 with self.assertRaises(TypeError): 953 isinstance(1, Generic) 954 955 def test_type_erasure_special(self): 956 T = TypeVar('T') 957 # this is the only test that checks type caching 958 self.clear_caches() 959 class MyTup(Tuple[T, T]): ... 960 self.assertIs(MyTup[int]().__class__, MyTup) 961 self.assertIs(MyTup[int]().__orig_class__, MyTup[int]) 962 class MyCall(Callable[..., T]): 963 def __call__(self): return None 964 self.assertIs(MyCall[T]().__class__, MyCall) 965 self.assertIs(MyCall[T]().__orig_class__, MyCall[T]) 966 class MyDict(typing.Dict[T, T]): ... 967 self.assertIs(MyDict[int]().__class__, MyDict) 968 self.assertIs(MyDict[int]().__orig_class__, MyDict[int]) 969 class MyDef(typing.DefaultDict[str, T]): ... 970 self.assertIs(MyDef[int]().__class__, MyDef) 971 self.assertIs(MyDef[int]().__orig_class__, MyDef[int]) 972 # ChainMap was added in 3.3 973 if sys.version_info >= (3, 3): 974 class MyChain(typing.ChainMap[str, T]): ... 975 self.assertIs(MyChain[int]().__class__, MyChain) 976 self.assertIs(MyChain[int]().__orig_class__, MyChain[int]) 977 978 def test_all_repr_eq_any(self): 979 objs = (getattr(typing, el) for el in typing.__all__) 980 for obj in objs: 981 self.assertNotEqual(repr(obj), '') 982 self.assertEqual(obj, obj) 983 if getattr(obj, '__parameters__', None) and len(obj.__parameters__) == 1: 984 self.assertEqual(obj[Any].__args__, (Any,)) 985 if isinstance(obj, type): 986 for base in obj.__mro__: 987 self.assertNotEqual(repr(base), '') 988 self.assertEqual(base, base) 989 990 def test_substitution_helper(self): 991 T = TypeVar('T') 992 KT = TypeVar('KT') 993 VT = TypeVar('VT') 994 class Map(Generic[KT, VT]): 995 def meth(self, k: KT, v: VT): ... 996 StrMap = Map[str, T] 997 obj = StrMap[int]() 998 999 new_args = typing._subs_tree(obj.__orig_class__) 1000 new_annots = {k: typing._replace_arg(v, type(obj).__parameters__, new_args) 1001 for k, v in obj.meth.__annotations__.items()} 1002 1003 self.assertEqual(new_annots, {'k': str, 'v': int}) 1004 1005 def test_pickle(self): 1006 global C # pickle wants to reference the class by name 1007 T = TypeVar('T') 1008 1009 class B(Generic[T]): 1010 pass 1011 1012 class C(B[int]): 1013 pass 1014 1015 c = C() 1016 c.foo = 42 1017 c.bar = 'abc' 1018 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 1019 z = pickle.dumps(c, proto) 1020 x = pickle.loads(z) 1021 self.assertEqual(x.foo, 42) 1022 self.assertEqual(x.bar, 'abc') 1023 self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) 1024 simples = [Any, Union, Tuple, Callable, ClassVar, List, typing.Iterable] 1025 for s in simples: 1026 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 1027 z = pickle.dumps(s, proto) 1028 x = pickle.loads(z) 1029 self.assertEqual(s, x) 1030 1031 def test_copy_and_deepcopy(self): 1032 T = TypeVar('T') 1033 class Node(Generic[T]): ... 1034 things = [Union[T, int], Tuple[T, int], Callable[..., T], Callable[[int], int], 1035 Tuple[Any, Any], Node[T], Node[int], Node[Any], typing.Iterable[T], 1036 typing.Iterable[Any], typing.Iterable[int], typing.Dict[int, str], 1037 typing.Dict[T, Any], ClassVar[int], ClassVar[List[T]], Tuple['T', 'T'], 1038 Union['T', int], List['T'], typing.Mapping['T', int]] 1039 for t in things + [Any]: 1040 self.assertEqual(t, copy(t)) 1041 self.assertEqual(t, deepcopy(t)) 1042 1043 def test_weakref_all(self): 1044 T = TypeVar('T') 1045 things = [Any, Union[T, int], Callable[..., T], Tuple[Any, Any], 1046 Optional[List[int]], typing.Mapping[int, str], 1047 typing.re.Match[bytes], typing.Iterable['whatever']] 1048 for t in things: 1049 self.assertEqual(weakref.ref(t)(), t) 1050 1051 def test_parameterized_slots(self): 1052 T = TypeVar('T') 1053 class C(Generic[T]): 1054 __slots__ = ('potato',) 1055 1056 c = C() 1057 c_int = C[int]() 1058 self.assertEqual(C.__slots__, C[str].__slots__) 1059 1060 c.potato = 0 1061 c_int.potato = 0 1062 with self.assertRaises(AttributeError): 1063 c.tomato = 0 1064 with self.assertRaises(AttributeError): 1065 c_int.tomato = 0 1066 1067 def foo(x: C['C']): ... 1068 self.assertEqual(get_type_hints(foo, globals(), locals())['x'], C[C]) 1069 self.assertEqual(get_type_hints(foo, globals(), locals())['x'].__slots__, 1070 C.__slots__) 1071 self.assertEqual(copy(C[int]), deepcopy(C[int])) 1072 1073 def test_parameterized_slots_dict(self): 1074 T = TypeVar('T') 1075 class D(Generic[T]): 1076 __slots__ = {'banana': 42} 1077 1078 d = D() 1079 d_int = D[int]() 1080 self.assertEqual(D.__slots__, D[str].__slots__) 1081 1082 d.banana = 'yes' 1083 d_int.banana = 'yes' 1084 with self.assertRaises(AttributeError): 1085 d.foobar = 'no' 1086 with self.assertRaises(AttributeError): 1087 d_int.foobar = 'no' 1088 1089 def test_errors(self): 1090 with self.assertRaises(TypeError): 1091 B = SimpleMapping[XK, Any] 1092 1093 class C(Generic[B]): 1094 pass 1095 1096 def test_repr_2(self): 1097 PY32 = sys.version_info[:2] < (3, 3) 1098 1099 class C(Generic[T]): 1100 pass 1101 1102 self.assertEqual(C.__module__, __name__) 1103 if not PY32: 1104 self.assertEqual(C.__qualname__, 1105 'GenericTests.test_repr_2.<locals>.C') 1106 self.assertEqual(repr(C).split('.')[-1], 'C') 1107 X = C[int] 1108 self.assertEqual(X.__module__, __name__) 1109 if not PY32: 1110 self.assertTrue(X.__qualname__.endswith('.<locals>.C')) 1111 self.assertEqual(repr(X).split('.')[-1], 'C[int]') 1112 1113 class Y(C[int]): 1114 pass 1115 1116 self.assertEqual(Y.__module__, __name__) 1117 if not PY32: 1118 self.assertEqual(Y.__qualname__, 1119 'GenericTests.test_repr_2.<locals>.Y') 1120 self.assertEqual(repr(Y).split('.')[-1], 'Y') 1121 1122 def test_eq_1(self): 1123 self.assertEqual(Generic, Generic) 1124 self.assertEqual(Generic[T], Generic[T]) 1125 self.assertNotEqual(Generic[KT], Generic[VT]) 1126 1127 def test_eq_2(self): 1128 1129 class A(Generic[T]): 1130 pass 1131 1132 class B(Generic[T]): 1133 pass 1134 1135 self.assertEqual(A, A) 1136 self.assertNotEqual(A, B) 1137 self.assertEqual(A[T], A[T]) 1138 self.assertNotEqual(A[T], B[T]) 1139 1140 def test_multiple_inheritance(self): 1141 1142 class A(Generic[T, VT]): 1143 pass 1144 1145 class B(Generic[KT, T]): 1146 pass 1147 1148 class C(A[T, VT], Generic[VT, T, KT], B[KT, T]): 1149 pass 1150 1151 self.assertEqual(C.__parameters__, (VT, T, KT)) 1152 1153 def test_nested(self): 1154 1155 G = Generic 1156 1157 class Visitor(G[T]): 1158 1159 a = None 1160 1161 def set(self, a: T): 1162 self.a = a 1163 1164 def get(self): 1165 return self.a 1166 1167 def visit(self) -> T: 1168 return self.a 1169 1170 V = Visitor[typing.List[int]] 1171 1172 class IntListVisitor(V): 1173 1174 def append(self, x: int): 1175 self.a.append(x) 1176 1177 a = IntListVisitor() 1178 a.set([]) 1179 a.append(1) 1180 a.append(42) 1181 self.assertEqual(a.get(), [1, 42]) 1182 1183 def test_type_erasure(self): 1184 T = TypeVar('T') 1185 1186 class Node(Generic[T]): 1187 def __init__(self, label: T, 1188 left: 'Node[T]' = None, 1189 right: 'Node[T]' = None): 1190 self.label = label # type: T 1191 self.left = left # type: Optional[Node[T]] 1192 self.right = right # type: Optional[Node[T]] 1193 1194 def foo(x: T): 1195 a = Node(x) 1196 b = Node[T](x) 1197 c = Node[Any](x) 1198 self.assertIs(type(a), Node) 1199 self.assertIs(type(b), Node) 1200 self.assertIs(type(c), Node) 1201 self.assertEqual(a.label, x) 1202 self.assertEqual(b.label, x) 1203 self.assertEqual(c.label, x) 1204 1205 foo(42) 1206 1207 def test_implicit_any(self): 1208 T = TypeVar('T') 1209 1210 class C(Generic[T]): 1211 pass 1212 1213 class D(C): 1214 pass 1215 1216 self.assertEqual(D.__parameters__, ()) 1217 1218 with self.assertRaises(Exception): 1219 D[int] 1220 with self.assertRaises(Exception): 1221 D[Any] 1222 with self.assertRaises(Exception): 1223 D[T] 1224 1225 1226class ClassVarTests(BaseTestCase): 1227 1228 def test_basics(self): 1229 with self.assertRaises(TypeError): 1230 ClassVar[1] 1231 with self.assertRaises(TypeError): 1232 ClassVar[int, str] 1233 with self.assertRaises(TypeError): 1234 ClassVar[int][str] 1235 1236 def test_repr(self): 1237 self.assertEqual(repr(ClassVar), 'typing.ClassVar') 1238 cv = ClassVar[int] 1239 self.assertEqual(repr(cv), 'typing.ClassVar[int]') 1240 cv = ClassVar[Employee] 1241 self.assertEqual(repr(cv), 'typing.ClassVar[%s.Employee]' % __name__) 1242 1243 def test_cannot_subclass(self): 1244 with self.assertRaises(TypeError): 1245 class C(type(ClassVar)): 1246 pass 1247 with self.assertRaises(TypeError): 1248 class C(type(ClassVar[int])): 1249 pass 1250 1251 def test_cannot_init(self): 1252 with self.assertRaises(TypeError): 1253 ClassVar() 1254 with self.assertRaises(TypeError): 1255 type(ClassVar)() 1256 with self.assertRaises(TypeError): 1257 type(ClassVar[Optional[int]])() 1258 1259 def test_no_isinstance(self): 1260 with self.assertRaises(TypeError): 1261 isinstance(1, ClassVar[int]) 1262 with self.assertRaises(TypeError): 1263 issubclass(int, ClassVar) 1264 1265 1266class CastTests(BaseTestCase): 1267 1268 def test_basics(self): 1269 self.assertEqual(cast(int, 42), 42) 1270 self.assertEqual(cast(float, 42), 42) 1271 self.assertIs(type(cast(float, 42)), int) 1272 self.assertEqual(cast(Any, 42), 42) 1273 self.assertEqual(cast(list, 42), 42) 1274 self.assertEqual(cast(Union[str, float], 42), 42) 1275 self.assertEqual(cast(AnyStr, 42), 42) 1276 self.assertEqual(cast(None, 42), 42) 1277 1278 def test_errors(self): 1279 # Bogus calls are not expected to fail. 1280 cast(42, 42) 1281 cast('hello', 42) 1282 1283 1284class ForwardRefTests(BaseTestCase): 1285 1286 def test_basics(self): 1287 1288 class Node(Generic[T]): 1289 1290 def __init__(self, label: T): 1291 self.label = label 1292 self.left = self.right = None 1293 1294 def add_both(self, 1295 left: 'Optional[Node[T]]', 1296 right: 'Node[T]' = None, 1297 stuff: int = None, 1298 blah=None): 1299 self.left = left 1300 self.right = right 1301 1302 def add_left(self, node: Optional['Node[T]']): 1303 self.add_both(node, None) 1304 1305 def add_right(self, node: 'Node[T]' = None): 1306 self.add_both(None, node) 1307 1308 t = Node[int] 1309 both_hints = get_type_hints(t.add_both, globals(), locals()) 1310 self.assertEqual(both_hints['left'], Optional[Node[T]]) 1311 self.assertEqual(both_hints['right'], Optional[Node[T]]) 1312 self.assertEqual(both_hints['left'], both_hints['right']) 1313 self.assertEqual(both_hints['stuff'], Optional[int]) 1314 self.assertNotIn('blah', both_hints) 1315 1316 left_hints = get_type_hints(t.add_left, globals(), locals()) 1317 self.assertEqual(left_hints['node'], Optional[Node[T]]) 1318 1319 right_hints = get_type_hints(t.add_right, globals(), locals()) 1320 self.assertEqual(right_hints['node'], Optional[Node[T]]) 1321 1322 def test_forwardref_instance_type_error(self): 1323 fr = typing._ForwardRef('int') 1324 with self.assertRaises(TypeError): 1325 isinstance(42, fr) 1326 1327 def test_forwardref_subclass_type_error(self): 1328 fr = typing._ForwardRef('int') 1329 with self.assertRaises(TypeError): 1330 issubclass(int, fr) 1331 1332 def test_forward_equality(self): 1333 fr = typing._ForwardRef('int') 1334 self.assertEqual(fr, typing._ForwardRef('int')) 1335 self.assertNotEqual(List['int'], List[int]) 1336 1337 def test_forward_repr(self): 1338 self.assertEqual(repr(List['int']), "typing.List[_ForwardRef('int')]") 1339 1340 def test_union_forward(self): 1341 1342 def foo(a: Union['T']): 1343 pass 1344 1345 self.assertEqual(get_type_hints(foo, globals(), locals()), 1346 {'a': Union[T]}) 1347 1348 def test_tuple_forward(self): 1349 1350 def foo(a: Tuple['T']): 1351 pass 1352 1353 self.assertEqual(get_type_hints(foo, globals(), locals()), 1354 {'a': Tuple[T]}) 1355 1356 def test_callable_forward(self): 1357 1358 def foo(a: Callable[['T'], 'T']): 1359 pass 1360 1361 self.assertEqual(get_type_hints(foo, globals(), locals()), 1362 {'a': Callable[[T], T]}) 1363 1364 def test_callable_with_ellipsis_forward(self): 1365 1366 def foo(a: 'Callable[..., T]'): 1367 pass 1368 1369 self.assertEqual(get_type_hints(foo, globals(), locals()), 1370 {'a': Callable[..., T]}) 1371 1372 def test_syntax_error(self): 1373 1374 with self.assertRaises(SyntaxError): 1375 Generic['/T'] 1376 1377 def test_delayed_syntax_error(self): 1378 1379 def foo(a: 'Node[T'): 1380 pass 1381 1382 with self.assertRaises(SyntaxError): 1383 get_type_hints(foo) 1384 1385 def test_type_error(self): 1386 1387 def foo(a: Tuple['42']): 1388 pass 1389 1390 with self.assertRaises(TypeError): 1391 get_type_hints(foo) 1392 1393 def test_name_error(self): 1394 1395 def foo(a: 'Noode[T]'): 1396 pass 1397 1398 with self.assertRaises(NameError): 1399 get_type_hints(foo, locals()) 1400 1401 def test_no_type_check(self): 1402 1403 @no_type_check 1404 def foo(a: 'whatevers') -> {}: 1405 pass 1406 1407 th = get_type_hints(foo) 1408 self.assertEqual(th, {}) 1409 1410 def test_no_type_check_class(self): 1411 1412 @no_type_check 1413 class C: 1414 def foo(a: 'whatevers') -> {}: 1415 pass 1416 1417 cth = get_type_hints(C.foo) 1418 self.assertEqual(cth, {}) 1419 ith = get_type_hints(C().foo) 1420 self.assertEqual(ith, {}) 1421 1422 def test_no_type_check_no_bases(self): 1423 class C: 1424 def meth(self, x: int): ... 1425 @no_type_check 1426 class D(C): 1427 c = C 1428 # verify that @no_type_check never affects bases 1429 self.assertEqual(get_type_hints(C.meth), {'x': int}) 1430 1431 def test_meta_no_type_check(self): 1432 1433 @no_type_check_decorator 1434 def magic_decorator(deco): 1435 return deco 1436 1437 self.assertEqual(magic_decorator.__name__, 'magic_decorator') 1438 1439 @magic_decorator 1440 def foo(a: 'whatevers') -> {}: 1441 pass 1442 1443 @magic_decorator 1444 class C: 1445 def foo(a: 'whatevers') -> {}: 1446 pass 1447 1448 self.assertEqual(foo.__name__, 'foo') 1449 th = get_type_hints(foo) 1450 self.assertEqual(th, {}) 1451 cth = get_type_hints(C.foo) 1452 self.assertEqual(cth, {}) 1453 ith = get_type_hints(C().foo) 1454 self.assertEqual(ith, {}) 1455 1456 def test_default_globals(self): 1457 code = ("class C:\n" 1458 " def foo(self, a: 'C') -> 'D': pass\n" 1459 "class D:\n" 1460 " def bar(self, b: 'D') -> C: pass\n" 1461 ) 1462 ns = {} 1463 exec(code, ns) 1464 hints = get_type_hints(ns['C'].foo) 1465 self.assertEqual(hints, {'a': ns['C'], 'return': ns['D']}) 1466 1467 1468class OverloadTests(BaseTestCase): 1469 1470 def test_overload_fails(self): 1471 from typing import overload 1472 1473 with self.assertRaises(RuntimeError): 1474 1475 @overload 1476 def blah(): 1477 pass 1478 1479 blah() 1480 1481 def test_overload_succeeds(self): 1482 from typing import overload 1483 1484 @overload 1485 def blah(): 1486 pass 1487 1488 def blah(): 1489 pass 1490 1491 blah() 1492 1493 1494ASYNCIO = sys.version_info[:2] >= (3, 5) 1495 1496ASYNCIO_TESTS = """ 1497import asyncio 1498 1499T_a = TypeVar('T_a') 1500 1501class AwaitableWrapper(typing.Awaitable[T_a]): 1502 1503 def __init__(self, value): 1504 self.value = value 1505 1506 def __await__(self) -> typing.Iterator[T_a]: 1507 yield 1508 return self.value 1509 1510class AsyncIteratorWrapper(typing.AsyncIterator[T_a]): 1511 1512 def __init__(self, value: typing.Iterable[T_a]): 1513 self.value = value 1514 1515 def __aiter__(self) -> typing.AsyncIterator[T_a]: 1516 return self 1517 1518 @asyncio.coroutine 1519 def __anext__(self) -> T_a: 1520 data = yield from self.value 1521 if data: 1522 return data 1523 else: 1524 raise StopAsyncIteration 1525""" 1526 1527if ASYNCIO: 1528 try: 1529 exec(ASYNCIO_TESTS) 1530 except ImportError: 1531 ASYNCIO = False 1532else: 1533 # fake names for the sake of static analysis 1534 asyncio = None 1535 AwaitableWrapper = AsyncIteratorWrapper = object 1536 1537PY36 = sys.version_info[:2] >= (3, 6) 1538 1539PY36_TESTS = """ 1540from test import ann_module, ann_module2, ann_module3 1541 1542class A: 1543 y: float 1544class B(A): 1545 x: ClassVar[Optional['B']] = None 1546 y: int 1547 b: int 1548class CSub(B): 1549 z: ClassVar['CSub'] = B() 1550class G(Generic[T]): 1551 lst: ClassVar[List[T]] = [] 1552 1553class NoneAndForward: 1554 parent: 'NoneAndForward' 1555 meaning: None 1556 1557class CoolEmployee(NamedTuple): 1558 name: str 1559 cool: int 1560 1561class CoolEmployeeWithDefault(NamedTuple): 1562 name: str 1563 cool: int = 0 1564 1565class XMeth(NamedTuple): 1566 x: int 1567 def double(self): 1568 return 2 * self.x 1569 1570class XRepr(NamedTuple): 1571 x: int 1572 y: int = 1 1573 def __str__(self): 1574 return f'{self.x} -> {self.y}' 1575 def __add__(self, other): 1576 return 0 1577""" 1578 1579if PY36: 1580 exec(PY36_TESTS) 1581else: 1582 # fake names for the sake of static analysis 1583 ann_module = ann_module2 = ann_module3 = None 1584 A = B = CSub = G = CoolEmployee = CoolEmployeeWithDefault = object 1585 XMeth = XRepr = NoneAndForward = object 1586 1587gth = get_type_hints 1588 1589 1590class GetTypeHintTests(BaseTestCase): 1591 def test_get_type_hints_from_various_objects(self): 1592 # For invalid objects should fail with TypeError (not AttributeError etc). 1593 with self.assertRaises(TypeError): 1594 gth(123) 1595 with self.assertRaises(TypeError): 1596 gth('abc') 1597 with self.assertRaises(TypeError): 1598 gth(None) 1599 1600 @skipUnless(PY36, 'Python 3.6 required') 1601 def test_get_type_hints_modules(self): 1602 ann_module_type_hints = {1: 2, 'f': Tuple[int, int], 'x': int, 'y': str} 1603 self.assertEqual(gth(ann_module), ann_module_type_hints) 1604 self.assertEqual(gth(ann_module2), {}) 1605 self.assertEqual(gth(ann_module3), {}) 1606 1607 @skipUnless(PY36, 'Python 3.6 required') 1608 def test_get_type_hints_classes(self): 1609 self.assertEqual(gth(ann_module.C, ann_module.__dict__), 1610 {'y': Optional[ann_module.C]}) 1611 self.assertIsInstance(gth(ann_module.j_class), dict) 1612 self.assertEqual(gth(ann_module.M), {'123': 123, 'o': type}) 1613 self.assertEqual(gth(ann_module.D), 1614 {'j': str, 'k': str, 'y': Optional[ann_module.C]}) 1615 self.assertEqual(gth(ann_module.Y), {'z': int}) 1616 self.assertEqual(gth(ann_module.h_class), 1617 {'y': Optional[ann_module.C]}) 1618 self.assertEqual(gth(ann_module.S), {'x': str, 'y': str}) 1619 self.assertEqual(gth(ann_module.foo), {'x': int}) 1620 self.assertEqual(gth(NoneAndForward, globals()), 1621 {'parent': NoneAndForward, 'meaning': type(None)}) 1622 1623 @skipUnless(PY36, 'Python 3.6 required') 1624 def test_respect_no_type_check(self): 1625 @no_type_check 1626 class NoTpCheck: 1627 class Inn: 1628 def __init__(self, x: 'not a type'): ... 1629 self.assertTrue(NoTpCheck.__no_type_check__) 1630 self.assertTrue(NoTpCheck.Inn.__init__.__no_type_check__) 1631 self.assertEqual(gth(ann_module2.NTC.meth), {}) 1632 class ABase(Generic[T]): 1633 def meth(x: int): ... 1634 @no_type_check 1635 class Der(ABase): ... 1636 self.assertEqual(gth(ABase.meth), {'x': int}) 1637 1638 def test_get_type_hints_for_builtins(self): 1639 # Should not fail for built-in classes and functions. 1640 self.assertEqual(gth(int), {}) 1641 self.assertEqual(gth(type), {}) 1642 self.assertEqual(gth(dir), {}) 1643 self.assertEqual(gth(len), {}) 1644 self.assertEqual(gth(object.__str__), {}) 1645 self.assertEqual(gth(object().__str__), {}) 1646 self.assertEqual(gth(str.join), {}) 1647 1648 def test_previous_behavior(self): 1649 def testf(x, y): ... 1650 testf.__annotations__['x'] = 'int' 1651 self.assertEqual(gth(testf), {'x': int}) 1652 def testg(x: None): ... 1653 self.assertEqual(gth(testg), {'x': type(None)}) 1654 1655 def test_get_type_hints_for_object_with_annotations(self): 1656 class A: ... 1657 class B: ... 1658 b = B() 1659 b.__annotations__ = {'x': 'A'} 1660 self.assertEqual(gth(b, locals()), {'x': A}) 1661 1662 @skipUnless(PY36, 'Python 3.6 required') 1663 def test_get_type_hints_ClassVar(self): 1664 self.assertEqual(gth(ann_module2.CV, ann_module2.__dict__), 1665 {'var': typing.ClassVar[ann_module2.CV]}) 1666 self.assertEqual(gth(B, globals()), 1667 {'y': int, 'x': ClassVar[Optional[B]], 'b': int}) 1668 self.assertEqual(gth(CSub, globals()), 1669 {'z': ClassVar[CSub], 'y': int, 'b': int, 1670 'x': ClassVar[Optional[B]]}) 1671 self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) 1672 1673 1674class CollectionsAbcTests(BaseTestCase): 1675 1676 def test_hashable(self): 1677 self.assertIsInstance(42, typing.Hashable) 1678 self.assertNotIsInstance([], typing.Hashable) 1679 1680 def test_iterable(self): 1681 self.assertIsInstance([], typing.Iterable) 1682 # Due to ABC caching, the second time takes a separate code 1683 # path and could fail. So call this a few times. 1684 self.assertIsInstance([], typing.Iterable) 1685 self.assertIsInstance([], typing.Iterable) 1686 self.assertNotIsInstance(42, typing.Iterable) 1687 # Just in case, also test issubclass() a few times. 1688 self.assertIsSubclass(list, typing.Iterable) 1689 self.assertIsSubclass(list, typing.Iterable) 1690 1691 def test_iterator(self): 1692 it = iter([]) 1693 self.assertIsInstance(it, typing.Iterator) 1694 self.assertNotIsInstance(42, typing.Iterator) 1695 1696 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 1697 def test_awaitable(self): 1698 ns = {} 1699 exec( 1700 "async def foo() -> typing.Awaitable[int]:\n" 1701 " return await AwaitableWrapper(42)\n", 1702 globals(), ns) 1703 foo = ns['foo'] 1704 g = foo() 1705 self.assertIsInstance(g, typing.Awaitable) 1706 self.assertNotIsInstance(foo, typing.Awaitable) 1707 g.send(None) # Run foo() till completion, to avoid warning. 1708 1709 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 1710 def test_coroutine(self): 1711 ns = {} 1712 exec( 1713 "async def foo():\n" 1714 " return\n", 1715 globals(), ns) 1716 foo = ns['foo'] 1717 g = foo() 1718 self.assertIsInstance(g, typing.Coroutine) 1719 with self.assertRaises(TypeError): 1720 isinstance(g, typing.Coroutine[int]) 1721 self.assertNotIsInstance(foo, typing.Coroutine) 1722 try: 1723 g.send(None) 1724 except StopIteration: 1725 pass 1726 1727 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 1728 def test_async_iterable(self): 1729 base_it = range(10) # type: Iterator[int] 1730 it = AsyncIteratorWrapper(base_it) 1731 self.assertIsInstance(it, typing.AsyncIterable) 1732 self.assertIsInstance(it, typing.AsyncIterable) 1733 self.assertNotIsInstance(42, typing.AsyncIterable) 1734 1735 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 1736 def test_async_iterator(self): 1737 base_it = range(10) # type: Iterator[int] 1738 it = AsyncIteratorWrapper(base_it) 1739 self.assertIsInstance(it, typing.AsyncIterator) 1740 self.assertNotIsInstance(42, typing.AsyncIterator) 1741 1742 def test_sized(self): 1743 self.assertIsInstance([], typing.Sized) 1744 self.assertNotIsInstance(42, typing.Sized) 1745 1746 def test_container(self): 1747 self.assertIsInstance([], typing.Container) 1748 self.assertNotIsInstance(42, typing.Container) 1749 1750 def test_collection(self): 1751 if hasattr(typing, 'Collection'): 1752 self.assertIsInstance(tuple(), typing.Collection) 1753 self.assertIsInstance(frozenset(), typing.Collection) 1754 self.assertIsSubclass(dict, typing.Collection) 1755 self.assertNotIsInstance(42, typing.Collection) 1756 1757 def test_abstractset(self): 1758 self.assertIsInstance(set(), typing.AbstractSet) 1759 self.assertNotIsInstance(42, typing.AbstractSet) 1760 1761 def test_mutableset(self): 1762 self.assertIsInstance(set(), typing.MutableSet) 1763 self.assertNotIsInstance(frozenset(), typing.MutableSet) 1764 1765 def test_mapping(self): 1766 self.assertIsInstance({}, typing.Mapping) 1767 self.assertNotIsInstance(42, typing.Mapping) 1768 1769 def test_mutablemapping(self): 1770 self.assertIsInstance({}, typing.MutableMapping) 1771 self.assertNotIsInstance(42, typing.MutableMapping) 1772 1773 def test_sequence(self): 1774 self.assertIsInstance([], typing.Sequence) 1775 self.assertNotIsInstance(42, typing.Sequence) 1776 1777 def test_mutablesequence(self): 1778 self.assertIsInstance([], typing.MutableSequence) 1779 self.assertNotIsInstance((), typing.MutableSequence) 1780 1781 def test_bytestring(self): 1782 self.assertIsInstance(b'', typing.ByteString) 1783 self.assertIsInstance(bytearray(b''), typing.ByteString) 1784 1785 def test_list(self): 1786 self.assertIsSubclass(list, typing.List) 1787 1788 def test_deque(self): 1789 self.assertIsSubclass(collections.deque, typing.Deque) 1790 class MyDeque(typing.Deque[int]): ... 1791 self.assertIsInstance(MyDeque(), collections.deque) 1792 1793 def test_counter(self): 1794 self.assertIsSubclass(collections.Counter, typing.Counter) 1795 1796 def test_set(self): 1797 self.assertIsSubclass(set, typing.Set) 1798 self.assertNotIsSubclass(frozenset, typing.Set) 1799 1800 def test_frozenset(self): 1801 self.assertIsSubclass(frozenset, typing.FrozenSet) 1802 self.assertNotIsSubclass(set, typing.FrozenSet) 1803 1804 def test_dict(self): 1805 self.assertIsSubclass(dict, typing.Dict) 1806 1807 def test_no_list_instantiation(self): 1808 with self.assertRaises(TypeError): 1809 typing.List() 1810 with self.assertRaises(TypeError): 1811 typing.List[T]() 1812 with self.assertRaises(TypeError): 1813 typing.List[int]() 1814 1815 def test_list_subclass(self): 1816 1817 class MyList(typing.List[int]): 1818 pass 1819 1820 a = MyList() 1821 self.assertIsInstance(a, MyList) 1822 self.assertIsInstance(a, typing.Sequence) 1823 1824 self.assertIsSubclass(MyList, list) 1825 self.assertNotIsSubclass(list, MyList) 1826 1827 def test_no_dict_instantiation(self): 1828 with self.assertRaises(TypeError): 1829 typing.Dict() 1830 with self.assertRaises(TypeError): 1831 typing.Dict[KT, VT]() 1832 with self.assertRaises(TypeError): 1833 typing.Dict[str, int]() 1834 1835 def test_dict_subclass(self): 1836 1837 class MyDict(typing.Dict[str, int]): 1838 pass 1839 1840 d = MyDict() 1841 self.assertIsInstance(d, MyDict) 1842 self.assertIsInstance(d, typing.MutableMapping) 1843 1844 self.assertIsSubclass(MyDict, dict) 1845 self.assertNotIsSubclass(dict, MyDict) 1846 1847 def test_defaultdict_instantiation(self): 1848 self.assertIs(type(typing.DefaultDict()), collections.defaultdict) 1849 self.assertIs(type(typing.DefaultDict[KT, VT]()), collections.defaultdict) 1850 self.assertIs(type(typing.DefaultDict[str, int]()), collections.defaultdict) 1851 1852 def test_defaultdict_subclass(self): 1853 1854 class MyDefDict(typing.DefaultDict[str, int]): 1855 pass 1856 1857 dd = MyDefDict() 1858 self.assertIsInstance(dd, MyDefDict) 1859 1860 self.assertIsSubclass(MyDefDict, collections.defaultdict) 1861 self.assertNotIsSubclass(collections.defaultdict, MyDefDict) 1862 1863 @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') 1864 def test_chainmap_instantiation(self): 1865 self.assertIs(type(typing.ChainMap()), collections.ChainMap) 1866 self.assertIs(type(typing.ChainMap[KT, VT]()), collections.ChainMap) 1867 self.assertIs(type(typing.ChainMap[str, int]()), collections.ChainMap) 1868 class CM(typing.ChainMap[KT, VT]): ... 1869 self.assertIs(type(CM[int, str]()), CM) 1870 1871 @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') 1872 def test_chainmap_subclass(self): 1873 1874 class MyChainMap(typing.ChainMap[str, int]): 1875 pass 1876 1877 cm = MyChainMap() 1878 self.assertIsInstance(cm, MyChainMap) 1879 1880 self.assertIsSubclass(MyChainMap, collections.ChainMap) 1881 self.assertNotIsSubclass(collections.ChainMap, MyChainMap) 1882 1883 def test_deque_instantiation(self): 1884 self.assertIs(type(typing.Deque()), collections.deque) 1885 self.assertIs(type(typing.Deque[T]()), collections.deque) 1886 self.assertIs(type(typing.Deque[int]()), collections.deque) 1887 class D(typing.Deque[T]): ... 1888 self.assertIs(type(D[int]()), D) 1889 1890 def test_counter_instantiation(self): 1891 self.assertIs(type(typing.Counter()), collections.Counter) 1892 self.assertIs(type(typing.Counter[T]()), collections.Counter) 1893 self.assertIs(type(typing.Counter[int]()), collections.Counter) 1894 class C(typing.Counter[T]): ... 1895 self.assertIs(type(C[int]()), C) 1896 1897 def test_counter_subclass_instantiation(self): 1898 1899 class MyCounter(typing.Counter[int]): 1900 pass 1901 1902 d = MyCounter() 1903 self.assertIsInstance(d, MyCounter) 1904 self.assertIsInstance(d, typing.Counter) 1905 self.assertIsInstance(d, collections.Counter) 1906 1907 def test_no_set_instantiation(self): 1908 with self.assertRaises(TypeError): 1909 typing.Set() 1910 with self.assertRaises(TypeError): 1911 typing.Set[T]() 1912 with self.assertRaises(TypeError): 1913 typing.Set[int]() 1914 1915 def test_set_subclass_instantiation(self): 1916 1917 class MySet(typing.Set[int]): 1918 pass 1919 1920 d = MySet() 1921 self.assertIsInstance(d, MySet) 1922 1923 def test_no_frozenset_instantiation(self): 1924 with self.assertRaises(TypeError): 1925 typing.FrozenSet() 1926 with self.assertRaises(TypeError): 1927 typing.FrozenSet[T]() 1928 with self.assertRaises(TypeError): 1929 typing.FrozenSet[int]() 1930 1931 def test_frozenset_subclass_instantiation(self): 1932 1933 class MyFrozenSet(typing.FrozenSet[int]): 1934 pass 1935 1936 d = MyFrozenSet() 1937 self.assertIsInstance(d, MyFrozenSet) 1938 1939 def test_no_tuple_instantiation(self): 1940 with self.assertRaises(TypeError): 1941 Tuple() 1942 with self.assertRaises(TypeError): 1943 Tuple[T]() 1944 with self.assertRaises(TypeError): 1945 Tuple[int]() 1946 1947 def test_generator(self): 1948 def foo(): 1949 yield 42 1950 g = foo() 1951 self.assertIsSubclass(type(g), typing.Generator) 1952 1953 def test_no_generator_instantiation(self): 1954 with self.assertRaises(TypeError): 1955 typing.Generator() 1956 with self.assertRaises(TypeError): 1957 typing.Generator[T, T, T]() 1958 with self.assertRaises(TypeError): 1959 typing.Generator[int, int, int]() 1960 1961 @skipUnless(PY36, 'Python 3.6 required') 1962 def test_async_generator(self): 1963 ns = {} 1964 exec("async def f():\n" 1965 " yield 42\n", globals(), ns) 1966 g = ns['f']() 1967 self.assertIsSubclass(type(g), typing.AsyncGenerator) 1968 1969 @skipUnless(PY36, 'Python 3.6 required') 1970 def test_no_async_generator_instantiation(self): 1971 with self.assertRaises(TypeError): 1972 typing.AsyncGenerator() 1973 with self.assertRaises(TypeError): 1974 typing.AsyncGenerator[T, T]() 1975 with self.assertRaises(TypeError): 1976 typing.AsyncGenerator[int, int]() 1977 1978 def test_subclassing(self): 1979 1980 class MMA(typing.MutableMapping): 1981 pass 1982 1983 with self.assertRaises(TypeError): # It's abstract 1984 MMA() 1985 1986 class MMC(MMA): 1987 def __getitem__(self, k): 1988 return None 1989 def __setitem__(self, k, v): 1990 pass 1991 def __delitem__(self, k): 1992 pass 1993 def __iter__(self): 1994 return iter(()) 1995 def __len__(self): 1996 return 0 1997 1998 self.assertEqual(len(MMC()), 0) 1999 assert callable(MMC.update) 2000 self.assertIsInstance(MMC(), typing.Mapping) 2001 2002 class MMB(typing.MutableMapping[KT, VT]): 2003 def __getitem__(self, k): 2004 return None 2005 def __setitem__(self, k, v): 2006 pass 2007 def __delitem__(self, k): 2008 pass 2009 def __iter__(self): 2010 return iter(()) 2011 def __len__(self): 2012 return 0 2013 2014 self.assertEqual(len(MMB()), 0) 2015 self.assertEqual(len(MMB[str, str]()), 0) 2016 self.assertEqual(len(MMB[KT, VT]()), 0) 2017 2018 self.assertNotIsSubclass(dict, MMA) 2019 self.assertNotIsSubclass(dict, MMB) 2020 2021 self.assertIsSubclass(MMA, typing.Mapping) 2022 self.assertIsSubclass(MMB, typing.Mapping) 2023 self.assertIsSubclass(MMC, typing.Mapping) 2024 2025 self.assertIsInstance(MMB[KT, VT](), typing.Mapping) 2026 self.assertIsInstance(MMB[KT, VT](), collections.Mapping) 2027 2028 self.assertIsSubclass(MMA, collections.Mapping) 2029 self.assertIsSubclass(MMB, collections.Mapping) 2030 self.assertIsSubclass(MMC, collections.Mapping) 2031 2032 self.assertIsSubclass(MMB[str, str], typing.Mapping) 2033 self.assertIsSubclass(MMC, MMA) 2034 2035 class I(typing.Iterable): ... 2036 self.assertNotIsSubclass(list, I) 2037 2038 class G(typing.Generator[int, int, int]): ... 2039 def g(): yield 0 2040 self.assertIsSubclass(G, typing.Generator) 2041 self.assertIsSubclass(G, typing.Iterable) 2042 if hasattr(collections, 'Generator'): 2043 self.assertIsSubclass(G, collections.Generator) 2044 self.assertIsSubclass(G, collections.Iterable) 2045 self.assertNotIsSubclass(type(g), G) 2046 2047 @skipUnless(PY36, 'Python 3.6 required') 2048 def test_subclassing_async_generator(self): 2049 class G(typing.AsyncGenerator[int, int]): 2050 def asend(self, value): 2051 pass 2052 def athrow(self, typ, val=None, tb=None): 2053 pass 2054 2055 ns = {} 2056 exec('async def g(): yield 0', globals(), ns) 2057 g = ns['g'] 2058 self.assertIsSubclass(G, typing.AsyncGenerator) 2059 self.assertIsSubclass(G, typing.AsyncIterable) 2060 self.assertIsSubclass(G, collections.AsyncGenerator) 2061 self.assertIsSubclass(G, collections.AsyncIterable) 2062 self.assertNotIsSubclass(type(g), G) 2063 2064 instance = G() 2065 self.assertIsInstance(instance, typing.AsyncGenerator) 2066 self.assertIsInstance(instance, typing.AsyncIterable) 2067 self.assertIsInstance(instance, collections.AsyncGenerator) 2068 self.assertIsInstance(instance, collections.AsyncIterable) 2069 self.assertNotIsInstance(type(g), G) 2070 self.assertNotIsInstance(g, G) 2071 2072 def test_subclassing_subclasshook(self): 2073 2074 class Base(typing.Iterable): 2075 @classmethod 2076 def __subclasshook__(cls, other): 2077 if other.__name__ == 'Foo': 2078 return True 2079 else: 2080 return False 2081 2082 class C(Base): ... 2083 class Foo: ... 2084 class Bar: ... 2085 self.assertIsSubclass(Foo, Base) 2086 self.assertIsSubclass(Foo, C) 2087 self.assertNotIsSubclass(Bar, C) 2088 2089 def test_subclassing_register(self): 2090 2091 class A(typing.Container): ... 2092 class B(A): ... 2093 2094 class C: ... 2095 A.register(C) 2096 self.assertIsSubclass(C, A) 2097 self.assertNotIsSubclass(C, B) 2098 2099 class D: ... 2100 B.register(D) 2101 self.assertIsSubclass(D, A) 2102 self.assertIsSubclass(D, B) 2103 2104 class M(): ... 2105 collections.MutableMapping.register(M) 2106 self.assertIsSubclass(M, typing.Mapping) 2107 2108 def test_collections_as_base(self): 2109 2110 class M(collections.Mapping): ... 2111 self.assertIsSubclass(M, typing.Mapping) 2112 self.assertIsSubclass(M, typing.Iterable) 2113 2114 class S(collections.MutableSequence): ... 2115 self.assertIsSubclass(S, typing.MutableSequence) 2116 self.assertIsSubclass(S, typing.Iterable) 2117 2118 class I(collections.Iterable): ... 2119 self.assertIsSubclass(I, typing.Iterable) 2120 2121 class A(collections.Mapping, metaclass=abc.ABCMeta): ... 2122 class B: ... 2123 A.register(B) 2124 self.assertIsSubclass(B, typing.Mapping) 2125 2126 2127class OtherABCTests(BaseTestCase): 2128 2129 @skipUnless(hasattr(typing, 'ContextManager'), 2130 'requires typing.ContextManager') 2131 def test_contextmanager(self): 2132 @contextlib.contextmanager 2133 def manager(): 2134 yield 42 2135 2136 cm = manager() 2137 self.assertIsInstance(cm, typing.ContextManager) 2138 self.assertNotIsInstance(42, typing.ContextManager) 2139 2140 2141class TypeTests(BaseTestCase): 2142 2143 def test_type_basic(self): 2144 2145 class User: pass 2146 class BasicUser(User): pass 2147 class ProUser(User): pass 2148 2149 def new_user(user_class: Type[User]) -> User: 2150 return user_class() 2151 2152 new_user(BasicUser) 2153 2154 def test_type_typevar(self): 2155 2156 class User: pass 2157 class BasicUser(User): pass 2158 class ProUser(User): pass 2159 2160 U = TypeVar('U', bound=User) 2161 2162 def new_user(user_class: Type[U]) -> U: 2163 return user_class() 2164 2165 new_user(BasicUser) 2166 2167 def test_type_optional(self): 2168 A = Optional[Type[BaseException]] 2169 2170 def foo(a: A) -> Optional[BaseException]: 2171 if a is None: 2172 return None 2173 else: 2174 return a() 2175 2176 assert isinstance(foo(KeyboardInterrupt), KeyboardInterrupt) 2177 assert foo(None) is None 2178 2179 2180class NewTypeTests(BaseTestCase): 2181 2182 def test_basic(self): 2183 UserId = NewType('UserId', int) 2184 UserName = NewType('UserName', str) 2185 self.assertIsInstance(UserId(5), int) 2186 self.assertIsInstance(UserName('Joe'), str) 2187 self.assertEqual(UserId(5) + 1, 6) 2188 2189 def test_errors(self): 2190 UserId = NewType('UserId', int) 2191 UserName = NewType('UserName', str) 2192 with self.assertRaises(TypeError): 2193 issubclass(UserId, int) 2194 with self.assertRaises(TypeError): 2195 class D(UserName): 2196 pass 2197 2198 2199class NamedTupleTests(BaseTestCase): 2200 2201 def test_basics(self): 2202 Emp = NamedTuple('Emp', [('name', str), ('id', int)]) 2203 self.assertIsSubclass(Emp, tuple) 2204 joe = Emp('Joe', 42) 2205 jim = Emp(name='Jim', id=1) 2206 self.assertIsInstance(joe, Emp) 2207 self.assertIsInstance(joe, tuple) 2208 self.assertEqual(joe.name, 'Joe') 2209 self.assertEqual(joe.id, 42) 2210 self.assertEqual(jim.name, 'Jim') 2211 self.assertEqual(jim.id, 1) 2212 self.assertEqual(Emp.__name__, 'Emp') 2213 self.assertEqual(Emp._fields, ('name', 'id')) 2214 self.assertEqual(Emp.__annotations__, 2215 collections.OrderedDict([('name', str), ('id', int)])) 2216 self.assertIs(Emp._field_types, Emp.__annotations__) 2217 2218 def test_namedtuple_pyversion(self): 2219 if sys.version_info[:2] < (3, 6): 2220 with self.assertRaises(TypeError): 2221 NamedTuple('Name', one=int, other=str) 2222 with self.assertRaises(TypeError): 2223 class NotYet(NamedTuple): 2224 whatever = 0 2225 2226 @skipUnless(PY36, 'Python 3.6 required') 2227 def test_annotation_usage(self): 2228 tim = CoolEmployee('Tim', 9000) 2229 self.assertIsInstance(tim, CoolEmployee) 2230 self.assertIsInstance(tim, tuple) 2231 self.assertEqual(tim.name, 'Tim') 2232 self.assertEqual(tim.cool, 9000) 2233 self.assertEqual(CoolEmployee.__name__, 'CoolEmployee') 2234 self.assertEqual(CoolEmployee._fields, ('name', 'cool')) 2235 self.assertEqual(CoolEmployee.__annotations__, 2236 collections.OrderedDict(name=str, cool=int)) 2237 self.assertIs(CoolEmployee._field_types, CoolEmployee.__annotations__) 2238 2239 @skipUnless(PY36, 'Python 3.6 required') 2240 def test_annotation_usage_with_default(self): 2241 jelle = CoolEmployeeWithDefault('Jelle') 2242 self.assertIsInstance(jelle, CoolEmployeeWithDefault) 2243 self.assertIsInstance(jelle, tuple) 2244 self.assertEqual(jelle.name, 'Jelle') 2245 self.assertEqual(jelle.cool, 0) 2246 cooler_employee = CoolEmployeeWithDefault('Sjoerd', 1) 2247 self.assertEqual(cooler_employee.cool, 1) 2248 2249 self.assertEqual(CoolEmployeeWithDefault.__name__, 'CoolEmployeeWithDefault') 2250 self.assertEqual(CoolEmployeeWithDefault._fields, ('name', 'cool')) 2251 self.assertEqual(CoolEmployeeWithDefault._field_types, dict(name=str, cool=int)) 2252 self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0)) 2253 2254 with self.assertRaises(TypeError): 2255 exec(""" 2256class NonDefaultAfterDefault(NamedTuple): 2257 x: int = 3 2258 y: int 2259""") 2260 2261 @skipUnless(PY36, 'Python 3.6 required') 2262 def test_annotation_usage_with_methods(self): 2263 self.assertEqual(XMeth(1).double(), 2) 2264 self.assertEqual(XMeth(42).x, XMeth(42)[0]) 2265 self.assertEqual(str(XRepr(42)), '42 -> 1') 2266 self.assertEqual(XRepr(1, 2) + XRepr(3), 0) 2267 2268 with self.assertRaises(AttributeError): 2269 exec(""" 2270class XMethBad(NamedTuple): 2271 x: int 2272 def _fields(self): 2273 return 'no chance for this' 2274""") 2275 2276 @skipUnless(PY36, 'Python 3.6 required') 2277 def test_namedtuple_keyword_usage(self): 2278 LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int) 2279 nick = LocalEmployee('Nick', 25) 2280 self.assertIsInstance(nick, tuple) 2281 self.assertEqual(nick.name, 'Nick') 2282 self.assertEqual(LocalEmployee.__name__, 'LocalEmployee') 2283 self.assertEqual(LocalEmployee._fields, ('name', 'age')) 2284 self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int)) 2285 self.assertIs(LocalEmployee._field_types, LocalEmployee.__annotations__) 2286 with self.assertRaises(TypeError): 2287 NamedTuple('Name', [('x', int)], y=str) 2288 with self.assertRaises(TypeError): 2289 NamedTuple('Name', x=1, y='a') 2290 2291 def test_pickle(self): 2292 global Emp # pickle wants to reference the class by name 2293 Emp = NamedTuple('Emp', [('name', str), ('id', int)]) 2294 jane = Emp('jane', 37) 2295 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 2296 z = pickle.dumps(jane, proto) 2297 jane2 = pickle.loads(z) 2298 self.assertEqual(jane2, jane) 2299 2300 2301class IOTests(BaseTestCase): 2302 2303 def test_io(self): 2304 2305 def stuff(a: IO) -> AnyStr: 2306 return a.readline() 2307 2308 a = stuff.__annotations__['a'] 2309 self.assertEqual(a.__parameters__, (AnyStr,)) 2310 2311 def test_textio(self): 2312 2313 def stuff(a: TextIO) -> str: 2314 return a.readline() 2315 2316 a = stuff.__annotations__['a'] 2317 self.assertEqual(a.__parameters__, ()) 2318 2319 def test_binaryio(self): 2320 2321 def stuff(a: BinaryIO) -> bytes: 2322 return a.readline() 2323 2324 a = stuff.__annotations__['a'] 2325 self.assertEqual(a.__parameters__, ()) 2326 2327 def test_io_submodule(self): 2328 from typing.io import IO, TextIO, BinaryIO, __all__, __name__ 2329 self.assertIs(IO, typing.IO) 2330 self.assertIs(TextIO, typing.TextIO) 2331 self.assertIs(BinaryIO, typing.BinaryIO) 2332 self.assertEqual(set(__all__), set(['IO', 'TextIO', 'BinaryIO'])) 2333 self.assertEqual(__name__, 'typing.io') 2334 2335 2336class RETests(BaseTestCase): 2337 # Much of this is really testing _TypeAlias. 2338 2339 def test_basics(self): 2340 pat = re.compile('[a-z]+', re.I) 2341 self.assertIsSubclass(pat.__class__, Pattern) 2342 self.assertIsSubclass(type(pat), Pattern) 2343 self.assertIsInstance(pat, Pattern) 2344 2345 mat = pat.search('12345abcde.....') 2346 self.assertIsSubclass(mat.__class__, Match) 2347 self.assertIsSubclass(type(mat), Match) 2348 self.assertIsInstance(mat, Match) 2349 2350 # these should just work 2351 Pattern[Union[str, bytes]] 2352 Match[Union[bytes, str]] 2353 2354 def test_alias_equality(self): 2355 self.assertEqual(Pattern[str], Pattern[str]) 2356 self.assertNotEqual(Pattern[str], Pattern[bytes]) 2357 self.assertNotEqual(Pattern[str], Match[str]) 2358 self.assertNotEqual(Pattern[str], str) 2359 2360 def test_errors(self): 2361 with self.assertRaises(TypeError): 2362 # Doesn't fit AnyStr. 2363 Pattern[int] 2364 with self.assertRaises(TypeError): 2365 # Can't change type vars? 2366 Match[T] 2367 m = Match[Union[str, bytes]] 2368 with self.assertRaises(TypeError): 2369 # Too complicated? 2370 m[str] 2371 with self.assertRaises(TypeError): 2372 # We don't support isinstance(). 2373 isinstance(42, Pattern[str]) 2374 with self.assertRaises(TypeError): 2375 # We don't support issubclass(). 2376 issubclass(Pattern[bytes], Pattern[str]) 2377 2378 def test_repr(self): 2379 self.assertEqual(repr(Pattern), 'Pattern[~AnyStr]') 2380 self.assertEqual(repr(Pattern[str]), 'Pattern[str]') 2381 self.assertEqual(repr(Pattern[bytes]), 'Pattern[bytes]') 2382 self.assertEqual(repr(Match), 'Match[~AnyStr]') 2383 self.assertEqual(repr(Match[str]), 'Match[str]') 2384 self.assertEqual(repr(Match[bytes]), 'Match[bytes]') 2385 2386 def test_re_submodule(self): 2387 from typing.re import Match, Pattern, __all__, __name__ 2388 self.assertIs(Match, typing.Match) 2389 self.assertIs(Pattern, typing.Pattern) 2390 self.assertEqual(set(__all__), set(['Match', 'Pattern'])) 2391 self.assertEqual(__name__, 'typing.re') 2392 2393 def test_cannot_subclass(self): 2394 with self.assertRaises(TypeError) as ex: 2395 2396 class A(typing.Match): 2397 pass 2398 2399 self.assertEqual(str(ex.exception), 2400 "Cannot subclass typing._TypeAlias") 2401 2402 2403class AllTests(BaseTestCase): 2404 """Tests for __all__.""" 2405 2406 def test_all(self): 2407 from typing import __all__ as a 2408 # Just spot-check the first and last of every category. 2409 self.assertIn('AbstractSet', a) 2410 self.assertIn('ValuesView', a) 2411 self.assertIn('cast', a) 2412 self.assertIn('overload', a) 2413 if hasattr(contextlib, 'AbstractContextManager'): 2414 self.assertIn('ContextManager', a) 2415 # Check that io and re are not exported. 2416 self.assertNotIn('io', a) 2417 self.assertNotIn('re', a) 2418 # Spot-check that stdlib modules aren't exported. 2419 self.assertNotIn('os', a) 2420 self.assertNotIn('sys', a) 2421 # Check that Text is defined. 2422 self.assertIn('Text', a) 2423 2424 2425if __name__ == '__main__': 2426 main() 2427