1import contextlib 2import collections 3import pickle 4import re 5import sys 6from unittest import TestCase, main, skipUnless, SkipTest, skip 7from copy import copy, deepcopy 8 9from typing import Any, NoReturn 10from typing import TypeVar, AnyStr 11from typing import T, KT, VT # Not in __all__. 12from typing import Union, Optional, Literal 13from typing import Tuple, List, MutableMapping 14from typing import Callable 15from typing import Generic, ClassVar, Final, final, Protocol 16from typing import cast, runtime_checkable 17from typing import get_type_hints 18from typing import get_origin, get_args 19from typing import no_type_check, no_type_check_decorator 20from typing import Type 21from typing import NewType 22from typing import NamedTuple, TypedDict 23from typing import IO, TextIO, BinaryIO 24from typing import Pattern, Match 25import abc 26import typing 27import weakref 28import types 29 30from test import mod_generics_cache 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_any_works_with_alias(self): 106 # These expressions must simply not fail. 107 typing.Match[Any] 108 typing.Pattern[Any] 109 typing.IO[Any] 110 111 112class NoReturnTests(BaseTestCase): 113 114 def test_noreturn_instance_type_error(self): 115 with self.assertRaises(TypeError): 116 isinstance(42, NoReturn) 117 118 def test_noreturn_subclass_type_error(self): 119 with self.assertRaises(TypeError): 120 issubclass(Employee, NoReturn) 121 with self.assertRaises(TypeError): 122 issubclass(NoReturn, Employee) 123 124 def test_repr(self): 125 self.assertEqual(repr(NoReturn), 'typing.NoReturn') 126 127 def test_not_generic(self): 128 with self.assertRaises(TypeError): 129 NoReturn[int] 130 131 def test_cannot_subclass(self): 132 with self.assertRaises(TypeError): 133 class A(NoReturn): 134 pass 135 with self.assertRaises(TypeError): 136 class A(type(NoReturn)): 137 pass 138 139 def test_cannot_instantiate(self): 140 with self.assertRaises(TypeError): 141 NoReturn() 142 with self.assertRaises(TypeError): 143 type(NoReturn)() 144 145 146class TypeVarTests(BaseTestCase): 147 148 def test_basic_plain(self): 149 T = TypeVar('T') 150 # T equals itself. 151 self.assertEqual(T, T) 152 # T is an instance of TypeVar 153 self.assertIsInstance(T, TypeVar) 154 155 def test_typevar_instance_type_error(self): 156 T = TypeVar('T') 157 with self.assertRaises(TypeError): 158 isinstance(42, T) 159 160 def test_typevar_subclass_type_error(self): 161 T = TypeVar('T') 162 with self.assertRaises(TypeError): 163 issubclass(int, T) 164 with self.assertRaises(TypeError): 165 issubclass(T, int) 166 167 def test_constrained_error(self): 168 with self.assertRaises(TypeError): 169 X = TypeVar('X', int) 170 X 171 172 def test_union_unique(self): 173 X = TypeVar('X') 174 Y = TypeVar('Y') 175 self.assertNotEqual(X, Y) 176 self.assertEqual(Union[X], X) 177 self.assertNotEqual(Union[X], Union[X, Y]) 178 self.assertEqual(Union[X, X], X) 179 self.assertNotEqual(Union[X, int], Union[X]) 180 self.assertNotEqual(Union[X, int], Union[int]) 181 self.assertEqual(Union[X, int].__args__, (X, int)) 182 self.assertEqual(Union[X, int].__parameters__, (X,)) 183 self.assertIs(Union[X, int].__origin__, Union) 184 185 def test_union_constrained(self): 186 A = TypeVar('A', str, bytes) 187 self.assertNotEqual(Union[A, str], Union[A]) 188 189 def test_repr(self): 190 self.assertEqual(repr(T), '~T') 191 self.assertEqual(repr(KT), '~KT') 192 self.assertEqual(repr(VT), '~VT') 193 self.assertEqual(repr(AnyStr), '~AnyStr') 194 T_co = TypeVar('T_co', covariant=True) 195 self.assertEqual(repr(T_co), '+T_co') 196 T_contra = TypeVar('T_contra', contravariant=True) 197 self.assertEqual(repr(T_contra), '-T_contra') 198 199 def test_no_redefinition(self): 200 self.assertNotEqual(TypeVar('T'), TypeVar('T')) 201 self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str)) 202 203 def test_cannot_subclass_vars(self): 204 with self.assertRaises(TypeError): 205 class V(TypeVar('T')): 206 pass 207 208 def test_cannot_subclass_var_itself(self): 209 with self.assertRaises(TypeError): 210 class V(TypeVar): 211 pass 212 213 def test_cannot_instantiate_vars(self): 214 with self.assertRaises(TypeError): 215 TypeVar('A')() 216 217 def test_bound_errors(self): 218 with self.assertRaises(TypeError): 219 TypeVar('X', bound=42) 220 with self.assertRaises(TypeError): 221 TypeVar('X', str, float, bound=Employee) 222 223 def test_missing__name__(self): 224 # See bpo-39942 225 code = ("import typing\n" 226 "T = typing.TypeVar('T')\n" 227 ) 228 exec(code, {}) 229 230 def test_no_bivariant(self): 231 with self.assertRaises(ValueError): 232 TypeVar('T', covariant=True, contravariant=True) 233 234 235class UnionTests(BaseTestCase): 236 237 def test_basics(self): 238 u = Union[int, float] 239 self.assertNotEqual(u, Union) 240 241 def test_subclass_error(self): 242 with self.assertRaises(TypeError): 243 issubclass(int, Union) 244 with self.assertRaises(TypeError): 245 issubclass(Union, int) 246 with self.assertRaises(TypeError): 247 issubclass(int, Union[int, str]) 248 with self.assertRaises(TypeError): 249 issubclass(Union[int, str], int) 250 251 def test_union_any(self): 252 u = Union[Any] 253 self.assertEqual(u, Any) 254 u1 = Union[int, Any] 255 u2 = Union[Any, int] 256 u3 = Union[Any, object] 257 self.assertEqual(u1, u2) 258 self.assertNotEqual(u1, Any) 259 self.assertNotEqual(u2, Any) 260 self.assertNotEqual(u3, Any) 261 262 def test_union_object(self): 263 u = Union[object] 264 self.assertEqual(u, object) 265 u1 = Union[int, object] 266 u2 = Union[object, int] 267 self.assertEqual(u1, u2) 268 self.assertNotEqual(u1, object) 269 self.assertNotEqual(u2, object) 270 271 def test_unordered(self): 272 u1 = Union[int, float] 273 u2 = Union[float, int] 274 self.assertEqual(u1, u2) 275 276 def test_single_class_disappears(self): 277 t = Union[Employee] 278 self.assertIs(t, Employee) 279 280 def test_base_class_kept(self): 281 u = Union[Employee, Manager] 282 self.assertNotEqual(u, Employee) 283 self.assertIn(Employee, u.__args__) 284 self.assertIn(Manager, u.__args__) 285 286 def test_union_union(self): 287 u = Union[int, float] 288 v = Union[u, Employee] 289 self.assertEqual(v, Union[int, float, Employee]) 290 291 def test_repr(self): 292 self.assertEqual(repr(Union), 'typing.Union') 293 u = Union[Employee, int] 294 self.assertEqual(repr(u), 'typing.Union[%s.Employee, int]' % __name__) 295 u = Union[int, Employee] 296 self.assertEqual(repr(u), 'typing.Union[int, %s.Employee]' % __name__) 297 T = TypeVar('T') 298 u = Union[T, int][int] 299 self.assertEqual(repr(u), repr(int)) 300 u = Union[List[int], int] 301 self.assertEqual(repr(u), 'typing.Union[typing.List[int], int]') 302 303 def test_cannot_subclass(self): 304 with self.assertRaises(TypeError): 305 class C(Union): 306 pass 307 with self.assertRaises(TypeError): 308 class C(type(Union)): 309 pass 310 with self.assertRaises(TypeError): 311 class C(Union[int, str]): 312 pass 313 314 def test_cannot_instantiate(self): 315 with self.assertRaises(TypeError): 316 Union() 317 with self.assertRaises(TypeError): 318 type(Union)() 319 u = Union[int, float] 320 with self.assertRaises(TypeError): 321 u() 322 with self.assertRaises(TypeError): 323 type(u)() 324 325 def test_union_generalization(self): 326 self.assertFalse(Union[str, typing.Iterable[int]] == str) 327 self.assertFalse(Union[str, typing.Iterable[int]] == typing.Iterable[int]) 328 self.assertIn(str, Union[str, typing.Iterable[int]].__args__) 329 self.assertIn(typing.Iterable[int], Union[str, typing.Iterable[int]].__args__) 330 331 def test_union_compare_other(self): 332 self.assertNotEqual(Union, object) 333 self.assertNotEqual(Union, Any) 334 self.assertNotEqual(ClassVar, Union) 335 self.assertNotEqual(Optional, Union) 336 self.assertNotEqual([None], Optional) 337 self.assertNotEqual(Optional, typing.Mapping) 338 self.assertNotEqual(Optional[typing.MutableMapping], Union) 339 340 def test_optional(self): 341 o = Optional[int] 342 u = Union[int, None] 343 self.assertEqual(o, u) 344 345 def test_empty(self): 346 with self.assertRaises(TypeError): 347 Union[()] 348 349 def test_union_instance_type_error(self): 350 with self.assertRaises(TypeError): 351 isinstance(42, Union[int, str]) 352 353 def test_no_eval_union(self): 354 u = Union[int, str] 355 def f(x: u): ... 356 self.assertIs(get_type_hints(f)['x'], u) 357 358 def test_function_repr_union(self): 359 def fun() -> int: ... 360 self.assertEqual(repr(Union[fun, int]), 'typing.Union[fun, int]') 361 362 def test_union_str_pattern(self): 363 # Shouldn't crash; see http://bugs.python.org/issue25390 364 A = Union[str, Pattern] 365 A 366 367 def test_etree(self): 368 # See https://github.com/python/typing/issues/229 369 # (Only relevant for Python 2.) 370 try: 371 from xml.etree.cElementTree import Element 372 except ImportError: 373 raise SkipTest("cElementTree not found") 374 Union[Element, str] # Shouldn't crash 375 376 def Elem(*args): 377 return Element(*args) 378 379 Union[Elem, str] # Nor should this 380 381 382class TupleTests(BaseTestCase): 383 384 def test_basics(self): 385 with self.assertRaises(TypeError): 386 issubclass(Tuple, Tuple[int, str]) 387 with self.assertRaises(TypeError): 388 issubclass(tuple, Tuple[int, str]) 389 390 class TP(tuple): ... 391 self.assertTrue(issubclass(tuple, Tuple)) 392 self.assertTrue(issubclass(TP, Tuple)) 393 394 def test_equality(self): 395 self.assertEqual(Tuple[int], Tuple[int]) 396 self.assertEqual(Tuple[int, ...], Tuple[int, ...]) 397 self.assertNotEqual(Tuple[int], Tuple[int, int]) 398 self.assertNotEqual(Tuple[int], Tuple[int, ...]) 399 400 def test_tuple_subclass(self): 401 class MyTuple(tuple): 402 pass 403 self.assertTrue(issubclass(MyTuple, Tuple)) 404 405 def test_tuple_instance_type_error(self): 406 with self.assertRaises(TypeError): 407 isinstance((0, 0), Tuple[int, int]) 408 self.assertIsInstance((0, 0), Tuple) 409 410 def test_repr(self): 411 self.assertEqual(repr(Tuple), 'typing.Tuple') 412 self.assertEqual(repr(Tuple[()]), 'typing.Tuple[()]') 413 self.assertEqual(repr(Tuple[int, float]), 'typing.Tuple[int, float]') 414 self.assertEqual(repr(Tuple[int, ...]), 'typing.Tuple[int, ...]') 415 416 def test_errors(self): 417 with self.assertRaises(TypeError): 418 issubclass(42, Tuple) 419 with self.assertRaises(TypeError): 420 issubclass(42, Tuple[int]) 421 422 423class CallableTests(BaseTestCase): 424 425 def test_self_subclass(self): 426 with self.assertRaises(TypeError): 427 self.assertTrue(issubclass(type(lambda x: x), Callable[[int], int])) 428 self.assertTrue(issubclass(type(lambda x: x), Callable)) 429 430 def test_eq_hash(self): 431 self.assertEqual(Callable[[int], int], Callable[[int], int]) 432 self.assertEqual(len({Callable[[int], int], Callable[[int], int]}), 1) 433 self.assertNotEqual(Callable[[int], int], Callable[[int], str]) 434 self.assertNotEqual(Callable[[int], int], Callable[[str], int]) 435 self.assertNotEqual(Callable[[int], int], Callable[[int, int], int]) 436 self.assertNotEqual(Callable[[int], int], Callable[[], int]) 437 self.assertNotEqual(Callable[[int], int], Callable) 438 439 def test_cannot_instantiate(self): 440 with self.assertRaises(TypeError): 441 Callable() 442 with self.assertRaises(TypeError): 443 type(Callable)() 444 c = Callable[[int], str] 445 with self.assertRaises(TypeError): 446 c() 447 with self.assertRaises(TypeError): 448 type(c)() 449 450 def test_callable_wrong_forms(self): 451 with self.assertRaises(TypeError): 452 Callable[[...], int] 453 with self.assertRaises(TypeError): 454 Callable[(), int] 455 with self.assertRaises(TypeError): 456 Callable[[()], int] 457 with self.assertRaises(TypeError): 458 Callable[[int, 1], 2] 459 with self.assertRaises(TypeError): 460 Callable[int] 461 462 def test_callable_instance_works(self): 463 def f(): 464 pass 465 self.assertIsInstance(f, Callable) 466 self.assertNotIsInstance(None, Callable) 467 468 def test_callable_instance_type_error(self): 469 def f(): 470 pass 471 with self.assertRaises(TypeError): 472 self.assertIsInstance(f, Callable[[], None]) 473 with self.assertRaises(TypeError): 474 self.assertIsInstance(f, Callable[[], Any]) 475 with self.assertRaises(TypeError): 476 self.assertNotIsInstance(None, Callable[[], None]) 477 with self.assertRaises(TypeError): 478 self.assertNotIsInstance(None, Callable[[], Any]) 479 480 def test_repr(self): 481 ct0 = Callable[[], bool] 482 self.assertEqual(repr(ct0), 'typing.Callable[[], bool]') 483 ct2 = Callable[[str, float], int] 484 self.assertEqual(repr(ct2), 'typing.Callable[[str, float], int]') 485 ctv = Callable[..., str] 486 self.assertEqual(repr(ctv), 'typing.Callable[..., str]') 487 488 def test_callable_with_ellipsis(self): 489 490 def foo(a: Callable[..., T]): 491 pass 492 493 self.assertEqual(get_type_hints(foo, globals(), locals()), 494 {'a': Callable[..., T]}) 495 496 def test_ellipsis_in_generic(self): 497 # Shouldn't crash; see https://github.com/python/typing/issues/259 498 typing.List[Callable[..., str]] 499 500 501class LiteralTests(BaseTestCase): 502 def test_basics(self): 503 # All of these are allowed. 504 Literal[1] 505 Literal[1, 2, 3] 506 Literal["x", "y", "z"] 507 Literal[None] 508 Literal[True] 509 Literal[1, "2", False] 510 Literal[Literal[1, 2], Literal[4, 5]] 511 Literal[b"foo", u"bar"] 512 513 def test_illegal_parameters_do_not_raise_runtime_errors(self): 514 # Type checkers should reject these types, but we do not 515 # raise errors at runtime to maintain maximium flexibility. 516 Literal[int] 517 Literal[3j + 2, ..., ()] 518 Literal[{"foo": 3, "bar": 4}] 519 Literal[T] 520 521 def test_literals_inside_other_types(self): 522 List[Literal[1, 2, 3]] 523 List[Literal[("foo", "bar", "baz")]] 524 525 def test_repr(self): 526 self.assertEqual(repr(Literal[1]), "typing.Literal[1]") 527 self.assertEqual(repr(Literal[1, True, "foo"]), "typing.Literal[1, True, 'foo']") 528 self.assertEqual(repr(Literal[int]), "typing.Literal[int]") 529 self.assertEqual(repr(Literal), "typing.Literal") 530 self.assertEqual(repr(Literal[None]), "typing.Literal[None]") 531 532 def test_cannot_init(self): 533 with self.assertRaises(TypeError): 534 Literal() 535 with self.assertRaises(TypeError): 536 Literal[1]() 537 with self.assertRaises(TypeError): 538 type(Literal)() 539 with self.assertRaises(TypeError): 540 type(Literal[1])() 541 542 def test_no_isinstance_or_issubclass(self): 543 with self.assertRaises(TypeError): 544 isinstance(1, Literal[1]) 545 with self.assertRaises(TypeError): 546 isinstance(int, Literal[1]) 547 with self.assertRaises(TypeError): 548 issubclass(1, Literal[1]) 549 with self.assertRaises(TypeError): 550 issubclass(int, Literal[1]) 551 552 def test_no_subclassing(self): 553 with self.assertRaises(TypeError): 554 class Foo(Literal[1]): pass 555 with self.assertRaises(TypeError): 556 class Bar(Literal): pass 557 558 def test_no_multiple_subscripts(self): 559 with self.assertRaises(TypeError): 560 Literal[1][1] 561 562 563XK = TypeVar('XK', str, bytes) 564XV = TypeVar('XV') 565 566 567class SimpleMapping(Generic[XK, XV]): 568 569 def __getitem__(self, key: XK) -> XV: 570 ... 571 572 def __setitem__(self, key: XK, value: XV): 573 ... 574 575 def get(self, key: XK, default: XV = None) -> XV: 576 ... 577 578 579class MySimpleMapping(SimpleMapping[XK, XV]): 580 581 def __init__(self): 582 self.store = {} 583 584 def __getitem__(self, key: str): 585 return self.store[key] 586 587 def __setitem__(self, key: str, value): 588 self.store[key] = value 589 590 def get(self, key: str, default=None): 591 try: 592 return self.store[key] 593 except KeyError: 594 return default 595 596 597class Coordinate(Protocol): 598 x: int 599 y: int 600 601@runtime_checkable 602class Point(Coordinate, Protocol): 603 label: str 604 605class MyPoint: 606 x: int 607 y: int 608 label: str 609 610class XAxis(Protocol): 611 x: int 612 613class YAxis(Protocol): 614 y: int 615 616@runtime_checkable 617class Position(XAxis, YAxis, Protocol): 618 pass 619 620@runtime_checkable 621class Proto(Protocol): 622 attr: int 623 def meth(self, arg: str) -> int: 624 ... 625 626class Concrete(Proto): 627 pass 628 629class Other: 630 attr: int = 1 631 def meth(self, arg: str) -> int: 632 if arg == 'this': 633 return 1 634 return 0 635 636class NT(NamedTuple): 637 x: int 638 y: int 639 640@runtime_checkable 641class HasCallProtocol(Protocol): 642 __call__: typing.Callable 643 644 645class ProtocolTests(BaseTestCase): 646 def test_basic_protocol(self): 647 @runtime_checkable 648 class P(Protocol): 649 def meth(self): 650 pass 651 652 class C: pass 653 654 class D: 655 def meth(self): 656 pass 657 658 def f(): 659 pass 660 661 self.assertIsSubclass(D, P) 662 self.assertIsInstance(D(), P) 663 self.assertNotIsSubclass(C, P) 664 self.assertNotIsInstance(C(), P) 665 self.assertNotIsSubclass(types.FunctionType, P) 666 self.assertNotIsInstance(f, P) 667 668 def test_everything_implements_empty_protocol(self): 669 @runtime_checkable 670 class Empty(Protocol): 671 pass 672 673 class C: 674 pass 675 676 def f(): 677 pass 678 679 for thing in (object, type, tuple, C, types.FunctionType): 680 self.assertIsSubclass(thing, Empty) 681 for thing in (object(), 1, (), typing, f): 682 self.assertIsInstance(thing, Empty) 683 684 def test_function_implements_protocol(self): 685 def f(): 686 pass 687 688 self.assertIsInstance(f, HasCallProtocol) 689 690 def test_no_inheritance_from_nominal(self): 691 class C: pass 692 693 class BP(Protocol): pass 694 695 with self.assertRaises(TypeError): 696 class P(C, Protocol): 697 pass 698 with self.assertRaises(TypeError): 699 class P(Protocol, C): 700 pass 701 with self.assertRaises(TypeError): 702 class P(BP, C, Protocol): 703 pass 704 705 class D(BP, C): pass 706 707 class E(C, BP): pass 708 709 self.assertNotIsInstance(D(), E) 710 self.assertNotIsInstance(E(), D) 711 712 def test_no_instantiation(self): 713 class P(Protocol): pass 714 715 with self.assertRaises(TypeError): 716 P() 717 718 class C(P): pass 719 720 self.assertIsInstance(C(), C) 721 T = TypeVar('T') 722 723 class PG(Protocol[T]): pass 724 725 with self.assertRaises(TypeError): 726 PG() 727 with self.assertRaises(TypeError): 728 PG[int]() 729 with self.assertRaises(TypeError): 730 PG[T]() 731 732 class CG(PG[T]): pass 733 734 self.assertIsInstance(CG[int](), CG) 735 736 def test_cannot_instantiate_abstract(self): 737 @runtime_checkable 738 class P(Protocol): 739 @abc.abstractmethod 740 def ameth(self) -> int: 741 raise NotImplementedError 742 743 class B(P): 744 pass 745 746 class C(B): 747 def ameth(self) -> int: 748 return 26 749 750 with self.assertRaises(TypeError): 751 B() 752 self.assertIsInstance(C(), P) 753 754 def test_subprotocols_extending(self): 755 class P1(Protocol): 756 def meth1(self): 757 pass 758 759 @runtime_checkable 760 class P2(P1, Protocol): 761 def meth2(self): 762 pass 763 764 class C: 765 def meth1(self): 766 pass 767 768 def meth2(self): 769 pass 770 771 class C1: 772 def meth1(self): 773 pass 774 775 class C2: 776 def meth2(self): 777 pass 778 779 self.assertNotIsInstance(C1(), P2) 780 self.assertNotIsInstance(C2(), P2) 781 self.assertNotIsSubclass(C1, P2) 782 self.assertNotIsSubclass(C2, P2) 783 self.assertIsInstance(C(), P2) 784 self.assertIsSubclass(C, P2) 785 786 def test_subprotocols_merging(self): 787 class P1(Protocol): 788 def meth1(self): 789 pass 790 791 class P2(Protocol): 792 def meth2(self): 793 pass 794 795 @runtime_checkable 796 class P(P1, P2, Protocol): 797 pass 798 799 class C: 800 def meth1(self): 801 pass 802 803 def meth2(self): 804 pass 805 806 class C1: 807 def meth1(self): 808 pass 809 810 class C2: 811 def meth2(self): 812 pass 813 814 self.assertNotIsInstance(C1(), P) 815 self.assertNotIsInstance(C2(), P) 816 self.assertNotIsSubclass(C1, P) 817 self.assertNotIsSubclass(C2, P) 818 self.assertIsInstance(C(), P) 819 self.assertIsSubclass(C, P) 820 821 def test_protocols_issubclass(self): 822 T = TypeVar('T') 823 824 @runtime_checkable 825 class P(Protocol): 826 def x(self): ... 827 828 @runtime_checkable 829 class PG(Protocol[T]): 830 def x(self): ... 831 832 class BadP(Protocol): 833 def x(self): ... 834 835 class BadPG(Protocol[T]): 836 def x(self): ... 837 838 class C: 839 def x(self): ... 840 841 self.assertIsSubclass(C, P) 842 self.assertIsSubclass(C, PG) 843 self.assertIsSubclass(BadP, PG) 844 845 with self.assertRaises(TypeError): 846 issubclass(C, PG[T]) 847 with self.assertRaises(TypeError): 848 issubclass(C, PG[C]) 849 with self.assertRaises(TypeError): 850 issubclass(C, BadP) 851 with self.assertRaises(TypeError): 852 issubclass(C, BadPG) 853 with self.assertRaises(TypeError): 854 issubclass(P, PG[T]) 855 with self.assertRaises(TypeError): 856 issubclass(PG, PG[int]) 857 858 def test_protocols_issubclass_non_callable(self): 859 class C: 860 x = 1 861 862 @runtime_checkable 863 class PNonCall(Protocol): 864 x = 1 865 866 with self.assertRaises(TypeError): 867 issubclass(C, PNonCall) 868 self.assertIsInstance(C(), PNonCall) 869 PNonCall.register(C) 870 with self.assertRaises(TypeError): 871 issubclass(C, PNonCall) 872 self.assertIsInstance(C(), PNonCall) 873 874 # check that non-protocol subclasses are not affected 875 class D(PNonCall): ... 876 877 self.assertNotIsSubclass(C, D) 878 self.assertNotIsInstance(C(), D) 879 D.register(C) 880 self.assertIsSubclass(C, D) 881 self.assertIsInstance(C(), D) 882 with self.assertRaises(TypeError): 883 issubclass(D, PNonCall) 884 885 def test_protocols_isinstance(self): 886 T = TypeVar('T') 887 888 @runtime_checkable 889 class P(Protocol): 890 def meth(x): ... 891 892 @runtime_checkable 893 class PG(Protocol[T]): 894 def meth(x): ... 895 896 class BadP(Protocol): 897 def meth(x): ... 898 899 class BadPG(Protocol[T]): 900 def meth(x): ... 901 902 class C: 903 def meth(x): ... 904 905 self.assertIsInstance(C(), P) 906 self.assertIsInstance(C(), PG) 907 with self.assertRaises(TypeError): 908 isinstance(C(), PG[T]) 909 with self.assertRaises(TypeError): 910 isinstance(C(), PG[C]) 911 with self.assertRaises(TypeError): 912 isinstance(C(), BadP) 913 with self.assertRaises(TypeError): 914 isinstance(C(), BadPG) 915 916 def test_protocols_isinstance_py36(self): 917 class APoint: 918 def __init__(self, x, y, label): 919 self.x = x 920 self.y = y 921 self.label = label 922 923 class BPoint: 924 label = 'B' 925 926 def __init__(self, x, y): 927 self.x = x 928 self.y = y 929 930 class C: 931 def __init__(self, attr): 932 self.attr = attr 933 934 def meth(self, arg): 935 return 0 936 937 class Bad: pass 938 939 self.assertIsInstance(APoint(1, 2, 'A'), Point) 940 self.assertIsInstance(BPoint(1, 2), Point) 941 self.assertNotIsInstance(MyPoint(), Point) 942 self.assertIsInstance(BPoint(1, 2), Position) 943 self.assertIsInstance(Other(), Proto) 944 self.assertIsInstance(Concrete(), Proto) 945 self.assertIsInstance(C(42), Proto) 946 self.assertNotIsInstance(Bad(), Proto) 947 self.assertNotIsInstance(Bad(), Point) 948 self.assertNotIsInstance(Bad(), Position) 949 self.assertNotIsInstance(Bad(), Concrete) 950 self.assertNotIsInstance(Other(), Concrete) 951 self.assertIsInstance(NT(1, 2), Position) 952 953 def test_protocols_isinstance_init(self): 954 T = TypeVar('T') 955 956 @runtime_checkable 957 class P(Protocol): 958 x = 1 959 960 @runtime_checkable 961 class PG(Protocol[T]): 962 x = 1 963 964 class C: 965 def __init__(self, x): 966 self.x = x 967 968 self.assertIsInstance(C(1), P) 969 self.assertIsInstance(C(1), PG) 970 971 def test_protocol_checks_after_subscript(self): 972 class P(Protocol[T]): pass 973 class C(P[T]): pass 974 class Other1: pass 975 class Other2: pass 976 CA = C[Any] 977 978 self.assertNotIsInstance(Other1(), C) 979 self.assertNotIsSubclass(Other2, C) 980 981 class D1(C[Any]): pass 982 class D2(C[Any]): pass 983 CI = C[int] 984 985 self.assertIsInstance(D1(), C) 986 self.assertIsSubclass(D2, C) 987 988 def test_protocols_support_register(self): 989 @runtime_checkable 990 class P(Protocol): 991 x = 1 992 993 class PM(Protocol): 994 def meth(self): pass 995 996 class D(PM): pass 997 998 class C: pass 999 1000 D.register(C) 1001 P.register(C) 1002 self.assertIsInstance(C(), P) 1003 self.assertIsInstance(C(), D) 1004 1005 def test_none_on_non_callable_doesnt_block_implementation(self): 1006 @runtime_checkable 1007 class P(Protocol): 1008 x = 1 1009 1010 class A: 1011 x = 1 1012 1013 class B(A): 1014 x = None 1015 1016 class C: 1017 def __init__(self): 1018 self.x = None 1019 1020 self.assertIsInstance(B(), P) 1021 self.assertIsInstance(C(), P) 1022 1023 def test_none_on_callable_blocks_implementation(self): 1024 @runtime_checkable 1025 class P(Protocol): 1026 def x(self): ... 1027 1028 class A: 1029 def x(self): ... 1030 1031 class B(A): 1032 x = None 1033 1034 class C: 1035 def __init__(self): 1036 self.x = None 1037 1038 self.assertNotIsInstance(B(), P) 1039 self.assertNotIsInstance(C(), P) 1040 1041 def test_non_protocol_subclasses(self): 1042 class P(Protocol): 1043 x = 1 1044 1045 @runtime_checkable 1046 class PR(Protocol): 1047 def meth(self): pass 1048 1049 class NonP(P): 1050 x = 1 1051 1052 class NonPR(PR): pass 1053 1054 class C: 1055 x = 1 1056 1057 class D: 1058 def meth(self): pass 1059 1060 self.assertNotIsInstance(C(), NonP) 1061 self.assertNotIsInstance(D(), NonPR) 1062 self.assertNotIsSubclass(C, NonP) 1063 self.assertNotIsSubclass(D, NonPR) 1064 self.assertIsInstance(NonPR(), PR) 1065 self.assertIsSubclass(NonPR, PR) 1066 1067 def test_custom_subclasshook(self): 1068 class P(Protocol): 1069 x = 1 1070 1071 class OKClass: pass 1072 1073 class BadClass: 1074 x = 1 1075 1076 class C(P): 1077 @classmethod 1078 def __subclasshook__(cls, other): 1079 return other.__name__.startswith("OK") 1080 1081 self.assertIsInstance(OKClass(), C) 1082 self.assertNotIsInstance(BadClass(), C) 1083 self.assertIsSubclass(OKClass, C) 1084 self.assertNotIsSubclass(BadClass, C) 1085 1086 def test_issubclass_fails_correctly(self): 1087 @runtime_checkable 1088 class P(Protocol): 1089 x = 1 1090 1091 class C: pass 1092 1093 with self.assertRaises(TypeError): 1094 issubclass(C(), P) 1095 1096 def test_defining_generic_protocols(self): 1097 T = TypeVar('T') 1098 S = TypeVar('S') 1099 1100 @runtime_checkable 1101 class PR(Protocol[T, S]): 1102 def meth(self): pass 1103 1104 class P(PR[int, T], Protocol[T]): 1105 y = 1 1106 1107 with self.assertRaises(TypeError): 1108 PR[int] 1109 with self.assertRaises(TypeError): 1110 P[int, str] 1111 with self.assertRaises(TypeError): 1112 PR[int, 1] 1113 with self.assertRaises(TypeError): 1114 PR[int, ClassVar] 1115 1116 class C(PR[int, T]): pass 1117 1118 self.assertIsInstance(C[str](), C) 1119 1120 def test_defining_generic_protocols_old_style(self): 1121 T = TypeVar('T') 1122 S = TypeVar('S') 1123 1124 @runtime_checkable 1125 class PR(Protocol, Generic[T, S]): 1126 def meth(self): pass 1127 1128 class P(PR[int, str], Protocol): 1129 y = 1 1130 1131 with self.assertRaises(TypeError): 1132 issubclass(PR[int, str], PR) 1133 self.assertIsSubclass(P, PR) 1134 with self.assertRaises(TypeError): 1135 PR[int] 1136 with self.assertRaises(TypeError): 1137 PR[int, 1] 1138 1139 class P1(Protocol, Generic[T]): 1140 def bar(self, x: T) -> str: ... 1141 1142 class P2(Generic[T], Protocol): 1143 def bar(self, x: T) -> str: ... 1144 1145 @runtime_checkable 1146 class PSub(P1[str], Protocol): 1147 x = 1 1148 1149 class Test: 1150 x = 1 1151 1152 def bar(self, x: str) -> str: 1153 return x 1154 1155 self.assertIsInstance(Test(), PSub) 1156 with self.assertRaises(TypeError): 1157 PR[int, ClassVar] 1158 1159 def test_init_called(self): 1160 T = TypeVar('T') 1161 1162 class P(Protocol[T]): pass 1163 1164 class C(P[T]): 1165 def __init__(self): 1166 self.test = 'OK' 1167 1168 self.assertEqual(C[int]().test, 'OK') 1169 1170 def test_protocols_bad_subscripts(self): 1171 T = TypeVar('T') 1172 S = TypeVar('S') 1173 with self.assertRaises(TypeError): 1174 class P(Protocol[T, T]): pass 1175 with self.assertRaises(TypeError): 1176 class P(Protocol[int]): pass 1177 with self.assertRaises(TypeError): 1178 class P(Protocol[T], Protocol[S]): pass 1179 with self.assertRaises(TypeError): 1180 class P(typing.Mapping[T, S], Protocol[T]): pass 1181 1182 def test_generic_protocols_repr(self): 1183 T = TypeVar('T') 1184 S = TypeVar('S') 1185 1186 class P(Protocol[T, S]): pass 1187 1188 self.assertTrue(repr(P[T, S]).endswith('P[~T, ~S]')) 1189 self.assertTrue(repr(P[int, str]).endswith('P[int, str]')) 1190 1191 def test_generic_protocols_eq(self): 1192 T = TypeVar('T') 1193 S = TypeVar('S') 1194 1195 class P(Protocol[T, S]): pass 1196 1197 self.assertEqual(P, P) 1198 self.assertEqual(P[int, T], P[int, T]) 1199 self.assertEqual(P[T, T][Tuple[T, S]][int, str], 1200 P[Tuple[int, str], Tuple[int, str]]) 1201 1202 def test_generic_protocols_special_from_generic(self): 1203 T = TypeVar('T') 1204 1205 class P(Protocol[T]): pass 1206 1207 self.assertEqual(P.__parameters__, (T,)) 1208 self.assertEqual(P[int].__parameters__, ()) 1209 self.assertEqual(P[int].__args__, (int,)) 1210 self.assertIs(P[int].__origin__, P) 1211 1212 def test_generic_protocols_special_from_protocol(self): 1213 @runtime_checkable 1214 class PR(Protocol): 1215 x = 1 1216 1217 class P(Protocol): 1218 def meth(self): 1219 pass 1220 1221 T = TypeVar('T') 1222 1223 class PG(Protocol[T]): 1224 x = 1 1225 1226 def meth(self): 1227 pass 1228 1229 self.assertTrue(P._is_protocol) 1230 self.assertTrue(PR._is_protocol) 1231 self.assertTrue(PG._is_protocol) 1232 self.assertFalse(P._is_runtime_protocol) 1233 self.assertTrue(PR._is_runtime_protocol) 1234 self.assertTrue(PG[int]._is_protocol) 1235 self.assertEqual(typing._get_protocol_attrs(P), {'meth'}) 1236 self.assertEqual(typing._get_protocol_attrs(PR), {'x'}) 1237 self.assertEqual(frozenset(typing._get_protocol_attrs(PG)), 1238 frozenset({'x', 'meth'})) 1239 1240 def test_no_runtime_deco_on_nominal(self): 1241 with self.assertRaises(TypeError): 1242 @runtime_checkable 1243 class C: pass 1244 1245 class Proto(Protocol): 1246 x = 1 1247 1248 with self.assertRaises(TypeError): 1249 @runtime_checkable 1250 class Concrete(Proto): 1251 pass 1252 1253 def test_none_treated_correctly(self): 1254 @runtime_checkable 1255 class P(Protocol): 1256 x = None # type: int 1257 1258 class B(object): pass 1259 1260 self.assertNotIsInstance(B(), P) 1261 1262 class C: 1263 x = 1 1264 1265 class D: 1266 x = None 1267 1268 self.assertIsInstance(C(), P) 1269 self.assertIsInstance(D(), P) 1270 1271 class CI: 1272 def __init__(self): 1273 self.x = 1 1274 1275 class DI: 1276 def __init__(self): 1277 self.x = None 1278 1279 self.assertIsInstance(C(), P) 1280 self.assertIsInstance(D(), P) 1281 1282 def test_protocols_in_unions(self): 1283 class P(Protocol): 1284 x = None # type: int 1285 1286 Alias = typing.Union[typing.Iterable, P] 1287 Alias2 = typing.Union[P, typing.Iterable] 1288 self.assertEqual(Alias, Alias2) 1289 1290 def test_protocols_pickleable(self): 1291 global P, CP # pickle wants to reference the class by name 1292 T = TypeVar('T') 1293 1294 @runtime_checkable 1295 class P(Protocol[T]): 1296 x = 1 1297 1298 class CP(P[int]): 1299 pass 1300 1301 c = CP() 1302 c.foo = 42 1303 c.bar = 'abc' 1304 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 1305 z = pickle.dumps(c, proto) 1306 x = pickle.loads(z) 1307 self.assertEqual(x.foo, 42) 1308 self.assertEqual(x.bar, 'abc') 1309 self.assertEqual(x.x, 1) 1310 self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) 1311 s = pickle.dumps(P) 1312 D = pickle.loads(s) 1313 1314 class E: 1315 x = 1 1316 1317 self.assertIsInstance(E(), D) 1318 1319 def test_supports_int(self): 1320 self.assertIsSubclass(int, typing.SupportsInt) 1321 self.assertNotIsSubclass(str, typing.SupportsInt) 1322 1323 def test_supports_float(self): 1324 self.assertIsSubclass(float, typing.SupportsFloat) 1325 self.assertNotIsSubclass(str, typing.SupportsFloat) 1326 1327 def test_supports_complex(self): 1328 1329 # Note: complex itself doesn't have __complex__. 1330 class C: 1331 def __complex__(self): 1332 return 0j 1333 1334 self.assertIsSubclass(C, typing.SupportsComplex) 1335 self.assertNotIsSubclass(str, typing.SupportsComplex) 1336 1337 def test_supports_bytes(self): 1338 1339 # Note: bytes itself doesn't have __bytes__. 1340 class B: 1341 def __bytes__(self): 1342 return b'' 1343 1344 self.assertIsSubclass(B, typing.SupportsBytes) 1345 self.assertNotIsSubclass(str, typing.SupportsBytes) 1346 1347 def test_supports_abs(self): 1348 self.assertIsSubclass(float, typing.SupportsAbs) 1349 self.assertIsSubclass(int, typing.SupportsAbs) 1350 self.assertNotIsSubclass(str, typing.SupportsAbs) 1351 1352 def test_supports_round(self): 1353 issubclass(float, typing.SupportsRound) 1354 self.assertIsSubclass(float, typing.SupportsRound) 1355 self.assertIsSubclass(int, typing.SupportsRound) 1356 self.assertNotIsSubclass(str, typing.SupportsRound) 1357 1358 def test_reversible(self): 1359 self.assertIsSubclass(list, typing.Reversible) 1360 self.assertNotIsSubclass(int, typing.Reversible) 1361 1362 def test_supports_index(self): 1363 self.assertIsSubclass(int, typing.SupportsIndex) 1364 self.assertNotIsSubclass(str, typing.SupportsIndex) 1365 1366 def test_bundled_protocol_instance_works(self): 1367 self.assertIsInstance(0, typing.SupportsAbs) 1368 class C1(typing.SupportsInt): 1369 def __int__(self) -> int: 1370 return 42 1371 class C2(C1): 1372 pass 1373 c = C2() 1374 self.assertIsInstance(c, C1) 1375 1376 def test_collections_protocols_allowed(self): 1377 @runtime_checkable 1378 class Custom(collections.abc.Iterable, Protocol): 1379 def close(self): ... 1380 1381 class A: pass 1382 class B: 1383 def __iter__(self): 1384 return [] 1385 def close(self): 1386 return 0 1387 1388 self.assertIsSubclass(B, Custom) 1389 self.assertNotIsSubclass(A, Custom) 1390 1391 def test_builtin_protocol_whitelist(self): 1392 with self.assertRaises(TypeError): 1393 class CustomProtocol(TestCase, Protocol): 1394 pass 1395 1396 class CustomContextManager(typing.ContextManager, Protocol): 1397 pass 1398 1399class GenericTests(BaseTestCase): 1400 1401 def test_basics(self): 1402 X = SimpleMapping[str, Any] 1403 self.assertEqual(X.__parameters__, ()) 1404 with self.assertRaises(TypeError): 1405 X[str] 1406 with self.assertRaises(TypeError): 1407 X[str, str] 1408 Y = SimpleMapping[XK, str] 1409 self.assertEqual(Y.__parameters__, (XK,)) 1410 Y[str] 1411 with self.assertRaises(TypeError): 1412 Y[str, str] 1413 SM1 = SimpleMapping[str, int] 1414 with self.assertRaises(TypeError): 1415 issubclass(SM1, SimpleMapping) 1416 self.assertIsInstance(SM1(), SimpleMapping) 1417 1418 def test_generic_errors(self): 1419 T = TypeVar('T') 1420 S = TypeVar('S') 1421 with self.assertRaises(TypeError): 1422 Generic[T]() 1423 with self.assertRaises(TypeError): 1424 Generic[T][T] 1425 with self.assertRaises(TypeError): 1426 Generic[T][S] 1427 with self.assertRaises(TypeError): 1428 class C(Generic[T], Generic[T]): ... 1429 with self.assertRaises(TypeError): 1430 isinstance([], List[int]) 1431 with self.assertRaises(TypeError): 1432 issubclass(list, List[int]) 1433 with self.assertRaises(TypeError): 1434 class NewGeneric(Generic): ... 1435 with self.assertRaises(TypeError): 1436 class MyGeneric(Generic[T], Generic[S]): ... 1437 with self.assertRaises(TypeError): 1438 class MyGeneric(List[T], Generic[S]): ... 1439 1440 def test_init(self): 1441 T = TypeVar('T') 1442 S = TypeVar('S') 1443 with self.assertRaises(TypeError): 1444 Generic[T, T] 1445 with self.assertRaises(TypeError): 1446 Generic[T, S, T] 1447 1448 def test_init_subclass(self): 1449 class X(typing.Generic[T]): 1450 def __init_subclass__(cls, **kwargs): 1451 super().__init_subclass__(**kwargs) 1452 cls.attr = 42 1453 class Y(X): 1454 pass 1455 self.assertEqual(Y.attr, 42) 1456 with self.assertRaises(AttributeError): 1457 X.attr 1458 X.attr = 1 1459 Y.attr = 2 1460 class Z(Y): 1461 pass 1462 class W(X[int]): 1463 pass 1464 self.assertEqual(Y.attr, 2) 1465 self.assertEqual(Z.attr, 42) 1466 self.assertEqual(W.attr, 42) 1467 1468 def test_repr(self): 1469 self.assertEqual(repr(SimpleMapping), 1470 f"<class '{__name__}.SimpleMapping'>") 1471 self.assertEqual(repr(MySimpleMapping), 1472 f"<class '{__name__}.MySimpleMapping'>") 1473 1474 def test_chain_repr(self): 1475 T = TypeVar('T') 1476 S = TypeVar('S') 1477 1478 class C(Generic[T]): 1479 pass 1480 1481 X = C[Tuple[S, T]] 1482 self.assertEqual(X, C[Tuple[S, T]]) 1483 self.assertNotEqual(X, C[Tuple[T, S]]) 1484 1485 Y = X[T, int] 1486 self.assertEqual(Y, X[T, int]) 1487 self.assertNotEqual(Y, X[S, int]) 1488 self.assertNotEqual(Y, X[T, str]) 1489 1490 Z = Y[str] 1491 self.assertEqual(Z, Y[str]) 1492 self.assertNotEqual(Z, Y[int]) 1493 self.assertNotEqual(Z, Y[T]) 1494 1495 self.assertTrue(str(Z).endswith( 1496 '.C[typing.Tuple[str, int]]')) 1497 1498 def test_new_repr(self): 1499 T = TypeVar('T') 1500 U = TypeVar('U', covariant=True) 1501 S = TypeVar('S') 1502 1503 self.assertEqual(repr(List), 'typing.List') 1504 self.assertEqual(repr(List[T]), 'typing.List[~T]') 1505 self.assertEqual(repr(List[U]), 'typing.List[+U]') 1506 self.assertEqual(repr(List[S][T][int]), 'typing.List[int]') 1507 self.assertEqual(repr(List[int]), 'typing.List[int]') 1508 1509 def test_new_repr_complex(self): 1510 T = TypeVar('T') 1511 TS = TypeVar('TS') 1512 1513 self.assertEqual(repr(typing.Mapping[T, TS][TS, T]), 'typing.Mapping[~TS, ~T]') 1514 self.assertEqual(repr(List[Tuple[T, TS]][int, T]), 1515 'typing.List[typing.Tuple[int, ~T]]') 1516 self.assertEqual( 1517 repr(List[Tuple[T, T]][List[int]]), 1518 'typing.List[typing.Tuple[typing.List[int], typing.List[int]]]' 1519 ) 1520 1521 def test_new_repr_bare(self): 1522 T = TypeVar('T') 1523 self.assertEqual(repr(Generic[T]), 'typing.Generic[~T]') 1524 self.assertEqual(repr(typing.Protocol[T]), 'typing.Protocol[~T]') 1525 class C(typing.Dict[Any, Any]): ... 1526 # this line should just work 1527 repr(C.__mro__) 1528 1529 def test_dict(self): 1530 T = TypeVar('T') 1531 1532 class B(Generic[T]): 1533 pass 1534 1535 b = B() 1536 b.foo = 42 1537 self.assertEqual(b.__dict__, {'foo': 42}) 1538 1539 class C(B[int]): 1540 pass 1541 1542 c = C() 1543 c.bar = 'abc' 1544 self.assertEqual(c.__dict__, {'bar': 'abc'}) 1545 1546 def test_subscripted_generics_as_proxies(self): 1547 T = TypeVar('T') 1548 class C(Generic[T]): 1549 x = 'def' 1550 self.assertEqual(C[int].x, 'def') 1551 self.assertEqual(C[C[int]].x, 'def') 1552 C[C[int]].x = 'changed' 1553 self.assertEqual(C.x, 'changed') 1554 self.assertEqual(C[str].x, 'changed') 1555 C[List[str]].z = 'new' 1556 self.assertEqual(C.z, 'new') 1557 self.assertEqual(C[Tuple[int]].z, 'new') 1558 1559 self.assertEqual(C().x, 'changed') 1560 self.assertEqual(C[Tuple[str]]().z, 'new') 1561 1562 class D(C[T]): 1563 pass 1564 self.assertEqual(D[int].x, 'changed') 1565 self.assertEqual(D.z, 'new') 1566 D.z = 'from derived z' 1567 D[int].x = 'from derived x' 1568 self.assertEqual(C.x, 'changed') 1569 self.assertEqual(C[int].z, 'new') 1570 self.assertEqual(D.x, 'from derived x') 1571 self.assertEqual(D[str].z, 'from derived z') 1572 1573 def test_abc_registry_kept(self): 1574 T = TypeVar('T') 1575 class C(collections.abc.Mapping, Generic[T]): ... 1576 C.register(int) 1577 self.assertIsInstance(1, C) 1578 C[int] 1579 self.assertIsInstance(1, C) 1580 C._abc_registry_clear() 1581 C._abc_caches_clear() # To keep refleak hunting mode clean 1582 1583 def test_false_subclasses(self): 1584 class MyMapping(MutableMapping[str, str]): pass 1585 self.assertNotIsInstance({}, MyMapping) 1586 self.assertNotIsSubclass(dict, MyMapping) 1587 1588 def test_abc_bases(self): 1589 class MM(MutableMapping[str, str]): 1590 def __getitem__(self, k): 1591 return None 1592 def __setitem__(self, k, v): 1593 pass 1594 def __delitem__(self, k): 1595 pass 1596 def __iter__(self): 1597 return iter(()) 1598 def __len__(self): 1599 return 0 1600 # this should just work 1601 MM().update() 1602 self.assertIsInstance(MM(), collections.abc.MutableMapping) 1603 self.assertIsInstance(MM(), MutableMapping) 1604 self.assertNotIsInstance(MM(), List) 1605 self.assertNotIsInstance({}, MM) 1606 1607 def test_multiple_bases(self): 1608 class MM1(MutableMapping[str, str], collections.abc.MutableMapping): 1609 pass 1610 class MM2(collections.abc.MutableMapping, MutableMapping[str, str]): 1611 pass 1612 self.assertEqual(MM2.__bases__, (collections.abc.MutableMapping, Generic)) 1613 1614 def test_orig_bases(self): 1615 T = TypeVar('T') 1616 class C(typing.Dict[str, T]): ... 1617 self.assertEqual(C.__orig_bases__, (typing.Dict[str, T],)) 1618 1619 def test_naive_runtime_checks(self): 1620 def naive_dict_check(obj, tp): 1621 # Check if a dictionary conforms to Dict type 1622 if len(tp.__parameters__) > 0: 1623 raise NotImplementedError 1624 if tp.__args__: 1625 KT, VT = tp.__args__ 1626 return all( 1627 isinstance(k, KT) and isinstance(v, VT) 1628 for k, v in obj.items() 1629 ) 1630 self.assertTrue(naive_dict_check({'x': 1}, typing.Dict[str, int])) 1631 self.assertFalse(naive_dict_check({1: 'x'}, typing.Dict[str, int])) 1632 with self.assertRaises(NotImplementedError): 1633 naive_dict_check({1: 'x'}, typing.Dict[str, T]) 1634 1635 def naive_generic_check(obj, tp): 1636 # Check if an instance conforms to the generic class 1637 if not hasattr(obj, '__orig_class__'): 1638 raise NotImplementedError 1639 return obj.__orig_class__ == tp 1640 class Node(Generic[T]): ... 1641 self.assertTrue(naive_generic_check(Node[int](), Node[int])) 1642 self.assertFalse(naive_generic_check(Node[str](), Node[int])) 1643 self.assertFalse(naive_generic_check(Node[str](), List)) 1644 with self.assertRaises(NotImplementedError): 1645 naive_generic_check([1, 2, 3], Node[int]) 1646 1647 def naive_list_base_check(obj, tp): 1648 # Check if list conforms to a List subclass 1649 return all(isinstance(x, tp.__orig_bases__[0].__args__[0]) 1650 for x in obj) 1651 class C(List[int]): ... 1652 self.assertTrue(naive_list_base_check([1, 2, 3], C)) 1653 self.assertFalse(naive_list_base_check(['a', 'b'], C)) 1654 1655 def test_multi_subscr_base(self): 1656 T = TypeVar('T') 1657 U = TypeVar('U') 1658 V = TypeVar('V') 1659 class C(List[T][U][V]): ... 1660 class D(C, List[T][U][V]): ... 1661 self.assertEqual(C.__parameters__, (V,)) 1662 self.assertEqual(D.__parameters__, (V,)) 1663 self.assertEqual(C[int].__parameters__, ()) 1664 self.assertEqual(D[int].__parameters__, ()) 1665 self.assertEqual(C[int].__args__, (int,)) 1666 self.assertEqual(D[int].__args__, (int,)) 1667 self.assertEqual(C.__bases__, (list, Generic)) 1668 self.assertEqual(D.__bases__, (C, list, Generic)) 1669 self.assertEqual(C.__orig_bases__, (List[T][U][V],)) 1670 self.assertEqual(D.__orig_bases__, (C, List[T][U][V])) 1671 1672 def test_subscript_meta(self): 1673 T = TypeVar('T') 1674 class Meta(type): ... 1675 self.assertEqual(Type[Meta], Type[Meta]) 1676 self.assertEqual(Union[T, int][Meta], Union[Meta, int]) 1677 self.assertEqual(Callable[..., Meta].__args__, (Ellipsis, Meta)) 1678 1679 def test_generic_hashes(self): 1680 class A(Generic[T]): 1681 ... 1682 1683 class B(Generic[T]): 1684 class A(Generic[T]): 1685 ... 1686 1687 self.assertEqual(A, A) 1688 self.assertEqual(mod_generics_cache.A[str], mod_generics_cache.A[str]) 1689 self.assertEqual(B.A, B.A) 1690 self.assertEqual(mod_generics_cache.B.A[B.A[str]], 1691 mod_generics_cache.B.A[B.A[str]]) 1692 1693 self.assertNotEqual(A, B.A) 1694 self.assertNotEqual(A, mod_generics_cache.A) 1695 self.assertNotEqual(A, mod_generics_cache.B.A) 1696 self.assertNotEqual(B.A, mod_generics_cache.A) 1697 self.assertNotEqual(B.A, mod_generics_cache.B.A) 1698 1699 self.assertNotEqual(A[str], B.A[str]) 1700 self.assertNotEqual(A[List[Any]], B.A[List[Any]]) 1701 self.assertNotEqual(A[str], mod_generics_cache.A[str]) 1702 self.assertNotEqual(A[str], mod_generics_cache.B.A[str]) 1703 self.assertNotEqual(B.A[int], mod_generics_cache.A[int]) 1704 self.assertNotEqual(B.A[List[Any]], mod_generics_cache.B.A[List[Any]]) 1705 1706 self.assertNotEqual(Tuple[A[str]], Tuple[B.A[str]]) 1707 self.assertNotEqual(Tuple[A[List[Any]]], Tuple[B.A[List[Any]]]) 1708 self.assertNotEqual(Union[str, A[str]], Union[str, mod_generics_cache.A[str]]) 1709 self.assertNotEqual(Union[A[str], A[str]], 1710 Union[A[str], mod_generics_cache.A[str]]) 1711 self.assertNotEqual(typing.FrozenSet[A[str]], 1712 typing.FrozenSet[mod_generics_cache.B.A[str]]) 1713 1714 if sys.version_info[:2] > (3, 2): 1715 self.assertTrue(repr(Tuple[A[str]]).endswith('<locals>.A[str]]')) 1716 self.assertTrue(repr(Tuple[B.A[str]]).endswith('<locals>.B.A[str]]')) 1717 self.assertTrue(repr(Tuple[mod_generics_cache.A[str]]) 1718 .endswith('mod_generics_cache.A[str]]')) 1719 self.assertTrue(repr(Tuple[mod_generics_cache.B.A[str]]) 1720 .endswith('mod_generics_cache.B.A[str]]')) 1721 1722 def test_extended_generic_rules_eq(self): 1723 T = TypeVar('T') 1724 U = TypeVar('U') 1725 self.assertEqual(Tuple[T, T][int], Tuple[int, int]) 1726 self.assertEqual(typing.Iterable[Tuple[T, T]][T], typing.Iterable[Tuple[T, T]]) 1727 with self.assertRaises(TypeError): 1728 Tuple[T, int][()] 1729 with self.assertRaises(TypeError): 1730 Tuple[T, U][T, ...] 1731 1732 self.assertEqual(Union[T, int][int], int) 1733 self.assertEqual(Union[T, U][int, Union[int, str]], Union[int, str]) 1734 class Base: ... 1735 class Derived(Base): ... 1736 self.assertEqual(Union[T, Base][Union[Base, Derived]], Union[Base, Derived]) 1737 with self.assertRaises(TypeError): 1738 Union[T, int][1] 1739 1740 self.assertEqual(Callable[[T], T][KT], Callable[[KT], KT]) 1741 self.assertEqual(Callable[..., List[T]][int], Callable[..., List[int]]) 1742 with self.assertRaises(TypeError): 1743 Callable[[T], U][..., int] 1744 with self.assertRaises(TypeError): 1745 Callable[[T], U][[], int] 1746 1747 def test_extended_generic_rules_repr(self): 1748 T = TypeVar('T') 1749 self.assertEqual(repr(Union[Tuple, Callable]).replace('typing.', ''), 1750 'Union[Tuple, Callable]') 1751 self.assertEqual(repr(Union[Tuple, Tuple[int]]).replace('typing.', ''), 1752 'Union[Tuple, Tuple[int]]') 1753 self.assertEqual(repr(Callable[..., Optional[T]][int]).replace('typing.', ''), 1754 'Callable[..., Union[int, NoneType]]') 1755 self.assertEqual(repr(Callable[[], List[T]][int]).replace('typing.', ''), 1756 'Callable[[], List[int]]') 1757 1758 def test_generic_forward_ref(self): 1759 def foobar(x: List[List['CC']]): ... 1760 class CC: ... 1761 self.assertEqual( 1762 get_type_hints(foobar, globals(), locals()), 1763 {'x': List[List[CC]]} 1764 ) 1765 T = TypeVar('T') 1766 AT = Tuple[T, ...] 1767 def barfoo(x: AT): ... 1768 self.assertIs(get_type_hints(barfoo, globals(), locals())['x'], AT) 1769 CT = Callable[..., List[T]] 1770 def barfoo2(x: CT): ... 1771 self.assertIs(get_type_hints(barfoo2, globals(), locals())['x'], CT) 1772 1773 def test_extended_generic_rules_subclassing(self): 1774 class T1(Tuple[T, KT]): ... 1775 class T2(Tuple[T, ...]): ... 1776 class C1(Callable[[T], T]): ... 1777 class C2(Callable[..., int]): 1778 def __call__(self): 1779 return None 1780 1781 self.assertEqual(T1.__parameters__, (T, KT)) 1782 self.assertEqual(T1[int, str].__args__, (int, str)) 1783 self.assertEqual(T1[int, T].__origin__, T1) 1784 1785 self.assertEqual(T2.__parameters__, (T,)) 1786 with self.assertRaises(TypeError): 1787 T1[int] 1788 with self.assertRaises(TypeError): 1789 T2[int, str] 1790 1791 self.assertEqual(repr(C1[int]).split('.')[-1], 'C1[int]') 1792 self.assertEqual(C2.__parameters__, ()) 1793 self.assertIsInstance(C2(), collections.abc.Callable) 1794 self.assertIsSubclass(C2, collections.abc.Callable) 1795 self.assertIsSubclass(C1, collections.abc.Callable) 1796 self.assertIsInstance(T1(), tuple) 1797 self.assertIsSubclass(T2, tuple) 1798 with self.assertRaises(TypeError): 1799 issubclass(Tuple[int, ...], typing.Sequence) 1800 with self.assertRaises(TypeError): 1801 issubclass(Tuple[int, ...], typing.Iterable) 1802 1803 def test_fail_with_bare_union(self): 1804 with self.assertRaises(TypeError): 1805 List[Union] 1806 with self.assertRaises(TypeError): 1807 Tuple[Optional] 1808 with self.assertRaises(TypeError): 1809 ClassVar[ClassVar] 1810 with self.assertRaises(TypeError): 1811 List[ClassVar[int]] 1812 1813 def test_fail_with_bare_generic(self): 1814 T = TypeVar('T') 1815 with self.assertRaises(TypeError): 1816 List[Generic] 1817 with self.assertRaises(TypeError): 1818 Tuple[Generic[T]] 1819 with self.assertRaises(TypeError): 1820 List[typing.Protocol] 1821 1822 def test_type_erasure_special(self): 1823 T = TypeVar('T') 1824 # this is the only test that checks type caching 1825 self.clear_caches() 1826 class MyTup(Tuple[T, T]): ... 1827 self.assertIs(MyTup[int]().__class__, MyTup) 1828 self.assertIs(MyTup[int]().__orig_class__, MyTup[int]) 1829 class MyCall(Callable[..., T]): 1830 def __call__(self): return None 1831 self.assertIs(MyCall[T]().__class__, MyCall) 1832 self.assertIs(MyCall[T]().__orig_class__, MyCall[T]) 1833 class MyDict(typing.Dict[T, T]): ... 1834 self.assertIs(MyDict[int]().__class__, MyDict) 1835 self.assertIs(MyDict[int]().__orig_class__, MyDict[int]) 1836 class MyDef(typing.DefaultDict[str, T]): ... 1837 self.assertIs(MyDef[int]().__class__, MyDef) 1838 self.assertIs(MyDef[int]().__orig_class__, MyDef[int]) 1839 # ChainMap was added in 3.3 1840 if sys.version_info >= (3, 3): 1841 class MyChain(typing.ChainMap[str, T]): ... 1842 self.assertIs(MyChain[int]().__class__, MyChain) 1843 self.assertIs(MyChain[int]().__orig_class__, MyChain[int]) 1844 1845 def test_all_repr_eq_any(self): 1846 objs = (getattr(typing, el) for el in typing.__all__) 1847 for obj in objs: 1848 self.assertNotEqual(repr(obj), '') 1849 self.assertEqual(obj, obj) 1850 if getattr(obj, '__parameters__', None) and len(obj.__parameters__) == 1: 1851 self.assertEqual(obj[Any].__args__, (Any,)) 1852 if isinstance(obj, type): 1853 for base in obj.__mro__: 1854 self.assertNotEqual(repr(base), '') 1855 self.assertEqual(base, base) 1856 1857 def test_pickle(self): 1858 global C # pickle wants to reference the class by name 1859 T = TypeVar('T') 1860 1861 class B(Generic[T]): 1862 pass 1863 1864 class C(B[int]): 1865 pass 1866 1867 c = C() 1868 c.foo = 42 1869 c.bar = 'abc' 1870 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 1871 z = pickle.dumps(c, proto) 1872 x = pickle.loads(z) 1873 self.assertEqual(x.foo, 42) 1874 self.assertEqual(x.bar, 'abc') 1875 self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) 1876 samples = [Any, Union, Tuple, Callable, ClassVar, 1877 Union[int, str], ClassVar[List], Tuple[int, ...], Callable[[str], bytes], 1878 typing.DefaultDict, typing.FrozenSet[int]] 1879 for s in samples: 1880 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 1881 z = pickle.dumps(s, proto) 1882 x = pickle.loads(z) 1883 self.assertEqual(s, x) 1884 more_samples = [List, typing.Iterable, typing.Type, List[int], 1885 typing.Type[typing.Mapping], typing.AbstractSet[Tuple[int, str]]] 1886 for s in more_samples: 1887 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 1888 z = pickle.dumps(s, proto) 1889 x = pickle.loads(z) 1890 self.assertEqual(s, x) 1891 1892 def test_copy_and_deepcopy(self): 1893 T = TypeVar('T') 1894 class Node(Generic[T]): ... 1895 things = [Union[T, int], Tuple[T, int], Callable[..., T], Callable[[int], int], 1896 Tuple[Any, Any], Node[T], Node[int], Node[Any], typing.Iterable[T], 1897 typing.Iterable[Any], typing.Iterable[int], typing.Dict[int, str], 1898 typing.Dict[T, Any], ClassVar[int], ClassVar[List[T]], Tuple['T', 'T'], 1899 Union['T', int], List['T'], typing.Mapping['T', int]] 1900 for t in things + [Any]: 1901 self.assertEqual(t, copy(t)) 1902 self.assertEqual(t, deepcopy(t)) 1903 1904 def test_immutability_by_copy_and_pickle(self): 1905 # Special forms like Union, Any, etc., generic aliases to containers like List, 1906 # Mapping, etc., and type variabcles are considered immutable by copy and pickle. 1907 global TP, TPB, TPV # for pickle 1908 TP = TypeVar('TP') 1909 TPB = TypeVar('TPB', bound=int) 1910 TPV = TypeVar('TPV', bytes, str) 1911 for X in [TP, TPB, TPV, List, typing.Mapping, ClassVar, typing.Iterable, 1912 Union, Any, Tuple, Callable]: 1913 self.assertIs(copy(X), X) 1914 self.assertIs(deepcopy(X), X) 1915 self.assertIs(pickle.loads(pickle.dumps(X)), X) 1916 # Check that local type variables are copyable. 1917 TL = TypeVar('TL') 1918 TLB = TypeVar('TLB', bound=int) 1919 TLV = TypeVar('TLV', bytes, str) 1920 for X in [TL, TLB, TLV]: 1921 self.assertIs(copy(X), X) 1922 self.assertIs(deepcopy(X), X) 1923 1924 def test_copy_generic_instances(self): 1925 T = TypeVar('T') 1926 class C(Generic[T]): 1927 def __init__(self, attr: T) -> None: 1928 self.attr = attr 1929 1930 c = C(42) 1931 self.assertEqual(copy(c).attr, 42) 1932 self.assertEqual(deepcopy(c).attr, 42) 1933 self.assertIsNot(copy(c), c) 1934 self.assertIsNot(deepcopy(c), c) 1935 c.attr = 1 1936 self.assertEqual(copy(c).attr, 1) 1937 self.assertEqual(deepcopy(c).attr, 1) 1938 ci = C[int](42) 1939 self.assertEqual(copy(ci).attr, 42) 1940 self.assertEqual(deepcopy(ci).attr, 42) 1941 self.assertIsNot(copy(ci), ci) 1942 self.assertIsNot(deepcopy(ci), ci) 1943 ci.attr = 1 1944 self.assertEqual(copy(ci).attr, 1) 1945 self.assertEqual(deepcopy(ci).attr, 1) 1946 self.assertEqual(ci.__orig_class__, C[int]) 1947 1948 def test_weakref_all(self): 1949 T = TypeVar('T') 1950 things = [Any, Union[T, int], Callable[..., T], Tuple[Any, Any], 1951 Optional[List[int]], typing.Mapping[int, str], 1952 typing.re.Match[bytes], typing.Iterable['whatever']] 1953 for t in things: 1954 self.assertEqual(weakref.ref(t)(), t) 1955 1956 def test_parameterized_slots(self): 1957 T = TypeVar('T') 1958 class C(Generic[T]): 1959 __slots__ = ('potato',) 1960 1961 c = C() 1962 c_int = C[int]() 1963 1964 c.potato = 0 1965 c_int.potato = 0 1966 with self.assertRaises(AttributeError): 1967 c.tomato = 0 1968 with self.assertRaises(AttributeError): 1969 c_int.tomato = 0 1970 1971 def foo(x: C['C']): ... 1972 self.assertEqual(get_type_hints(foo, globals(), locals())['x'], C[C]) 1973 self.assertEqual(copy(C[int]), deepcopy(C[int])) 1974 1975 def test_parameterized_slots_dict(self): 1976 T = TypeVar('T') 1977 class D(Generic[T]): 1978 __slots__ = {'banana': 42} 1979 1980 d = D() 1981 d_int = D[int]() 1982 1983 d.banana = 'yes' 1984 d_int.banana = 'yes' 1985 with self.assertRaises(AttributeError): 1986 d.foobar = 'no' 1987 with self.assertRaises(AttributeError): 1988 d_int.foobar = 'no' 1989 1990 def test_errors(self): 1991 with self.assertRaises(TypeError): 1992 B = SimpleMapping[XK, Any] 1993 1994 class C(Generic[B]): 1995 pass 1996 1997 def test_repr_2(self): 1998 class C(Generic[T]): 1999 pass 2000 2001 self.assertEqual(C.__module__, __name__) 2002 self.assertEqual(C.__qualname__, 2003 'GenericTests.test_repr_2.<locals>.C') 2004 X = C[int] 2005 self.assertEqual(X.__module__, __name__) 2006 self.assertEqual(repr(X).split('.')[-1], 'C[int]') 2007 2008 class Y(C[int]): 2009 pass 2010 2011 self.assertEqual(Y.__module__, __name__) 2012 self.assertEqual(Y.__qualname__, 2013 'GenericTests.test_repr_2.<locals>.Y') 2014 2015 def test_eq_1(self): 2016 self.assertEqual(Generic, Generic) 2017 self.assertEqual(Generic[T], Generic[T]) 2018 self.assertNotEqual(Generic[KT], Generic[VT]) 2019 2020 def test_eq_2(self): 2021 2022 class A(Generic[T]): 2023 pass 2024 2025 class B(Generic[T]): 2026 pass 2027 2028 self.assertEqual(A, A) 2029 self.assertNotEqual(A, B) 2030 self.assertEqual(A[T], A[T]) 2031 self.assertNotEqual(A[T], B[T]) 2032 2033 def test_multiple_inheritance(self): 2034 2035 class A(Generic[T, VT]): 2036 pass 2037 2038 class B(Generic[KT, T]): 2039 pass 2040 2041 class C(A[T, VT], Generic[VT, T, KT], B[KT, T]): 2042 pass 2043 2044 self.assertEqual(C.__parameters__, (VT, T, KT)) 2045 2046 def test_multiple_inheritance_special(self): 2047 S = TypeVar('S') 2048 class B(Generic[S]): ... 2049 class C(List[int], B): ... 2050 self.assertEqual(C.__mro__, (C, list, B, Generic, object)) 2051 2052 def test_init_subclass_super_called(self): 2053 class FinalException(Exception): 2054 pass 2055 2056 class Final: 2057 def __init_subclass__(cls, **kwargs) -> None: 2058 for base in cls.__bases__: 2059 if base is not Final and issubclass(base, Final): 2060 raise FinalException(base) 2061 super().__init_subclass__(**kwargs) 2062 class Test(Generic[T], Final): 2063 pass 2064 with self.assertRaises(FinalException): 2065 class Subclass(Test): 2066 pass 2067 with self.assertRaises(FinalException): 2068 class Subclass(Test[int]): 2069 pass 2070 2071 def test_nested(self): 2072 2073 G = Generic 2074 2075 class Visitor(G[T]): 2076 2077 a = None 2078 2079 def set(self, a: T): 2080 self.a = a 2081 2082 def get(self): 2083 return self.a 2084 2085 def visit(self) -> T: 2086 return self.a 2087 2088 V = Visitor[typing.List[int]] 2089 2090 class IntListVisitor(V): 2091 2092 def append(self, x: int): 2093 self.a.append(x) 2094 2095 a = IntListVisitor() 2096 a.set([]) 2097 a.append(1) 2098 a.append(42) 2099 self.assertEqual(a.get(), [1, 42]) 2100 2101 def test_type_erasure(self): 2102 T = TypeVar('T') 2103 2104 class Node(Generic[T]): 2105 def __init__(self, label: T, 2106 left: 'Node[T]' = None, 2107 right: 'Node[T]' = None): 2108 self.label = label # type: T 2109 self.left = left # type: Optional[Node[T]] 2110 self.right = right # type: Optional[Node[T]] 2111 2112 def foo(x: T): 2113 a = Node(x) 2114 b = Node[T](x) 2115 c = Node[Any](x) 2116 self.assertIs(type(a), Node) 2117 self.assertIs(type(b), Node) 2118 self.assertIs(type(c), Node) 2119 self.assertEqual(a.label, x) 2120 self.assertEqual(b.label, x) 2121 self.assertEqual(c.label, x) 2122 2123 foo(42) 2124 2125 def test_implicit_any(self): 2126 T = TypeVar('T') 2127 2128 class C(Generic[T]): 2129 pass 2130 2131 class D(C): 2132 pass 2133 2134 self.assertEqual(D.__parameters__, ()) 2135 2136 with self.assertRaises(Exception): 2137 D[int] 2138 with self.assertRaises(Exception): 2139 D[Any] 2140 with self.assertRaises(Exception): 2141 D[T] 2142 2143 def test_new_with_args(self): 2144 2145 class A(Generic[T]): 2146 pass 2147 2148 class B: 2149 def __new__(cls, arg): 2150 # call object 2151 obj = super().__new__(cls) 2152 obj.arg = arg 2153 return obj 2154 2155 # mro: C, A, Generic, B, object 2156 class C(A, B): 2157 pass 2158 2159 c = C('foo') 2160 self.assertEqual(c.arg, 'foo') 2161 2162 def test_new_with_args2(self): 2163 2164 class A: 2165 def __init__(self, arg): 2166 self.from_a = arg 2167 # call object 2168 super().__init__() 2169 2170 # mro: C, Generic, A, object 2171 class C(Generic[T], A): 2172 def __init__(self, arg): 2173 self.from_c = arg 2174 # call Generic 2175 super().__init__(arg) 2176 2177 c = C('foo') 2178 self.assertEqual(c.from_a, 'foo') 2179 self.assertEqual(c.from_c, 'foo') 2180 2181 def test_new_no_args(self): 2182 2183 class A(Generic[T]): 2184 pass 2185 2186 with self.assertRaises(TypeError): 2187 A('foo') 2188 2189 class B: 2190 def __new__(cls): 2191 # call object 2192 obj = super().__new__(cls) 2193 obj.from_b = 'b' 2194 return obj 2195 2196 # mro: C, A, Generic, B, object 2197 class C(A, B): 2198 def __init__(self, arg): 2199 self.arg = arg 2200 2201 def __new__(cls, arg): 2202 # call A 2203 obj = super().__new__(cls) 2204 obj.from_c = 'c' 2205 return obj 2206 2207 c = C('foo') 2208 self.assertEqual(c.arg, 'foo') 2209 self.assertEqual(c.from_b, 'b') 2210 self.assertEqual(c.from_c, 'c') 2211 2212 2213class ClassVarTests(BaseTestCase): 2214 2215 def test_basics(self): 2216 with self.assertRaises(TypeError): 2217 ClassVar[1] 2218 with self.assertRaises(TypeError): 2219 ClassVar[int, str] 2220 with self.assertRaises(TypeError): 2221 ClassVar[int][str] 2222 2223 def test_repr(self): 2224 self.assertEqual(repr(ClassVar), 'typing.ClassVar') 2225 cv = ClassVar[int] 2226 self.assertEqual(repr(cv), 'typing.ClassVar[int]') 2227 cv = ClassVar[Employee] 2228 self.assertEqual(repr(cv), 'typing.ClassVar[%s.Employee]' % __name__) 2229 2230 def test_cannot_subclass(self): 2231 with self.assertRaises(TypeError): 2232 class C(type(ClassVar)): 2233 pass 2234 with self.assertRaises(TypeError): 2235 class C(type(ClassVar[int])): 2236 pass 2237 2238 def test_cannot_init(self): 2239 with self.assertRaises(TypeError): 2240 ClassVar() 2241 with self.assertRaises(TypeError): 2242 type(ClassVar)() 2243 with self.assertRaises(TypeError): 2244 type(ClassVar[Optional[int]])() 2245 2246 def test_no_isinstance(self): 2247 with self.assertRaises(TypeError): 2248 isinstance(1, ClassVar[int]) 2249 with self.assertRaises(TypeError): 2250 issubclass(int, ClassVar) 2251 2252 2253class FinalTests(BaseTestCase): 2254 2255 def test_basics(self): 2256 Final[int] # OK 2257 with self.assertRaises(TypeError): 2258 Final[1] 2259 with self.assertRaises(TypeError): 2260 Final[int, str] 2261 with self.assertRaises(TypeError): 2262 Final[int][str] 2263 with self.assertRaises(TypeError): 2264 Optional[Final[int]] 2265 2266 def test_repr(self): 2267 self.assertEqual(repr(Final), 'typing.Final') 2268 cv = Final[int] 2269 self.assertEqual(repr(cv), 'typing.Final[int]') 2270 cv = Final[Employee] 2271 self.assertEqual(repr(cv), 'typing.Final[%s.Employee]' % __name__) 2272 2273 def test_cannot_subclass(self): 2274 with self.assertRaises(TypeError): 2275 class C(type(Final)): 2276 pass 2277 with self.assertRaises(TypeError): 2278 class C(type(Final[int])): 2279 pass 2280 2281 def test_cannot_init(self): 2282 with self.assertRaises(TypeError): 2283 Final() 2284 with self.assertRaises(TypeError): 2285 type(Final)() 2286 with self.assertRaises(TypeError): 2287 type(Final[Optional[int]])() 2288 2289 def test_no_isinstance(self): 2290 with self.assertRaises(TypeError): 2291 isinstance(1, Final[int]) 2292 with self.assertRaises(TypeError): 2293 issubclass(int, Final) 2294 2295 def test_final_unmodified(self): 2296 def func(x): ... 2297 self.assertIs(func, final(func)) 2298 2299 2300class CastTests(BaseTestCase): 2301 2302 def test_basics(self): 2303 self.assertEqual(cast(int, 42), 42) 2304 self.assertEqual(cast(float, 42), 42) 2305 self.assertIs(type(cast(float, 42)), int) 2306 self.assertEqual(cast(Any, 42), 42) 2307 self.assertEqual(cast(list, 42), 42) 2308 self.assertEqual(cast(Union[str, float], 42), 42) 2309 self.assertEqual(cast(AnyStr, 42), 42) 2310 self.assertEqual(cast(None, 42), 42) 2311 2312 def test_errors(self): 2313 # Bogus calls are not expected to fail. 2314 cast(42, 42) 2315 cast('hello', 42) 2316 2317 2318class ForwardRefTests(BaseTestCase): 2319 2320 def test_basics(self): 2321 2322 class Node(Generic[T]): 2323 2324 def __init__(self, label: T): 2325 self.label = label 2326 self.left = self.right = None 2327 2328 def add_both(self, 2329 left: 'Optional[Node[T]]', 2330 right: 'Node[T]' = None, 2331 stuff: int = None, 2332 blah=None): 2333 self.left = left 2334 self.right = right 2335 2336 def add_left(self, node: Optional['Node[T]']): 2337 self.add_both(node, None) 2338 2339 def add_right(self, node: 'Node[T]' = None): 2340 self.add_both(None, node) 2341 2342 t = Node[int] 2343 both_hints = get_type_hints(t.add_both, globals(), locals()) 2344 self.assertEqual(both_hints['left'], Optional[Node[T]]) 2345 self.assertEqual(both_hints['right'], Optional[Node[T]]) 2346 self.assertEqual(both_hints['left'], both_hints['right']) 2347 self.assertEqual(both_hints['stuff'], Optional[int]) 2348 self.assertNotIn('blah', both_hints) 2349 2350 left_hints = get_type_hints(t.add_left, globals(), locals()) 2351 self.assertEqual(left_hints['node'], Optional[Node[T]]) 2352 2353 right_hints = get_type_hints(t.add_right, globals(), locals()) 2354 self.assertEqual(right_hints['node'], Optional[Node[T]]) 2355 2356 def test_forwardref_instance_type_error(self): 2357 fr = typing.ForwardRef('int') 2358 with self.assertRaises(TypeError): 2359 isinstance(42, fr) 2360 2361 def test_forwardref_subclass_type_error(self): 2362 fr = typing.ForwardRef('int') 2363 with self.assertRaises(TypeError): 2364 issubclass(int, fr) 2365 2366 def test_forward_equality(self): 2367 fr = typing.ForwardRef('int') 2368 self.assertEqual(fr, typing.ForwardRef('int')) 2369 self.assertNotEqual(List['int'], List[int]) 2370 2371 def test_forward_equality_gth(self): 2372 c1 = typing.ForwardRef('C') 2373 c1_gth = typing.ForwardRef('C') 2374 c2 = typing.ForwardRef('C') 2375 c2_gth = typing.ForwardRef('C') 2376 2377 class C: 2378 pass 2379 def foo(a: c1_gth, b: c2_gth): 2380 pass 2381 2382 self.assertEqual(get_type_hints(foo, globals(), locals()), {'a': C, 'b': C}) 2383 self.assertEqual(c1, c2) 2384 self.assertEqual(c1, c1_gth) 2385 self.assertEqual(c1_gth, c2_gth) 2386 self.assertEqual(List[c1], List[c1_gth]) 2387 self.assertNotEqual(List[c1], List[C]) 2388 self.assertNotEqual(List[c1_gth], List[C]) 2389 self.assertEqual(Union[c1, c1_gth], Union[c1]) 2390 self.assertEqual(Union[c1, c1_gth, int], Union[c1, int]) 2391 2392 def test_forward_equality_hash(self): 2393 c1 = typing.ForwardRef('int') 2394 c1_gth = typing.ForwardRef('int') 2395 c2 = typing.ForwardRef('int') 2396 c2_gth = typing.ForwardRef('int') 2397 2398 def foo(a: c1_gth, b: c2_gth): 2399 pass 2400 get_type_hints(foo, globals(), locals()) 2401 2402 self.assertEqual(hash(c1), hash(c2)) 2403 self.assertEqual(hash(c1_gth), hash(c2_gth)) 2404 self.assertEqual(hash(c1), hash(c1_gth)) 2405 2406 def test_forward_equality_namespace(self): 2407 class A: 2408 pass 2409 def namespace1(): 2410 a = typing.ForwardRef('A') 2411 def fun(x: a): 2412 pass 2413 get_type_hints(fun, globals(), locals()) 2414 return a 2415 2416 def namespace2(): 2417 a = typing.ForwardRef('A') 2418 2419 class A: 2420 pass 2421 def fun(x: a): 2422 pass 2423 2424 get_type_hints(fun, globals(), locals()) 2425 return a 2426 2427 self.assertEqual(namespace1(), namespace1()) 2428 self.assertNotEqual(namespace1(), namespace2()) 2429 2430 def test_forward_repr(self): 2431 self.assertEqual(repr(List['int']), "typing.List[ForwardRef('int')]") 2432 2433 def test_union_forward(self): 2434 2435 def foo(a: Union['T']): 2436 pass 2437 2438 self.assertEqual(get_type_hints(foo, globals(), locals()), 2439 {'a': Union[T]}) 2440 2441 def test_tuple_forward(self): 2442 2443 def foo(a: Tuple['T']): 2444 pass 2445 2446 self.assertEqual(get_type_hints(foo, globals(), locals()), 2447 {'a': Tuple[T]}) 2448 2449 def test_forward_recursion_actually(self): 2450 def namespace1(): 2451 a = typing.ForwardRef('A') 2452 A = a 2453 def fun(x: a): pass 2454 2455 ret = get_type_hints(fun, globals(), locals()) 2456 return a 2457 2458 def namespace2(): 2459 a = typing.ForwardRef('A') 2460 A = a 2461 def fun(x: a): pass 2462 2463 ret = get_type_hints(fun, globals(), locals()) 2464 return a 2465 2466 def cmp(o1, o2): 2467 return o1 == o2 2468 2469 r1 = namespace1() 2470 r2 = namespace2() 2471 self.assertIsNot(r1, r2) 2472 self.assertRaises(RecursionError, cmp, r1, r2) 2473 2474 def test_union_forward_recursion(self): 2475 ValueList = List['Value'] 2476 Value = Union[str, ValueList] 2477 2478 class C: 2479 foo: List[Value] 2480 class D: 2481 foo: Union[Value, ValueList] 2482 class E: 2483 foo: Union[List[Value], ValueList] 2484 class F: 2485 foo: Union[Value, List[Value], ValueList] 2486 2487 self.assertEqual(get_type_hints(C, globals(), locals()), get_type_hints(C, globals(), locals())) 2488 self.assertEqual(get_type_hints(C, globals(), locals()), 2489 {'foo': List[Union[str, List[Union[str, List['Value']]]]]}) 2490 self.assertEqual(get_type_hints(D, globals(), locals()), 2491 {'foo': Union[str, List[Union[str, List['Value']]]]}) 2492 self.assertEqual(get_type_hints(E, globals(), locals()), 2493 {'foo': Union[ 2494 List[Union[str, List[Union[str, List['Value']]]]], 2495 List[Union[str, List['Value']]] 2496 ] 2497 }) 2498 self.assertEqual(get_type_hints(F, globals(), locals()), 2499 {'foo': Union[ 2500 str, 2501 List[Union[str, List['Value']]], 2502 List[Union[str, List[Union[str, List['Value']]]]] 2503 ] 2504 }) 2505 2506 def test_callable_forward(self): 2507 2508 def foo(a: Callable[['T'], 'T']): 2509 pass 2510 2511 self.assertEqual(get_type_hints(foo, globals(), locals()), 2512 {'a': Callable[[T], T]}) 2513 2514 def test_callable_with_ellipsis_forward(self): 2515 2516 def foo(a: 'Callable[..., T]'): 2517 pass 2518 2519 self.assertEqual(get_type_hints(foo, globals(), locals()), 2520 {'a': Callable[..., T]}) 2521 2522 def test_syntax_error(self): 2523 2524 with self.assertRaises(SyntaxError): 2525 Generic['/T'] 2526 2527 def test_delayed_syntax_error(self): 2528 2529 def foo(a: 'Node[T'): 2530 pass 2531 2532 with self.assertRaises(SyntaxError): 2533 get_type_hints(foo) 2534 2535 def test_type_error(self): 2536 2537 def foo(a: Tuple['42']): 2538 pass 2539 2540 with self.assertRaises(TypeError): 2541 get_type_hints(foo) 2542 2543 def test_name_error(self): 2544 2545 def foo(a: 'Noode[T]'): 2546 pass 2547 2548 with self.assertRaises(NameError): 2549 get_type_hints(foo, locals()) 2550 2551 def test_no_type_check(self): 2552 2553 @no_type_check 2554 def foo(a: 'whatevers') -> {}: 2555 pass 2556 2557 th = get_type_hints(foo) 2558 self.assertEqual(th, {}) 2559 2560 def test_no_type_check_class(self): 2561 2562 @no_type_check 2563 class C: 2564 def foo(a: 'whatevers') -> {}: 2565 pass 2566 2567 cth = get_type_hints(C.foo) 2568 self.assertEqual(cth, {}) 2569 ith = get_type_hints(C().foo) 2570 self.assertEqual(ith, {}) 2571 2572 def test_no_type_check_no_bases(self): 2573 class C: 2574 def meth(self, x: int): ... 2575 @no_type_check 2576 class D(C): 2577 c = C 2578 # verify that @no_type_check never affects bases 2579 self.assertEqual(get_type_hints(C.meth), {'x': int}) 2580 2581 def test_no_type_check_forward_ref_as_string(self): 2582 class C: 2583 foo: typing.ClassVar[int] = 7 2584 class D: 2585 foo: ClassVar[int] = 7 2586 class E: 2587 foo: 'typing.ClassVar[int]' = 7 2588 class F: 2589 foo: 'ClassVar[int]' = 7 2590 2591 expected_result = {'foo': typing.ClassVar[int]} 2592 for clazz in [C, D, E, F]: 2593 self.assertEqual(get_type_hints(clazz), expected_result) 2594 2595 def test_nested_classvar_fails_forward_ref_check(self): 2596 class E: 2597 foo: 'typing.ClassVar[typing.ClassVar[int]]' = 7 2598 class F: 2599 foo: ClassVar['ClassVar[int]'] = 7 2600 2601 for clazz in [E, F]: 2602 with self.assertRaises(TypeError): 2603 get_type_hints(clazz) 2604 2605 def test_meta_no_type_check(self): 2606 2607 @no_type_check_decorator 2608 def magic_decorator(func): 2609 return func 2610 2611 self.assertEqual(magic_decorator.__name__, 'magic_decorator') 2612 2613 @magic_decorator 2614 def foo(a: 'whatevers') -> {}: 2615 pass 2616 2617 @magic_decorator 2618 class C: 2619 def foo(a: 'whatevers') -> {}: 2620 pass 2621 2622 self.assertEqual(foo.__name__, 'foo') 2623 th = get_type_hints(foo) 2624 self.assertEqual(th, {}) 2625 cth = get_type_hints(C.foo) 2626 self.assertEqual(cth, {}) 2627 ith = get_type_hints(C().foo) 2628 self.assertEqual(ith, {}) 2629 2630 def test_default_globals(self): 2631 code = ("class C:\n" 2632 " def foo(self, a: 'C') -> 'D': pass\n" 2633 "class D:\n" 2634 " def bar(self, b: 'D') -> C: pass\n" 2635 ) 2636 ns = {} 2637 exec(code, ns) 2638 hints = get_type_hints(ns['C'].foo) 2639 self.assertEqual(hints, {'a': ns['C'], 'return': ns['D']}) 2640 2641 def test_final_forward_ref(self): 2642 self.assertEqual(gth(Loop, globals())['attr'], Final[Loop]) 2643 self.assertNotEqual(gth(Loop, globals())['attr'], Final[int]) 2644 self.assertNotEqual(gth(Loop, globals())['attr'], Final) 2645 2646 2647class OverloadTests(BaseTestCase): 2648 2649 def test_overload_fails(self): 2650 from typing import overload 2651 2652 with self.assertRaises(RuntimeError): 2653 2654 @overload 2655 def blah(): 2656 pass 2657 2658 blah() 2659 2660 def test_overload_succeeds(self): 2661 from typing import overload 2662 2663 @overload 2664 def blah(): 2665 pass 2666 2667 def blah(): 2668 pass 2669 2670 blah() 2671 2672 2673ASYNCIO_TESTS = """ 2674import asyncio 2675 2676T_a = TypeVar('T_a') 2677 2678class AwaitableWrapper(typing.Awaitable[T_a]): 2679 2680 def __init__(self, value): 2681 self.value = value 2682 2683 def __await__(self) -> typing.Iterator[T_a]: 2684 yield 2685 return self.value 2686 2687class AsyncIteratorWrapper(typing.AsyncIterator[T_a]): 2688 2689 def __init__(self, value: typing.Iterable[T_a]): 2690 self.value = value 2691 2692 def __aiter__(self) -> typing.AsyncIterator[T_a]: 2693 return self 2694 2695 async def __anext__(self) -> T_a: 2696 data = await self.value 2697 if data: 2698 return data 2699 else: 2700 raise StopAsyncIteration 2701 2702class ACM: 2703 async def __aenter__(self) -> int: 2704 return 42 2705 async def __aexit__(self, etype, eval, tb): 2706 return None 2707""" 2708 2709try: 2710 exec(ASYNCIO_TESTS) 2711except ImportError: 2712 ASYNCIO = False # multithreading is not enabled 2713else: 2714 ASYNCIO = True 2715 2716# Definitions needed for features introduced in Python 3.6 2717 2718from test import ann_module, ann_module2, ann_module3 2719from typing import AsyncContextManager 2720 2721class A: 2722 y: float 2723class B(A): 2724 x: ClassVar[Optional['B']] = None 2725 y: int 2726 b: int 2727class CSub(B): 2728 z: ClassVar['CSub'] = B() 2729class G(Generic[T]): 2730 lst: ClassVar[List[T]] = [] 2731 2732class Loop: 2733 attr: Final['Loop'] 2734 2735class NoneAndForward: 2736 parent: 'NoneAndForward' 2737 meaning: None 2738 2739class CoolEmployee(NamedTuple): 2740 name: str 2741 cool: int 2742 2743class CoolEmployeeWithDefault(NamedTuple): 2744 name: str 2745 cool: int = 0 2746 2747class XMeth(NamedTuple): 2748 x: int 2749 def double(self): 2750 return 2 * self.x 2751 2752class XRepr(NamedTuple): 2753 x: int 2754 y: int = 1 2755 def __str__(self): 2756 return f'{self.x} -> {self.y}' 2757 def __add__(self, other): 2758 return 0 2759 2760Label = TypedDict('Label', [('label', str)]) 2761 2762class Point2D(TypedDict): 2763 x: int 2764 y: int 2765 2766class LabelPoint2D(Point2D, Label): ... 2767 2768class Options(TypedDict, total=False): 2769 log_level: int 2770 log_path: str 2771 2772class HasForeignBaseClass(mod_generics_cache.A): 2773 some_xrepr: 'XRepr' 2774 other_a: 'mod_generics_cache.A' 2775 2776async def g_with(am: AsyncContextManager[int]): 2777 x: int 2778 async with am as x: 2779 return x 2780 2781try: 2782 g_with(ACM()).send(None) 2783except StopIteration as e: 2784 assert e.args[0] == 42 2785 2786gth = get_type_hints 2787 2788class ForRefExample: 2789 @ann_module.dec 2790 def func(self: 'ForRefExample'): 2791 pass 2792 2793 @ann_module.dec 2794 @ann_module.dec 2795 def nested(self: 'ForRefExample'): 2796 pass 2797 2798 2799class GetTypeHintTests(BaseTestCase): 2800 def test_get_type_hints_from_various_objects(self): 2801 # For invalid objects should fail with TypeError (not AttributeError etc). 2802 with self.assertRaises(TypeError): 2803 gth(123) 2804 with self.assertRaises(TypeError): 2805 gth('abc') 2806 with self.assertRaises(TypeError): 2807 gth(None) 2808 2809 def test_get_type_hints_modules(self): 2810 ann_module_type_hints = {1: 2, 'f': Tuple[int, int], 'x': int, 'y': str} 2811 self.assertEqual(gth(ann_module), ann_module_type_hints) 2812 self.assertEqual(gth(ann_module2), {}) 2813 self.assertEqual(gth(ann_module3), {}) 2814 2815 @skip("known bug") 2816 def test_get_type_hints_modules_forwardref(self): 2817 # FIXME: This currently exposes a bug in typing. Cached forward references 2818 # don't account for the case where there are multiple types of the same 2819 # name coming from different modules in the same program. 2820 mgc_hints = {'default_a': Optional[mod_generics_cache.A], 2821 'default_b': Optional[mod_generics_cache.B]} 2822 self.assertEqual(gth(mod_generics_cache), mgc_hints) 2823 2824 def test_get_type_hints_classes(self): 2825 self.assertEqual(gth(ann_module.C), # gth will find the right globalns 2826 {'y': Optional[ann_module.C]}) 2827 self.assertIsInstance(gth(ann_module.j_class), dict) 2828 self.assertEqual(gth(ann_module.M), {'123': 123, 'o': type}) 2829 self.assertEqual(gth(ann_module.D), 2830 {'j': str, 'k': str, 'y': Optional[ann_module.C]}) 2831 self.assertEqual(gth(ann_module.Y), {'z': int}) 2832 self.assertEqual(gth(ann_module.h_class), 2833 {'y': Optional[ann_module.C]}) 2834 self.assertEqual(gth(ann_module.S), {'x': str, 'y': str}) 2835 self.assertEqual(gth(ann_module.foo), {'x': int}) 2836 self.assertEqual(gth(NoneAndForward), 2837 {'parent': NoneAndForward, 'meaning': type(None)}) 2838 self.assertEqual(gth(HasForeignBaseClass), 2839 {'some_xrepr': XRepr, 'other_a': mod_generics_cache.A, 2840 'some_b': mod_generics_cache.B}) 2841 self.assertEqual(gth(XRepr.__new__), 2842 {'x': int, 'y': int}) 2843 self.assertEqual(gth(mod_generics_cache.B), 2844 {'my_inner_a1': mod_generics_cache.B.A, 2845 'my_inner_a2': mod_generics_cache.B.A, 2846 'my_outer_a': mod_generics_cache.A}) 2847 2848 def test_respect_no_type_check(self): 2849 @no_type_check 2850 class NoTpCheck: 2851 class Inn: 2852 def __init__(self, x: 'not a type'): ... 2853 self.assertTrue(NoTpCheck.__no_type_check__) 2854 self.assertTrue(NoTpCheck.Inn.__init__.__no_type_check__) 2855 self.assertEqual(gth(ann_module2.NTC.meth), {}) 2856 class ABase(Generic[T]): 2857 def meth(x: int): ... 2858 @no_type_check 2859 class Der(ABase): ... 2860 self.assertEqual(gth(ABase.meth), {'x': int}) 2861 2862 def test_get_type_hints_for_builtins(self): 2863 # Should not fail for built-in classes and functions. 2864 self.assertEqual(gth(int), {}) 2865 self.assertEqual(gth(type), {}) 2866 self.assertEqual(gth(dir), {}) 2867 self.assertEqual(gth(len), {}) 2868 self.assertEqual(gth(object.__str__), {}) 2869 self.assertEqual(gth(object().__str__), {}) 2870 self.assertEqual(gth(str.join), {}) 2871 2872 def test_previous_behavior(self): 2873 def testf(x, y): ... 2874 testf.__annotations__['x'] = 'int' 2875 self.assertEqual(gth(testf), {'x': int}) 2876 def testg(x: None): ... 2877 self.assertEqual(gth(testg), {'x': type(None)}) 2878 2879 def test_get_type_hints_for_object_with_annotations(self): 2880 class A: ... 2881 class B: ... 2882 b = B() 2883 b.__annotations__ = {'x': 'A'} 2884 self.assertEqual(gth(b, locals()), {'x': A}) 2885 2886 def test_get_type_hints_ClassVar(self): 2887 self.assertEqual(gth(ann_module2.CV, ann_module2.__dict__), 2888 {'var': typing.ClassVar[ann_module2.CV]}) 2889 self.assertEqual(gth(B, globals()), 2890 {'y': int, 'x': ClassVar[Optional[B]], 'b': int}) 2891 self.assertEqual(gth(CSub, globals()), 2892 {'z': ClassVar[CSub], 'y': int, 'b': int, 2893 'x': ClassVar[Optional[B]]}) 2894 self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) 2895 2896 def test_get_type_hints_wrapped_decoratored_func(self): 2897 expects = {'self': ForRefExample} 2898 self.assertEqual(gth(ForRefExample.func), expects) 2899 self.assertEqual(gth(ForRefExample.nested), expects) 2900 2901 2902class GetUtilitiesTestCase(TestCase): 2903 def test_get_origin(self): 2904 T = TypeVar('T') 2905 class C(Generic[T]): pass 2906 self.assertIs(get_origin(C[int]), C) 2907 self.assertIs(get_origin(C[T]), C) 2908 self.assertIs(get_origin(int), None) 2909 self.assertIs(get_origin(ClassVar[int]), ClassVar) 2910 self.assertIs(get_origin(Union[int, str]), Union) 2911 self.assertIs(get_origin(Literal[42, 43]), Literal) 2912 self.assertIs(get_origin(Final[List[int]]), Final) 2913 self.assertIs(get_origin(Generic), Generic) 2914 self.assertIs(get_origin(Generic[T]), Generic) 2915 self.assertIs(get_origin(List[Tuple[T, T]][int]), list) 2916 self.assertIs(get_origin(List), list) 2917 self.assertIs(get_origin(Tuple), tuple) 2918 self.assertIs(get_origin(Callable), collections.abc.Callable) 2919 2920 def test_get_args(self): 2921 T = TypeVar('T') 2922 class C(Generic[T]): pass 2923 self.assertEqual(get_args(C[int]), (int,)) 2924 self.assertEqual(get_args(C[T]), (T,)) 2925 self.assertEqual(get_args(int), ()) 2926 self.assertEqual(get_args(ClassVar[int]), (int,)) 2927 self.assertEqual(get_args(Union[int, str]), (int, str)) 2928 self.assertEqual(get_args(Literal[42, 43]), (42, 43)) 2929 self.assertEqual(get_args(Final[List[int]]), (List[int],)) 2930 self.assertEqual(get_args(Union[int, Tuple[T, int]][str]), 2931 (int, Tuple[str, int])) 2932 self.assertEqual(get_args(typing.Dict[int, Tuple[T, T]][Optional[int]]), 2933 (int, Tuple[Optional[int], Optional[int]])) 2934 self.assertEqual(get_args(Callable[[], T][int]), ([], int)) 2935 self.assertEqual(get_args(Callable[..., int]), (..., int)) 2936 self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]), 2937 (int, Callable[[Tuple[T, ...]], str])) 2938 self.assertEqual(get_args(Tuple[int, ...]), (int, ...)) 2939 self.assertEqual(get_args(Tuple[()]), ((),)) 2940 self.assertEqual(get_args(List), ()) 2941 self.assertEqual(get_args(Tuple), ()) 2942 self.assertEqual(get_args(Callable), ()) 2943 2944 2945class CollectionsAbcTests(BaseTestCase): 2946 2947 def test_hashable(self): 2948 self.assertIsInstance(42, typing.Hashable) 2949 self.assertNotIsInstance([], typing.Hashable) 2950 2951 def test_iterable(self): 2952 self.assertIsInstance([], typing.Iterable) 2953 # Due to ABC caching, the second time takes a separate code 2954 # path and could fail. So call this a few times. 2955 self.assertIsInstance([], typing.Iterable) 2956 self.assertIsInstance([], typing.Iterable) 2957 self.assertNotIsInstance(42, typing.Iterable) 2958 # Just in case, also test issubclass() a few times. 2959 self.assertIsSubclass(list, typing.Iterable) 2960 self.assertIsSubclass(list, typing.Iterable) 2961 2962 def test_iterator(self): 2963 it = iter([]) 2964 self.assertIsInstance(it, typing.Iterator) 2965 self.assertNotIsInstance(42, typing.Iterator) 2966 2967 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 2968 def test_awaitable(self): 2969 ns = {} 2970 exec( 2971 "async def foo() -> typing.Awaitable[int]:\n" 2972 " return await AwaitableWrapper(42)\n", 2973 globals(), ns) 2974 foo = ns['foo'] 2975 g = foo() 2976 self.assertIsInstance(g, typing.Awaitable) 2977 self.assertNotIsInstance(foo, typing.Awaitable) 2978 g.send(None) # Run foo() till completion, to avoid warning. 2979 2980 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 2981 def test_coroutine(self): 2982 ns = {} 2983 exec( 2984 "async def foo():\n" 2985 " return\n", 2986 globals(), ns) 2987 foo = ns['foo'] 2988 g = foo() 2989 self.assertIsInstance(g, typing.Coroutine) 2990 with self.assertRaises(TypeError): 2991 isinstance(g, typing.Coroutine[int]) 2992 self.assertNotIsInstance(foo, typing.Coroutine) 2993 try: 2994 g.send(None) 2995 except StopIteration: 2996 pass 2997 2998 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 2999 def test_async_iterable(self): 3000 base_it = range(10) # type: Iterator[int] 3001 it = AsyncIteratorWrapper(base_it) 3002 self.assertIsInstance(it, typing.AsyncIterable) 3003 self.assertIsInstance(it, typing.AsyncIterable) 3004 self.assertNotIsInstance(42, typing.AsyncIterable) 3005 3006 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 3007 def test_async_iterator(self): 3008 base_it = range(10) # type: Iterator[int] 3009 it = AsyncIteratorWrapper(base_it) 3010 self.assertIsInstance(it, typing.AsyncIterator) 3011 self.assertNotIsInstance(42, typing.AsyncIterator) 3012 3013 def test_sized(self): 3014 self.assertIsInstance([], typing.Sized) 3015 self.assertNotIsInstance(42, typing.Sized) 3016 3017 def test_container(self): 3018 self.assertIsInstance([], typing.Container) 3019 self.assertNotIsInstance(42, typing.Container) 3020 3021 def test_collection(self): 3022 if hasattr(typing, 'Collection'): 3023 self.assertIsInstance(tuple(), typing.Collection) 3024 self.assertIsInstance(frozenset(), typing.Collection) 3025 self.assertIsSubclass(dict, typing.Collection) 3026 self.assertNotIsInstance(42, typing.Collection) 3027 3028 def test_abstractset(self): 3029 self.assertIsInstance(set(), typing.AbstractSet) 3030 self.assertNotIsInstance(42, typing.AbstractSet) 3031 3032 def test_mutableset(self): 3033 self.assertIsInstance(set(), typing.MutableSet) 3034 self.assertNotIsInstance(frozenset(), typing.MutableSet) 3035 3036 def test_mapping(self): 3037 self.assertIsInstance({}, typing.Mapping) 3038 self.assertNotIsInstance(42, typing.Mapping) 3039 3040 def test_mutablemapping(self): 3041 self.assertIsInstance({}, typing.MutableMapping) 3042 self.assertNotIsInstance(42, typing.MutableMapping) 3043 3044 def test_sequence(self): 3045 self.assertIsInstance([], typing.Sequence) 3046 self.assertNotIsInstance(42, typing.Sequence) 3047 3048 def test_mutablesequence(self): 3049 self.assertIsInstance([], typing.MutableSequence) 3050 self.assertNotIsInstance((), typing.MutableSequence) 3051 3052 def test_bytestring(self): 3053 self.assertIsInstance(b'', typing.ByteString) 3054 self.assertIsInstance(bytearray(b''), typing.ByteString) 3055 3056 def test_list(self): 3057 self.assertIsSubclass(list, typing.List) 3058 3059 def test_deque(self): 3060 self.assertIsSubclass(collections.deque, typing.Deque) 3061 class MyDeque(typing.Deque[int]): ... 3062 self.assertIsInstance(MyDeque(), collections.deque) 3063 3064 def test_counter(self): 3065 self.assertIsSubclass(collections.Counter, typing.Counter) 3066 3067 def test_set(self): 3068 self.assertIsSubclass(set, typing.Set) 3069 self.assertNotIsSubclass(frozenset, typing.Set) 3070 3071 def test_frozenset(self): 3072 self.assertIsSubclass(frozenset, typing.FrozenSet) 3073 self.assertNotIsSubclass(set, typing.FrozenSet) 3074 3075 def test_dict(self): 3076 self.assertIsSubclass(dict, typing.Dict) 3077 3078 def test_no_list_instantiation(self): 3079 with self.assertRaises(TypeError): 3080 typing.List() 3081 with self.assertRaises(TypeError): 3082 typing.List[T]() 3083 with self.assertRaises(TypeError): 3084 typing.List[int]() 3085 3086 def test_list_subclass(self): 3087 3088 class MyList(typing.List[int]): 3089 pass 3090 3091 a = MyList() 3092 self.assertIsInstance(a, MyList) 3093 self.assertIsInstance(a, typing.Sequence) 3094 3095 self.assertIsSubclass(MyList, list) 3096 self.assertNotIsSubclass(list, MyList) 3097 3098 def test_no_dict_instantiation(self): 3099 with self.assertRaises(TypeError): 3100 typing.Dict() 3101 with self.assertRaises(TypeError): 3102 typing.Dict[KT, VT]() 3103 with self.assertRaises(TypeError): 3104 typing.Dict[str, int]() 3105 3106 def test_dict_subclass(self): 3107 3108 class MyDict(typing.Dict[str, int]): 3109 pass 3110 3111 d = MyDict() 3112 self.assertIsInstance(d, MyDict) 3113 self.assertIsInstance(d, typing.MutableMapping) 3114 3115 self.assertIsSubclass(MyDict, dict) 3116 self.assertNotIsSubclass(dict, MyDict) 3117 3118 def test_defaultdict_instantiation(self): 3119 self.assertIs(type(typing.DefaultDict()), collections.defaultdict) 3120 self.assertIs(type(typing.DefaultDict[KT, VT]()), collections.defaultdict) 3121 self.assertIs(type(typing.DefaultDict[str, int]()), collections.defaultdict) 3122 3123 def test_defaultdict_subclass(self): 3124 3125 class MyDefDict(typing.DefaultDict[str, int]): 3126 pass 3127 3128 dd = MyDefDict() 3129 self.assertIsInstance(dd, MyDefDict) 3130 3131 self.assertIsSubclass(MyDefDict, collections.defaultdict) 3132 self.assertNotIsSubclass(collections.defaultdict, MyDefDict) 3133 3134 def test_ordereddict_instantiation(self): 3135 self.assertIs(type(typing.OrderedDict()), collections.OrderedDict) 3136 self.assertIs(type(typing.OrderedDict[KT, VT]()), collections.OrderedDict) 3137 self.assertIs(type(typing.OrderedDict[str, int]()), collections.OrderedDict) 3138 3139 def test_ordereddict_subclass(self): 3140 3141 class MyOrdDict(typing.OrderedDict[str, int]): 3142 pass 3143 3144 od = MyOrdDict() 3145 self.assertIsInstance(od, MyOrdDict) 3146 3147 self.assertIsSubclass(MyOrdDict, collections.OrderedDict) 3148 self.assertNotIsSubclass(collections.OrderedDict, MyOrdDict) 3149 3150 @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') 3151 def test_chainmap_instantiation(self): 3152 self.assertIs(type(typing.ChainMap()), collections.ChainMap) 3153 self.assertIs(type(typing.ChainMap[KT, VT]()), collections.ChainMap) 3154 self.assertIs(type(typing.ChainMap[str, int]()), collections.ChainMap) 3155 class CM(typing.ChainMap[KT, VT]): ... 3156 self.assertIs(type(CM[int, str]()), CM) 3157 3158 @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') 3159 def test_chainmap_subclass(self): 3160 3161 class MyChainMap(typing.ChainMap[str, int]): 3162 pass 3163 3164 cm = MyChainMap() 3165 self.assertIsInstance(cm, MyChainMap) 3166 3167 self.assertIsSubclass(MyChainMap, collections.ChainMap) 3168 self.assertNotIsSubclass(collections.ChainMap, MyChainMap) 3169 3170 def test_deque_instantiation(self): 3171 self.assertIs(type(typing.Deque()), collections.deque) 3172 self.assertIs(type(typing.Deque[T]()), collections.deque) 3173 self.assertIs(type(typing.Deque[int]()), collections.deque) 3174 class D(typing.Deque[T]): ... 3175 self.assertIs(type(D[int]()), D) 3176 3177 def test_counter_instantiation(self): 3178 self.assertIs(type(typing.Counter()), collections.Counter) 3179 self.assertIs(type(typing.Counter[T]()), collections.Counter) 3180 self.assertIs(type(typing.Counter[int]()), collections.Counter) 3181 class C(typing.Counter[T]): ... 3182 self.assertIs(type(C[int]()), C) 3183 3184 def test_counter_subclass_instantiation(self): 3185 3186 class MyCounter(typing.Counter[int]): 3187 pass 3188 3189 d = MyCounter() 3190 self.assertIsInstance(d, MyCounter) 3191 self.assertIsInstance(d, typing.Counter) 3192 self.assertIsInstance(d, collections.Counter) 3193 3194 def test_no_set_instantiation(self): 3195 with self.assertRaises(TypeError): 3196 typing.Set() 3197 with self.assertRaises(TypeError): 3198 typing.Set[T]() 3199 with self.assertRaises(TypeError): 3200 typing.Set[int]() 3201 3202 def test_set_subclass_instantiation(self): 3203 3204 class MySet(typing.Set[int]): 3205 pass 3206 3207 d = MySet() 3208 self.assertIsInstance(d, MySet) 3209 3210 def test_no_frozenset_instantiation(self): 3211 with self.assertRaises(TypeError): 3212 typing.FrozenSet() 3213 with self.assertRaises(TypeError): 3214 typing.FrozenSet[T]() 3215 with self.assertRaises(TypeError): 3216 typing.FrozenSet[int]() 3217 3218 def test_frozenset_subclass_instantiation(self): 3219 3220 class MyFrozenSet(typing.FrozenSet[int]): 3221 pass 3222 3223 d = MyFrozenSet() 3224 self.assertIsInstance(d, MyFrozenSet) 3225 3226 def test_no_tuple_instantiation(self): 3227 with self.assertRaises(TypeError): 3228 Tuple() 3229 with self.assertRaises(TypeError): 3230 Tuple[T]() 3231 with self.assertRaises(TypeError): 3232 Tuple[int]() 3233 3234 def test_generator(self): 3235 def foo(): 3236 yield 42 3237 g = foo() 3238 self.assertIsSubclass(type(g), typing.Generator) 3239 3240 def test_no_generator_instantiation(self): 3241 with self.assertRaises(TypeError): 3242 typing.Generator() 3243 with self.assertRaises(TypeError): 3244 typing.Generator[T, T, T]() 3245 with self.assertRaises(TypeError): 3246 typing.Generator[int, int, int]() 3247 3248 def test_async_generator(self): 3249 ns = {} 3250 exec("async def f():\n" 3251 " yield 42\n", globals(), ns) 3252 g = ns['f']() 3253 self.assertIsSubclass(type(g), typing.AsyncGenerator) 3254 3255 def test_no_async_generator_instantiation(self): 3256 with self.assertRaises(TypeError): 3257 typing.AsyncGenerator() 3258 with self.assertRaises(TypeError): 3259 typing.AsyncGenerator[T, T]() 3260 with self.assertRaises(TypeError): 3261 typing.AsyncGenerator[int, int]() 3262 3263 def test_subclassing(self): 3264 3265 class MMA(typing.MutableMapping): 3266 pass 3267 3268 with self.assertRaises(TypeError): # It's abstract 3269 MMA() 3270 3271 class MMC(MMA): 3272 def __getitem__(self, k): 3273 return None 3274 def __setitem__(self, k, v): 3275 pass 3276 def __delitem__(self, k): 3277 pass 3278 def __iter__(self): 3279 return iter(()) 3280 def __len__(self): 3281 return 0 3282 3283 self.assertEqual(len(MMC()), 0) 3284 assert callable(MMC.update) 3285 self.assertIsInstance(MMC(), typing.Mapping) 3286 3287 class MMB(typing.MutableMapping[KT, VT]): 3288 def __getitem__(self, k): 3289 return None 3290 def __setitem__(self, k, v): 3291 pass 3292 def __delitem__(self, k): 3293 pass 3294 def __iter__(self): 3295 return iter(()) 3296 def __len__(self): 3297 return 0 3298 3299 self.assertEqual(len(MMB()), 0) 3300 self.assertEqual(len(MMB[str, str]()), 0) 3301 self.assertEqual(len(MMB[KT, VT]()), 0) 3302 3303 self.assertNotIsSubclass(dict, MMA) 3304 self.assertNotIsSubclass(dict, MMB) 3305 3306 self.assertIsSubclass(MMA, typing.Mapping) 3307 self.assertIsSubclass(MMB, typing.Mapping) 3308 self.assertIsSubclass(MMC, typing.Mapping) 3309 3310 self.assertIsInstance(MMB[KT, VT](), typing.Mapping) 3311 self.assertIsInstance(MMB[KT, VT](), collections.abc.Mapping) 3312 3313 self.assertIsSubclass(MMA, collections.abc.Mapping) 3314 self.assertIsSubclass(MMB, collections.abc.Mapping) 3315 self.assertIsSubclass(MMC, collections.abc.Mapping) 3316 3317 with self.assertRaises(TypeError): 3318 issubclass(MMB[str, str], typing.Mapping) 3319 self.assertIsSubclass(MMC, MMA) 3320 3321 class I(typing.Iterable): ... 3322 self.assertNotIsSubclass(list, I) 3323 3324 class G(typing.Generator[int, int, int]): ... 3325 def g(): yield 0 3326 self.assertIsSubclass(G, typing.Generator) 3327 self.assertIsSubclass(G, typing.Iterable) 3328 self.assertIsSubclass(G, collections.abc.Generator) 3329 self.assertIsSubclass(G, collections.abc.Iterable) 3330 self.assertNotIsSubclass(type(g), G) 3331 3332 def test_subclassing_async_generator(self): 3333 class G(typing.AsyncGenerator[int, int]): 3334 def asend(self, value): 3335 pass 3336 def athrow(self, typ, val=None, tb=None): 3337 pass 3338 3339 ns = {} 3340 exec('async def g(): yield 0', globals(), ns) 3341 g = ns['g'] 3342 self.assertIsSubclass(G, typing.AsyncGenerator) 3343 self.assertIsSubclass(G, typing.AsyncIterable) 3344 self.assertIsSubclass(G, collections.abc.AsyncGenerator) 3345 self.assertIsSubclass(G, collections.abc.AsyncIterable) 3346 self.assertNotIsSubclass(type(g), G) 3347 3348 instance = G() 3349 self.assertIsInstance(instance, typing.AsyncGenerator) 3350 self.assertIsInstance(instance, typing.AsyncIterable) 3351 self.assertIsInstance(instance, collections.abc.AsyncGenerator) 3352 self.assertIsInstance(instance, collections.abc.AsyncIterable) 3353 self.assertNotIsInstance(type(g), G) 3354 self.assertNotIsInstance(g, G) 3355 3356 def test_subclassing_subclasshook(self): 3357 3358 class Base(typing.Iterable): 3359 @classmethod 3360 def __subclasshook__(cls, other): 3361 if other.__name__ == 'Foo': 3362 return True 3363 else: 3364 return False 3365 3366 class C(Base): ... 3367 class Foo: ... 3368 class Bar: ... 3369 self.assertIsSubclass(Foo, Base) 3370 self.assertIsSubclass(Foo, C) 3371 self.assertNotIsSubclass(Bar, C) 3372 3373 def test_subclassing_register(self): 3374 3375 class A(typing.Container): ... 3376 class B(A): ... 3377 3378 class C: ... 3379 A.register(C) 3380 self.assertIsSubclass(C, A) 3381 self.assertNotIsSubclass(C, B) 3382 3383 class D: ... 3384 B.register(D) 3385 self.assertIsSubclass(D, A) 3386 self.assertIsSubclass(D, B) 3387 3388 class M(): ... 3389 collections.abc.MutableMapping.register(M) 3390 self.assertIsSubclass(M, typing.Mapping) 3391 3392 def test_collections_as_base(self): 3393 3394 class M(collections.abc.Mapping): ... 3395 self.assertIsSubclass(M, typing.Mapping) 3396 self.assertIsSubclass(M, typing.Iterable) 3397 3398 class S(collections.abc.MutableSequence): ... 3399 self.assertIsSubclass(S, typing.MutableSequence) 3400 self.assertIsSubclass(S, typing.Iterable) 3401 3402 class I(collections.abc.Iterable): ... 3403 self.assertIsSubclass(I, typing.Iterable) 3404 3405 class A(collections.abc.Mapping, metaclass=abc.ABCMeta): ... 3406 class B: ... 3407 A.register(B) 3408 self.assertIsSubclass(B, typing.Mapping) 3409 3410 3411class OtherABCTests(BaseTestCase): 3412 3413 def test_contextmanager(self): 3414 @contextlib.contextmanager 3415 def manager(): 3416 yield 42 3417 3418 cm = manager() 3419 self.assertIsInstance(cm, typing.ContextManager) 3420 self.assertNotIsInstance(42, typing.ContextManager) 3421 3422 @skipUnless(ASYNCIO, 'Python 3.5 required') 3423 def test_async_contextmanager(self): 3424 class NotACM: 3425 pass 3426 self.assertIsInstance(ACM(), typing.AsyncContextManager) 3427 self.assertNotIsInstance(NotACM(), typing.AsyncContextManager) 3428 @contextlib.contextmanager 3429 def manager(): 3430 yield 42 3431 3432 cm = manager() 3433 self.assertNotIsInstance(cm, typing.AsyncContextManager) 3434 self.assertEqual(typing.AsyncContextManager[int].__args__, (int,)) 3435 with self.assertRaises(TypeError): 3436 isinstance(42, typing.AsyncContextManager[int]) 3437 with self.assertRaises(TypeError): 3438 typing.AsyncContextManager[int, str] 3439 3440 3441class TypeTests(BaseTestCase): 3442 3443 def test_type_basic(self): 3444 3445 class User: pass 3446 class BasicUser(User): pass 3447 class ProUser(User): pass 3448 3449 def new_user(user_class: Type[User]) -> User: 3450 return user_class() 3451 3452 new_user(BasicUser) 3453 3454 def test_type_typevar(self): 3455 3456 class User: pass 3457 class BasicUser(User): pass 3458 class ProUser(User): pass 3459 3460 U = TypeVar('U', bound=User) 3461 3462 def new_user(user_class: Type[U]) -> U: 3463 return user_class() 3464 3465 new_user(BasicUser) 3466 3467 def test_type_optional(self): 3468 A = Optional[Type[BaseException]] 3469 3470 def foo(a: A) -> Optional[BaseException]: 3471 if a is None: 3472 return None 3473 else: 3474 return a() 3475 3476 assert isinstance(foo(KeyboardInterrupt), KeyboardInterrupt) 3477 assert foo(None) is None 3478 3479 3480class NewTypeTests(BaseTestCase): 3481 3482 def test_basic(self): 3483 UserId = NewType('UserId', int) 3484 UserName = NewType('UserName', str) 3485 self.assertIsInstance(UserId(5), int) 3486 self.assertIsInstance(UserName('Joe'), str) 3487 self.assertEqual(UserId(5) + 1, 6) 3488 3489 def test_errors(self): 3490 UserId = NewType('UserId', int) 3491 UserName = NewType('UserName', str) 3492 with self.assertRaises(TypeError): 3493 issubclass(UserId, int) 3494 with self.assertRaises(TypeError): 3495 class D(UserName): 3496 pass 3497 3498 3499class NamedTupleTests(BaseTestCase): 3500 class NestedEmployee(NamedTuple): 3501 name: str 3502 cool: int 3503 3504 def test_basics(self): 3505 Emp = NamedTuple('Emp', [('name', str), ('id', int)]) 3506 self.assertIsSubclass(Emp, tuple) 3507 joe = Emp('Joe', 42) 3508 jim = Emp(name='Jim', id=1) 3509 self.assertIsInstance(joe, Emp) 3510 self.assertIsInstance(joe, tuple) 3511 self.assertEqual(joe.name, 'Joe') 3512 self.assertEqual(joe.id, 42) 3513 self.assertEqual(jim.name, 'Jim') 3514 self.assertEqual(jim.id, 1) 3515 self.assertEqual(Emp.__name__, 'Emp') 3516 self.assertEqual(Emp._fields, ('name', 'id')) 3517 self.assertEqual(Emp.__annotations__, 3518 collections.OrderedDict([('name', str), ('id', int)])) 3519 self.assertIs(Emp._field_types, Emp.__annotations__) 3520 3521 def test_namedtuple_pyversion(self): 3522 if sys.version_info[:2] < (3, 6): 3523 with self.assertRaises(TypeError): 3524 NamedTuple('Name', one=int, other=str) 3525 with self.assertRaises(TypeError): 3526 class NotYet(NamedTuple): 3527 whatever = 0 3528 3529 def test_annotation_usage(self): 3530 tim = CoolEmployee('Tim', 9000) 3531 self.assertIsInstance(tim, CoolEmployee) 3532 self.assertIsInstance(tim, tuple) 3533 self.assertEqual(tim.name, 'Tim') 3534 self.assertEqual(tim.cool, 9000) 3535 self.assertEqual(CoolEmployee.__name__, 'CoolEmployee') 3536 self.assertEqual(CoolEmployee._fields, ('name', 'cool')) 3537 self.assertEqual(CoolEmployee.__annotations__, 3538 collections.OrderedDict(name=str, cool=int)) 3539 self.assertIs(CoolEmployee._field_types, CoolEmployee.__annotations__) 3540 3541 def test_annotation_usage_with_default(self): 3542 jelle = CoolEmployeeWithDefault('Jelle') 3543 self.assertIsInstance(jelle, CoolEmployeeWithDefault) 3544 self.assertIsInstance(jelle, tuple) 3545 self.assertEqual(jelle.name, 'Jelle') 3546 self.assertEqual(jelle.cool, 0) 3547 cooler_employee = CoolEmployeeWithDefault('Sjoerd', 1) 3548 self.assertEqual(cooler_employee.cool, 1) 3549 3550 self.assertEqual(CoolEmployeeWithDefault.__name__, 'CoolEmployeeWithDefault') 3551 self.assertEqual(CoolEmployeeWithDefault._fields, ('name', 'cool')) 3552 self.assertEqual(CoolEmployeeWithDefault._field_types, dict(name=str, cool=int)) 3553 self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0)) 3554 3555 with self.assertRaises(TypeError): 3556 exec(""" 3557class NonDefaultAfterDefault(NamedTuple): 3558 x: int = 3 3559 y: int 3560""") 3561 3562 def test_annotation_usage_with_methods(self): 3563 self.assertEqual(XMeth(1).double(), 2) 3564 self.assertEqual(XMeth(42).x, XMeth(42)[0]) 3565 self.assertEqual(str(XRepr(42)), '42 -> 1') 3566 self.assertEqual(XRepr(1, 2) + XRepr(3), 0) 3567 3568 with self.assertRaises(AttributeError): 3569 exec(""" 3570class XMethBad(NamedTuple): 3571 x: int 3572 def _fields(self): 3573 return 'no chance for this' 3574""") 3575 3576 with self.assertRaises(AttributeError): 3577 exec(""" 3578class XMethBad2(NamedTuple): 3579 x: int 3580 def _source(self): 3581 return 'no chance for this as well' 3582""") 3583 3584 def test_namedtuple_keyword_usage(self): 3585 LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int) 3586 nick = LocalEmployee('Nick', 25) 3587 self.assertIsInstance(nick, tuple) 3588 self.assertEqual(nick.name, 'Nick') 3589 self.assertEqual(LocalEmployee.__name__, 'LocalEmployee') 3590 self.assertEqual(LocalEmployee._fields, ('name', 'age')) 3591 self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int)) 3592 self.assertIs(LocalEmployee._field_types, LocalEmployee.__annotations__) 3593 with self.assertRaises(TypeError): 3594 NamedTuple('Name', [('x', int)], y=str) 3595 with self.assertRaises(TypeError): 3596 NamedTuple('Name', x=1, y='a') 3597 3598 def test_namedtuple_special_keyword_names(self): 3599 NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list) 3600 self.assertEqual(NT.__name__, 'NT') 3601 self.assertEqual(NT._fields, ('cls', 'self', 'typename', 'fields')) 3602 a = NT(cls=str, self=42, typename='foo', fields=[('bar', tuple)]) 3603 self.assertEqual(a.cls, str) 3604 self.assertEqual(a.self, 42) 3605 self.assertEqual(a.typename, 'foo') 3606 self.assertEqual(a.fields, [('bar', tuple)]) 3607 3608 def test_namedtuple_errors(self): 3609 with self.assertRaises(TypeError): 3610 NamedTuple.__new__() 3611 with self.assertRaises(TypeError): 3612 NamedTuple() 3613 with self.assertRaises(TypeError): 3614 NamedTuple('Emp', [('name', str)], None) 3615 with self.assertRaises(ValueError): 3616 NamedTuple('Emp', [('_name', str)]) 3617 3618 with self.assertWarns(DeprecationWarning): 3619 Emp = NamedTuple(typename='Emp', name=str, id=int) 3620 self.assertEqual(Emp.__name__, 'Emp') 3621 self.assertEqual(Emp._fields, ('name', 'id')) 3622 3623 with self.assertWarns(DeprecationWarning): 3624 Emp = NamedTuple('Emp', fields=[('name', str), ('id', int)]) 3625 self.assertEqual(Emp.__name__, 'Emp') 3626 self.assertEqual(Emp._fields, ('name', 'id')) 3627 3628 def test_copy_and_pickle(self): 3629 global Emp # pickle wants to reference the class by name 3630 Emp = NamedTuple('Emp', [('name', str), ('cool', int)]) 3631 for cls in Emp, CoolEmployee, self.NestedEmployee: 3632 with self.subTest(cls=cls): 3633 jane = cls('jane', 37) 3634 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 3635 z = pickle.dumps(jane, proto) 3636 jane2 = pickle.loads(z) 3637 self.assertEqual(jane2, jane) 3638 self.assertIsInstance(jane2, cls) 3639 3640 jane2 = copy(jane) 3641 self.assertEqual(jane2, jane) 3642 self.assertIsInstance(jane2, cls) 3643 3644 jane2 = deepcopy(jane) 3645 self.assertEqual(jane2, jane) 3646 self.assertIsInstance(jane2, cls) 3647 3648 3649class TypedDictTests(BaseTestCase): 3650 def test_basics_functional_syntax(self): 3651 Emp = TypedDict('Emp', {'name': str, 'id': int}) 3652 self.assertIsSubclass(Emp, dict) 3653 self.assertIsSubclass(Emp, typing.MutableMapping) 3654 self.assertNotIsSubclass(Emp, collections.abc.Sequence) 3655 jim = Emp(name='Jim', id=1) 3656 self.assertIs(type(jim), dict) 3657 self.assertEqual(jim['name'], 'Jim') 3658 self.assertEqual(jim['id'], 1) 3659 self.assertEqual(Emp.__name__, 'Emp') 3660 self.assertEqual(Emp.__module__, __name__) 3661 self.assertEqual(Emp.__bases__, (dict,)) 3662 self.assertEqual(Emp.__annotations__, {'name': str, 'id': int}) 3663 self.assertEqual(Emp.__total__, True) 3664 3665 def test_basics_keywords_syntax(self): 3666 Emp = TypedDict('Emp', name=str, id=int) 3667 self.assertIsSubclass(Emp, dict) 3668 self.assertIsSubclass(Emp, typing.MutableMapping) 3669 self.assertNotIsSubclass(Emp, collections.abc.Sequence) 3670 jim = Emp(name='Jim', id=1) 3671 self.assertIs(type(jim), dict) 3672 self.assertEqual(jim['name'], 'Jim') 3673 self.assertEqual(jim['id'], 1) 3674 self.assertEqual(Emp.__name__, 'Emp') 3675 self.assertEqual(Emp.__module__, __name__) 3676 self.assertEqual(Emp.__bases__, (dict,)) 3677 self.assertEqual(Emp.__annotations__, {'name': str, 'id': int}) 3678 self.assertEqual(Emp.__total__, True) 3679 3680 def test_typeddict_special_keyword_names(self): 3681 TD = TypedDict("TD", cls=type, self=object, typename=str, _typename=int, fields=list, _fields=dict) 3682 self.assertEqual(TD.__name__, 'TD') 3683 self.assertEqual(TD.__annotations__, {'cls': type, 'self': object, 'typename': str, '_typename': int, 'fields': list, '_fields': dict}) 3684 a = TD(cls=str, self=42, typename='foo', _typename=53, fields=[('bar', tuple)], _fields={'baz', set}) 3685 self.assertEqual(a['cls'], str) 3686 self.assertEqual(a['self'], 42) 3687 self.assertEqual(a['typename'], 'foo') 3688 self.assertEqual(a['_typename'], 53) 3689 self.assertEqual(a['fields'], [('bar', tuple)]) 3690 self.assertEqual(a['_fields'], {'baz', set}) 3691 3692 def test_typeddict_create_errors(self): 3693 with self.assertRaises(TypeError): 3694 TypedDict.__new__() 3695 with self.assertRaises(TypeError): 3696 TypedDict() 3697 with self.assertRaises(TypeError): 3698 TypedDict('Emp', [('name', str)], None) 3699 with self.assertRaises(TypeError): 3700 TypedDict(_typename='Emp', name=str, id=int) 3701 with self.assertRaises(TypeError): 3702 TypedDict('Emp', _fields={'name': str, 'id': int}) 3703 3704 def test_typeddict_errors(self): 3705 Emp = TypedDict('Emp', {'name': str, 'id': int}) 3706 self.assertEqual(TypedDict.__module__, 'typing') 3707 jim = Emp(name='Jim', id=1) 3708 with self.assertRaises(TypeError): 3709 isinstance({}, Emp) 3710 with self.assertRaises(TypeError): 3711 isinstance(jim, Emp) 3712 with self.assertRaises(TypeError): 3713 issubclass(dict, Emp) 3714 with self.assertRaises(TypeError): 3715 TypedDict('Hi', x=1) 3716 with self.assertRaises(TypeError): 3717 TypedDict('Hi', [('x', int), ('y', 1)]) 3718 with self.assertRaises(TypeError): 3719 TypedDict('Hi', [('x', int)], y=int) 3720 3721 def test_py36_class_syntax_usage(self): 3722 self.assertEqual(LabelPoint2D.__name__, 'LabelPoint2D') 3723 self.assertEqual(LabelPoint2D.__module__, __name__) 3724 self.assertEqual(LabelPoint2D.__annotations__, {'x': int, 'y': int, 'label': str}) 3725 self.assertEqual(LabelPoint2D.__bases__, (dict,)) 3726 self.assertEqual(LabelPoint2D.__total__, True) 3727 self.assertNotIsSubclass(LabelPoint2D, typing.Sequence) 3728 not_origin = Point2D(x=0, y=1) 3729 self.assertEqual(not_origin['x'], 0) 3730 self.assertEqual(not_origin['y'], 1) 3731 other = LabelPoint2D(x=0, y=1, label='hi') 3732 self.assertEqual(other['label'], 'hi') 3733 3734 def test_pickle(self): 3735 global EmpD # pickle wants to reference the class by name 3736 EmpD = TypedDict('EmpD', name=str, id=int) 3737 jane = EmpD({'name': 'jane', 'id': 37}) 3738 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 3739 z = pickle.dumps(jane, proto) 3740 jane2 = pickle.loads(z) 3741 self.assertEqual(jane2, jane) 3742 self.assertEqual(jane2, {'name': 'jane', 'id': 37}) 3743 ZZ = pickle.dumps(EmpD, proto) 3744 EmpDnew = pickle.loads(ZZ) 3745 self.assertEqual(EmpDnew({'name': 'jane', 'id': 37}), jane) 3746 3747 def test_optional(self): 3748 EmpD = TypedDict('EmpD', name=str, id=int) 3749 3750 self.assertEqual(typing.Optional[EmpD], typing.Union[None, EmpD]) 3751 self.assertNotEqual(typing.List[EmpD], typing.Tuple[EmpD]) 3752 3753 def test_total(self): 3754 D = TypedDict('D', {'x': int}, total=False) 3755 self.assertEqual(D(), {}) 3756 self.assertEqual(D(x=1), {'x': 1}) 3757 self.assertEqual(D.__total__, False) 3758 3759 self.assertEqual(Options(), {}) 3760 self.assertEqual(Options(log_level=2), {'log_level': 2}) 3761 self.assertEqual(Options.__total__, False) 3762 3763 3764class IOTests(BaseTestCase): 3765 3766 def test_io(self): 3767 3768 def stuff(a: IO) -> AnyStr: 3769 return a.readline() 3770 3771 a = stuff.__annotations__['a'] 3772 self.assertEqual(a.__parameters__, (AnyStr,)) 3773 3774 def test_textio(self): 3775 3776 def stuff(a: TextIO) -> str: 3777 return a.readline() 3778 3779 a = stuff.__annotations__['a'] 3780 self.assertEqual(a.__parameters__, ()) 3781 3782 def test_binaryio(self): 3783 3784 def stuff(a: BinaryIO) -> bytes: 3785 return a.readline() 3786 3787 a = stuff.__annotations__['a'] 3788 self.assertEqual(a.__parameters__, ()) 3789 3790 def test_io_submodule(self): 3791 from typing.io import IO, TextIO, BinaryIO, __all__, __name__ 3792 self.assertIs(IO, typing.IO) 3793 self.assertIs(TextIO, typing.TextIO) 3794 self.assertIs(BinaryIO, typing.BinaryIO) 3795 self.assertEqual(set(__all__), set(['IO', 'TextIO', 'BinaryIO'])) 3796 self.assertEqual(__name__, 'typing.io') 3797 3798 3799class RETests(BaseTestCase): 3800 # Much of this is really testing _TypeAlias. 3801 3802 def test_basics(self): 3803 pat = re.compile('[a-z]+', re.I) 3804 self.assertIsSubclass(pat.__class__, Pattern) 3805 self.assertIsSubclass(type(pat), Pattern) 3806 self.assertIsInstance(pat, Pattern) 3807 3808 mat = pat.search('12345abcde.....') 3809 self.assertIsSubclass(mat.__class__, Match) 3810 self.assertIsSubclass(type(mat), Match) 3811 self.assertIsInstance(mat, Match) 3812 3813 # these should just work 3814 Pattern[Union[str, bytes]] 3815 Match[Union[bytes, str]] 3816 3817 def test_alias_equality(self): 3818 self.assertEqual(Pattern[str], Pattern[str]) 3819 self.assertNotEqual(Pattern[str], Pattern[bytes]) 3820 self.assertNotEqual(Pattern[str], Match[str]) 3821 self.assertNotEqual(Pattern[str], str) 3822 3823 def test_errors(self): 3824 m = Match[Union[str, bytes]] 3825 with self.assertRaises(TypeError): 3826 m[str] 3827 with self.assertRaises(TypeError): 3828 # We don't support isinstance(). 3829 isinstance(42, Pattern[str]) 3830 with self.assertRaises(TypeError): 3831 # We don't support issubclass(). 3832 issubclass(Pattern[bytes], Pattern[str]) 3833 3834 def test_repr(self): 3835 self.assertEqual(repr(Pattern), 'typing.Pattern') 3836 self.assertEqual(repr(Pattern[str]), 'typing.Pattern[str]') 3837 self.assertEqual(repr(Pattern[bytes]), 'typing.Pattern[bytes]') 3838 self.assertEqual(repr(Match), 'typing.Match') 3839 self.assertEqual(repr(Match[str]), 'typing.Match[str]') 3840 self.assertEqual(repr(Match[bytes]), 'typing.Match[bytes]') 3841 3842 def test_re_submodule(self): 3843 from typing.re import Match, Pattern, __all__, __name__ 3844 self.assertIs(Match, typing.Match) 3845 self.assertIs(Pattern, typing.Pattern) 3846 self.assertEqual(set(__all__), set(['Match', 'Pattern'])) 3847 self.assertEqual(__name__, 'typing.re') 3848 3849 def test_cannot_subclass(self): 3850 with self.assertRaises(TypeError) as ex: 3851 3852 class A(typing.Match): 3853 pass 3854 3855 self.assertEqual(str(ex.exception), 3856 "type 're.Match' is not an acceptable base type") 3857 3858 3859class AllTests(BaseTestCase): 3860 """Tests for __all__.""" 3861 3862 def test_all(self): 3863 from typing import __all__ as a 3864 # Just spot-check the first and last of every category. 3865 self.assertIn('AbstractSet', a) 3866 self.assertIn('ValuesView', a) 3867 self.assertIn('cast', a) 3868 self.assertIn('overload', a) 3869 if hasattr(contextlib, 'AbstractContextManager'): 3870 self.assertIn('ContextManager', a) 3871 # Check that io and re are not exported. 3872 self.assertNotIn('io', a) 3873 self.assertNotIn('re', a) 3874 # Spot-check that stdlib modules aren't exported. 3875 self.assertNotIn('os', a) 3876 self.assertNotIn('sys', a) 3877 # Check that Text is defined. 3878 self.assertIn('Text', a) 3879 # Check previously missing classes. 3880 self.assertIn('SupportsBytes', a) 3881 self.assertIn('SupportsComplex', a) 3882 3883 def test_all_exported_names(self): 3884 import typing 3885 3886 actual_all = set(typing.__all__) 3887 computed_all = { 3888 k for k, v in vars(typing).items() 3889 # explicitly exported, not a thing with __module__ 3890 if k in actual_all or ( 3891 # avoid private names 3892 not k.startswith('_') and 3893 # avoid things in the io / re typing submodules 3894 k not in typing.io.__all__ and 3895 k not in typing.re.__all__ and 3896 k not in {'io', 're'} and 3897 # there's a few types and metaclasses that aren't exported 3898 not k.endswith(('Meta', '_contra', '_co')) and 3899 not k.upper() == k and 3900 # but export all things that have __module__ == 'typing' 3901 getattr(v, '__module__', None) == typing.__name__ 3902 ) 3903 } 3904 self.assertSetEqual(computed_all, actual_all) 3905 3906 3907 3908if __name__ == '__main__': 3909 main() 3910