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