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