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