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