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