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_respect_no_type_check(self): 3108 @no_type_check 3109 class NoTpCheck: 3110 class Inn: 3111 def __init__(self, x: 'not a type'): ... 3112 self.assertTrue(NoTpCheck.__no_type_check__) 3113 self.assertTrue(NoTpCheck.Inn.__init__.__no_type_check__) 3114 self.assertEqual(gth(ann_module2.NTC.meth), {}) 3115 class ABase(Generic[T]): 3116 def meth(x: int): ... 3117 @no_type_check 3118 class Der(ABase): ... 3119 self.assertEqual(gth(ABase.meth), {'x': int}) 3120 3121 def test_get_type_hints_for_builtins(self): 3122 # Should not fail for built-in classes and functions. 3123 self.assertEqual(gth(int), {}) 3124 self.assertEqual(gth(type), {}) 3125 self.assertEqual(gth(dir), {}) 3126 self.assertEqual(gth(len), {}) 3127 self.assertEqual(gth(object.__str__), {}) 3128 self.assertEqual(gth(object().__str__), {}) 3129 self.assertEqual(gth(str.join), {}) 3130 3131 def test_previous_behavior(self): 3132 def testf(x, y): ... 3133 testf.__annotations__['x'] = 'int' 3134 self.assertEqual(gth(testf), {'x': int}) 3135 def testg(x: None): ... 3136 self.assertEqual(gth(testg), {'x': type(None)}) 3137 3138 def test_get_type_hints_for_object_with_annotations(self): 3139 class A: ... 3140 class B: ... 3141 b = B() 3142 b.__annotations__ = {'x': 'A'} 3143 self.assertEqual(gth(b, locals()), {'x': A}) 3144 3145 def test_get_type_hints_ClassVar(self): 3146 self.assertEqual(gth(ann_module2.CV, ann_module2.__dict__), 3147 {'var': typing.ClassVar[ann_module2.CV]}) 3148 self.assertEqual(gth(B, globals()), 3149 {'y': int, 'x': ClassVar[Optional[B]], 'b': int}) 3150 self.assertEqual(gth(CSub, globals()), 3151 {'z': ClassVar[CSub], 'y': int, 'b': int, 3152 'x': ClassVar[Optional[B]]}) 3153 self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) 3154 3155 def test_get_type_hints_wrapped_decoratored_func(self): 3156 expects = {'self': ForRefExample} 3157 self.assertEqual(gth(ForRefExample.func), expects) 3158 self.assertEqual(gth(ForRefExample.nested), expects) 3159 3160 def test_get_type_hints_annotated(self): 3161 def foobar(x: List['X']): ... 3162 X = Annotated[int, (1, 10)] 3163 self.assertEqual( 3164 get_type_hints(foobar, globals(), locals()), 3165 {'x': List[int]} 3166 ) 3167 self.assertEqual( 3168 get_type_hints(foobar, globals(), locals(), include_extras=True), 3169 {'x': List[Annotated[int, (1, 10)]]} 3170 ) 3171 3172 def foobar(x: list[ForwardRef('X')]): ... 3173 X = Annotated[int, (1, 10)] 3174 self.assertEqual( 3175 get_type_hints(foobar, globals(), locals()), 3176 {'x': list[int]} 3177 ) 3178 self.assertEqual( 3179 get_type_hints(foobar, globals(), locals(), include_extras=True), 3180 {'x': list[Annotated[int, (1, 10)]]} 3181 ) 3182 3183 BA = Tuple[Annotated[T, (1, 0)], ...] 3184 def barfoo(x: BA): ... 3185 self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], Tuple[T, ...]) 3186 self.assertIs( 3187 get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], 3188 BA 3189 ) 3190 3191 BA = tuple[Annotated[T, (1, 0)], ...] 3192 def barfoo(x: BA): ... 3193 self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], tuple[T, ...]) 3194 self.assertIs( 3195 get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], 3196 BA 3197 ) 3198 3199 def barfoo2(x: typing.Callable[..., Annotated[List[T], "const"]], 3200 y: typing.Union[int, Annotated[T, "mutable"]]): ... 3201 self.assertEqual( 3202 get_type_hints(barfoo2, globals(), locals()), 3203 {'x': typing.Callable[..., List[T]], 'y': typing.Union[int, T]} 3204 ) 3205 3206 BA2 = typing.Callable[..., List[T]] 3207 def barfoo3(x: BA2): ... 3208 self.assertIs( 3209 get_type_hints(barfoo3, globals(), locals(), include_extras=True)["x"], 3210 BA2 3211 ) 3212 BA3 = typing.Annotated[int | float, "const"] 3213 def barfoo4(x: BA3): ... 3214 self.assertEqual( 3215 get_type_hints(barfoo4, globals(), locals()), 3216 {"x": int | float} 3217 ) 3218 self.assertEqual( 3219 get_type_hints(barfoo4, globals(), locals(), include_extras=True), 3220 {"x": typing.Annotated[int | float, "const"]} 3221 ) 3222 3223 def test_get_type_hints_annotated_refs(self): 3224 3225 Const = Annotated[T, "Const"] 3226 3227 class MySet(Generic[T]): 3228 3229 def __ior__(self, other: "Const[MySet[T]]") -> "MySet[T]": 3230 ... 3231 3232 def __iand__(self, other: Const["MySet[T]"]) -> "MySet[T]": 3233 ... 3234 3235 self.assertEqual( 3236 get_type_hints(MySet.__iand__, globals(), locals()), 3237 {'other': MySet[T], 'return': MySet[T]} 3238 ) 3239 3240 self.assertEqual( 3241 get_type_hints(MySet.__iand__, globals(), locals(), include_extras=True), 3242 {'other': Const[MySet[T]], 'return': MySet[T]} 3243 ) 3244 3245 self.assertEqual( 3246 get_type_hints(MySet.__ior__, globals(), locals()), 3247 {'other': MySet[T], 'return': MySet[T]} 3248 ) 3249 3250 def test_get_type_hints_classes_str_annotations(self): 3251 class Foo: 3252 y = str 3253 x: 'y' 3254 # This previously raised an error under PEP 563. 3255 self.assertEqual(get_type_hints(Foo), {'x': str}) 3256 3257 def test_get_type_hints_bad_module(self): 3258 # bpo-41515 3259 class BadModule: 3260 pass 3261 BadModule.__module__ = 'bad' # Something not in sys.modules 3262 self.assertNotIn('bad', sys.modules) 3263 self.assertEqual(get_type_hints(BadModule), {}) 3264 3265 def test_get_type_hints_annotated_bad_module(self): 3266 # See https://bugs.python.org/issue44468 3267 class BadBase: 3268 foo: tuple 3269 class BadType(BadBase): 3270 bar: list 3271 BadType.__module__ = BadBase.__module__ = 'bad' 3272 self.assertNotIn('bad', sys.modules) 3273 self.assertEqual(get_type_hints(BadType), {'foo': tuple, 'bar': list}) 3274 3275 3276class GetUtilitiesTestCase(TestCase): 3277 def test_get_origin(self): 3278 T = TypeVar('T') 3279 P = ParamSpec('P') 3280 class C(Generic[T]): pass 3281 self.assertIs(get_origin(C[int]), C) 3282 self.assertIs(get_origin(C[T]), C) 3283 self.assertIs(get_origin(int), None) 3284 self.assertIs(get_origin(ClassVar[int]), ClassVar) 3285 self.assertIs(get_origin(Union[int, str]), Union) 3286 self.assertIs(get_origin(Literal[42, 43]), Literal) 3287 self.assertIs(get_origin(Final[List[int]]), Final) 3288 self.assertIs(get_origin(Generic), Generic) 3289 self.assertIs(get_origin(Generic[T]), Generic) 3290 self.assertIs(get_origin(List[Tuple[T, T]][int]), list) 3291 self.assertIs(get_origin(Annotated[T, 'thing']), Annotated) 3292 self.assertIs(get_origin(List), list) 3293 self.assertIs(get_origin(Tuple), tuple) 3294 self.assertIs(get_origin(Callable), collections.abc.Callable) 3295 self.assertIs(get_origin(list[int]), list) 3296 self.assertIs(get_origin(list), None) 3297 self.assertIs(get_origin(list | str), types.UnionType) 3298 self.assertIs(get_origin(P.args), P) 3299 self.assertIs(get_origin(P.kwargs), P) 3300 3301 def test_get_args(self): 3302 T = TypeVar('T') 3303 class C(Generic[T]): pass 3304 self.assertEqual(get_args(C[int]), (int,)) 3305 self.assertEqual(get_args(C[T]), (T,)) 3306 self.assertEqual(get_args(int), ()) 3307 self.assertEqual(get_args(ClassVar[int]), (int,)) 3308 self.assertEqual(get_args(Union[int, str]), (int, str)) 3309 self.assertEqual(get_args(Literal[42, 43]), (42, 43)) 3310 self.assertEqual(get_args(Final[List[int]]), (List[int],)) 3311 self.assertEqual(get_args(Union[int, Tuple[T, int]][str]), 3312 (int, Tuple[str, int])) 3313 self.assertEqual(get_args(typing.Dict[int, Tuple[T, T]][Optional[int]]), 3314 (int, Tuple[Optional[int], Optional[int]])) 3315 self.assertEqual(get_args(Callable[[], T][int]), ([], int)) 3316 self.assertEqual(get_args(Callable[..., int]), (..., int)) 3317 self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]), 3318 (int, Callable[[Tuple[T, ...]], str])) 3319 self.assertEqual(get_args(Tuple[int, ...]), (int, ...)) 3320 self.assertEqual(get_args(Tuple[()]), ((),)) 3321 self.assertEqual(get_args(Annotated[T, 'one', 2, ['three']]), (T, 'one', 2, ['three'])) 3322 self.assertEqual(get_args(List), ()) 3323 self.assertEqual(get_args(Tuple), ()) 3324 self.assertEqual(get_args(Callable), ()) 3325 self.assertEqual(get_args(list[int]), (int,)) 3326 self.assertEqual(get_args(list), ()) 3327 self.assertEqual(get_args(collections.abc.Callable[[int], str]), ([int], str)) 3328 self.assertEqual(get_args(collections.abc.Callable[..., str]), (..., str)) 3329 self.assertEqual(get_args(collections.abc.Callable[[], str]), ([], str)) 3330 self.assertEqual(get_args(collections.abc.Callable[[int], str]), 3331 get_args(Callable[[int], str])) 3332 P = ParamSpec('P') 3333 self.assertEqual(get_args(Callable[P, int]), (P, int)) 3334 self.assertEqual(get_args(Callable[Concatenate[int, P], int]), 3335 (Concatenate[int, P], int)) 3336 self.assertEqual(get_args(list | str), (list, str)) 3337 3338 def test_forward_ref_and_final(self): 3339 # https://bugs.python.org/issue45166 3340 hints = get_type_hints(ann_module5) 3341 self.assertEqual(hints, {'name': Final[str]}) 3342 3343 hints = get_type_hints(ann_module5.MyClass) 3344 self.assertEqual(hints, {'value': Final}) 3345 3346 def test_top_level_class_var(self): 3347 # https://bugs.python.org/issue45166 3348 with self.assertRaisesRegex( 3349 TypeError, 3350 r'typing.ClassVar\[int\] is not valid as type argument', 3351 ): 3352 get_type_hints(ann_module6) 3353 3354 3355class CollectionsAbcTests(BaseTestCase): 3356 3357 def test_hashable(self): 3358 self.assertIsInstance(42, typing.Hashable) 3359 self.assertNotIsInstance([], typing.Hashable) 3360 3361 def test_iterable(self): 3362 self.assertIsInstance([], typing.Iterable) 3363 # Due to ABC caching, the second time takes a separate code 3364 # path and could fail. So call this a few times. 3365 self.assertIsInstance([], typing.Iterable) 3366 self.assertIsInstance([], typing.Iterable) 3367 self.assertNotIsInstance(42, typing.Iterable) 3368 # Just in case, also test issubclass() a few times. 3369 self.assertIsSubclass(list, typing.Iterable) 3370 self.assertIsSubclass(list, typing.Iterable) 3371 3372 def test_iterator(self): 3373 it = iter([]) 3374 self.assertIsInstance(it, typing.Iterator) 3375 self.assertNotIsInstance(42, typing.Iterator) 3376 3377 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 3378 def test_awaitable(self): 3379 ns = {} 3380 exec( 3381 "async def foo() -> typing.Awaitable[int]:\n" 3382 " return await AwaitableWrapper(42)\n", 3383 globals(), ns) 3384 foo = ns['foo'] 3385 g = foo() 3386 self.assertIsInstance(g, typing.Awaitable) 3387 self.assertNotIsInstance(foo, typing.Awaitable) 3388 g.send(None) # Run foo() till completion, to avoid warning. 3389 3390 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 3391 def test_coroutine(self): 3392 ns = {} 3393 exec( 3394 "async def foo():\n" 3395 " return\n", 3396 globals(), ns) 3397 foo = ns['foo'] 3398 g = foo() 3399 self.assertIsInstance(g, typing.Coroutine) 3400 with self.assertRaises(TypeError): 3401 isinstance(g, typing.Coroutine[int]) 3402 self.assertNotIsInstance(foo, typing.Coroutine) 3403 try: 3404 g.send(None) 3405 except StopIteration: 3406 pass 3407 3408 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 3409 def test_async_iterable(self): 3410 base_it = range(10) # type: Iterator[int] 3411 it = AsyncIteratorWrapper(base_it) 3412 self.assertIsInstance(it, typing.AsyncIterable) 3413 self.assertIsInstance(it, typing.AsyncIterable) 3414 self.assertNotIsInstance(42, typing.AsyncIterable) 3415 3416 @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') 3417 def test_async_iterator(self): 3418 base_it = range(10) # type: Iterator[int] 3419 it = AsyncIteratorWrapper(base_it) 3420 self.assertIsInstance(it, typing.AsyncIterator) 3421 self.assertNotIsInstance(42, typing.AsyncIterator) 3422 3423 def test_sized(self): 3424 self.assertIsInstance([], typing.Sized) 3425 self.assertNotIsInstance(42, typing.Sized) 3426 3427 def test_container(self): 3428 self.assertIsInstance([], typing.Container) 3429 self.assertNotIsInstance(42, typing.Container) 3430 3431 def test_collection(self): 3432 if hasattr(typing, 'Collection'): 3433 self.assertIsInstance(tuple(), typing.Collection) 3434 self.assertIsInstance(frozenset(), typing.Collection) 3435 self.assertIsSubclass(dict, typing.Collection) 3436 self.assertNotIsInstance(42, typing.Collection) 3437 3438 def test_abstractset(self): 3439 self.assertIsInstance(set(), typing.AbstractSet) 3440 self.assertNotIsInstance(42, typing.AbstractSet) 3441 3442 def test_mutableset(self): 3443 self.assertIsInstance(set(), typing.MutableSet) 3444 self.assertNotIsInstance(frozenset(), typing.MutableSet) 3445 3446 def test_mapping(self): 3447 self.assertIsInstance({}, typing.Mapping) 3448 self.assertNotIsInstance(42, typing.Mapping) 3449 3450 def test_mutablemapping(self): 3451 self.assertIsInstance({}, typing.MutableMapping) 3452 self.assertNotIsInstance(42, typing.MutableMapping) 3453 3454 def test_sequence(self): 3455 self.assertIsInstance([], typing.Sequence) 3456 self.assertNotIsInstance(42, typing.Sequence) 3457 3458 def test_mutablesequence(self): 3459 self.assertIsInstance([], typing.MutableSequence) 3460 self.assertNotIsInstance((), typing.MutableSequence) 3461 3462 def test_bytestring(self): 3463 self.assertIsInstance(b'', typing.ByteString) 3464 self.assertIsInstance(bytearray(b''), typing.ByteString) 3465 3466 def test_list(self): 3467 self.assertIsSubclass(list, typing.List) 3468 3469 def test_deque(self): 3470 self.assertIsSubclass(collections.deque, typing.Deque) 3471 class MyDeque(typing.Deque[int]): ... 3472 self.assertIsInstance(MyDeque(), collections.deque) 3473 3474 def test_counter(self): 3475 self.assertIsSubclass(collections.Counter, typing.Counter) 3476 3477 def test_set(self): 3478 self.assertIsSubclass(set, typing.Set) 3479 self.assertNotIsSubclass(frozenset, typing.Set) 3480 3481 def test_frozenset(self): 3482 self.assertIsSubclass(frozenset, typing.FrozenSet) 3483 self.assertNotIsSubclass(set, typing.FrozenSet) 3484 3485 def test_dict(self): 3486 self.assertIsSubclass(dict, typing.Dict) 3487 3488 def test_dict_subscribe(self): 3489 K = TypeVar('K') 3490 V = TypeVar('V') 3491 self.assertEqual(Dict[K, V][str, int], Dict[str, int]) 3492 self.assertEqual(Dict[K, int][str], Dict[str, int]) 3493 self.assertEqual(Dict[str, V][int], Dict[str, int]) 3494 self.assertEqual(Dict[K, List[V]][str, int], Dict[str, List[int]]) 3495 self.assertEqual(Dict[K, List[int]][str], Dict[str, List[int]]) 3496 self.assertEqual(Dict[K, list[V]][str, int], Dict[str, list[int]]) 3497 self.assertEqual(Dict[K, list[int]][str], Dict[str, list[int]]) 3498 3499 def test_no_list_instantiation(self): 3500 with self.assertRaises(TypeError): 3501 typing.List() 3502 with self.assertRaises(TypeError): 3503 typing.List[T]() 3504 with self.assertRaises(TypeError): 3505 typing.List[int]() 3506 3507 def test_list_subclass(self): 3508 3509 class MyList(typing.List[int]): 3510 pass 3511 3512 a = MyList() 3513 self.assertIsInstance(a, MyList) 3514 self.assertIsInstance(a, typing.Sequence) 3515 3516 self.assertIsSubclass(MyList, list) 3517 self.assertNotIsSubclass(list, MyList) 3518 3519 def test_no_dict_instantiation(self): 3520 with self.assertRaises(TypeError): 3521 typing.Dict() 3522 with self.assertRaises(TypeError): 3523 typing.Dict[KT, VT]() 3524 with self.assertRaises(TypeError): 3525 typing.Dict[str, int]() 3526 3527 def test_dict_subclass(self): 3528 3529 class MyDict(typing.Dict[str, int]): 3530 pass 3531 3532 d = MyDict() 3533 self.assertIsInstance(d, MyDict) 3534 self.assertIsInstance(d, typing.MutableMapping) 3535 3536 self.assertIsSubclass(MyDict, dict) 3537 self.assertNotIsSubclass(dict, MyDict) 3538 3539 def test_defaultdict_instantiation(self): 3540 self.assertIs(type(typing.DefaultDict()), collections.defaultdict) 3541 self.assertIs(type(typing.DefaultDict[KT, VT]()), collections.defaultdict) 3542 self.assertIs(type(typing.DefaultDict[str, int]()), collections.defaultdict) 3543 3544 def test_defaultdict_subclass(self): 3545 3546 class MyDefDict(typing.DefaultDict[str, int]): 3547 pass 3548 3549 dd = MyDefDict() 3550 self.assertIsInstance(dd, MyDefDict) 3551 3552 self.assertIsSubclass(MyDefDict, collections.defaultdict) 3553 self.assertNotIsSubclass(collections.defaultdict, MyDefDict) 3554 3555 def test_ordereddict_instantiation(self): 3556 self.assertIs(type(typing.OrderedDict()), collections.OrderedDict) 3557 self.assertIs(type(typing.OrderedDict[KT, VT]()), collections.OrderedDict) 3558 self.assertIs(type(typing.OrderedDict[str, int]()), collections.OrderedDict) 3559 3560 def test_ordereddict_subclass(self): 3561 3562 class MyOrdDict(typing.OrderedDict[str, int]): 3563 pass 3564 3565 od = MyOrdDict() 3566 self.assertIsInstance(od, MyOrdDict) 3567 3568 self.assertIsSubclass(MyOrdDict, collections.OrderedDict) 3569 self.assertNotIsSubclass(collections.OrderedDict, MyOrdDict) 3570 3571 @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') 3572 def test_chainmap_instantiation(self): 3573 self.assertIs(type(typing.ChainMap()), collections.ChainMap) 3574 self.assertIs(type(typing.ChainMap[KT, VT]()), collections.ChainMap) 3575 self.assertIs(type(typing.ChainMap[str, int]()), collections.ChainMap) 3576 class CM(typing.ChainMap[KT, VT]): ... 3577 self.assertIs(type(CM[int, str]()), CM) 3578 3579 @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') 3580 def test_chainmap_subclass(self): 3581 3582 class MyChainMap(typing.ChainMap[str, int]): 3583 pass 3584 3585 cm = MyChainMap() 3586 self.assertIsInstance(cm, MyChainMap) 3587 3588 self.assertIsSubclass(MyChainMap, collections.ChainMap) 3589 self.assertNotIsSubclass(collections.ChainMap, MyChainMap) 3590 3591 def test_deque_instantiation(self): 3592 self.assertIs(type(typing.Deque()), collections.deque) 3593 self.assertIs(type(typing.Deque[T]()), collections.deque) 3594 self.assertIs(type(typing.Deque[int]()), collections.deque) 3595 class D(typing.Deque[T]): ... 3596 self.assertIs(type(D[int]()), D) 3597 3598 def test_counter_instantiation(self): 3599 self.assertIs(type(typing.Counter()), collections.Counter) 3600 self.assertIs(type(typing.Counter[T]()), collections.Counter) 3601 self.assertIs(type(typing.Counter[int]()), collections.Counter) 3602 class C(typing.Counter[T]): ... 3603 self.assertIs(type(C[int]()), C) 3604 3605 def test_counter_subclass_instantiation(self): 3606 3607 class MyCounter(typing.Counter[int]): 3608 pass 3609 3610 d = MyCounter() 3611 self.assertIsInstance(d, MyCounter) 3612 self.assertIsInstance(d, typing.Counter) 3613 self.assertIsInstance(d, collections.Counter) 3614 3615 def test_no_set_instantiation(self): 3616 with self.assertRaises(TypeError): 3617 typing.Set() 3618 with self.assertRaises(TypeError): 3619 typing.Set[T]() 3620 with self.assertRaises(TypeError): 3621 typing.Set[int]() 3622 3623 def test_set_subclass_instantiation(self): 3624 3625 class MySet(typing.Set[int]): 3626 pass 3627 3628 d = MySet() 3629 self.assertIsInstance(d, MySet) 3630 3631 def test_no_frozenset_instantiation(self): 3632 with self.assertRaises(TypeError): 3633 typing.FrozenSet() 3634 with self.assertRaises(TypeError): 3635 typing.FrozenSet[T]() 3636 with self.assertRaises(TypeError): 3637 typing.FrozenSet[int]() 3638 3639 def test_frozenset_subclass_instantiation(self): 3640 3641 class MyFrozenSet(typing.FrozenSet[int]): 3642 pass 3643 3644 d = MyFrozenSet() 3645 self.assertIsInstance(d, MyFrozenSet) 3646 3647 def test_no_tuple_instantiation(self): 3648 with self.assertRaises(TypeError): 3649 Tuple() 3650 with self.assertRaises(TypeError): 3651 Tuple[T]() 3652 with self.assertRaises(TypeError): 3653 Tuple[int]() 3654 3655 def test_generator(self): 3656 def foo(): 3657 yield 42 3658 g = foo() 3659 self.assertIsSubclass(type(g), typing.Generator) 3660 3661 def test_no_generator_instantiation(self): 3662 with self.assertRaises(TypeError): 3663 typing.Generator() 3664 with self.assertRaises(TypeError): 3665 typing.Generator[T, T, T]() 3666 with self.assertRaises(TypeError): 3667 typing.Generator[int, int, int]() 3668 3669 def test_async_generator(self): 3670 ns = {} 3671 exec("async def f():\n" 3672 " yield 42\n", globals(), ns) 3673 g = ns['f']() 3674 self.assertIsSubclass(type(g), typing.AsyncGenerator) 3675 3676 def test_no_async_generator_instantiation(self): 3677 with self.assertRaises(TypeError): 3678 typing.AsyncGenerator() 3679 with self.assertRaises(TypeError): 3680 typing.AsyncGenerator[T, T]() 3681 with self.assertRaises(TypeError): 3682 typing.AsyncGenerator[int, int]() 3683 3684 def test_subclassing(self): 3685 3686 class MMA(typing.MutableMapping): 3687 pass 3688 3689 with self.assertRaises(TypeError): # It's abstract 3690 MMA() 3691 3692 class MMC(MMA): 3693 def __getitem__(self, k): 3694 return None 3695 def __setitem__(self, k, v): 3696 pass 3697 def __delitem__(self, k): 3698 pass 3699 def __iter__(self): 3700 return iter(()) 3701 def __len__(self): 3702 return 0 3703 3704 self.assertEqual(len(MMC()), 0) 3705 assert callable(MMC.update) 3706 self.assertIsInstance(MMC(), typing.Mapping) 3707 3708 class MMB(typing.MutableMapping[KT, VT]): 3709 def __getitem__(self, k): 3710 return None 3711 def __setitem__(self, k, v): 3712 pass 3713 def __delitem__(self, k): 3714 pass 3715 def __iter__(self): 3716 return iter(()) 3717 def __len__(self): 3718 return 0 3719 3720 self.assertEqual(len(MMB()), 0) 3721 self.assertEqual(len(MMB[str, str]()), 0) 3722 self.assertEqual(len(MMB[KT, VT]()), 0) 3723 3724 self.assertNotIsSubclass(dict, MMA) 3725 self.assertNotIsSubclass(dict, MMB) 3726 3727 self.assertIsSubclass(MMA, typing.Mapping) 3728 self.assertIsSubclass(MMB, typing.Mapping) 3729 self.assertIsSubclass(MMC, typing.Mapping) 3730 3731 self.assertIsInstance(MMB[KT, VT](), typing.Mapping) 3732 self.assertIsInstance(MMB[KT, VT](), collections.abc.Mapping) 3733 3734 self.assertIsSubclass(MMA, collections.abc.Mapping) 3735 self.assertIsSubclass(MMB, collections.abc.Mapping) 3736 self.assertIsSubclass(MMC, collections.abc.Mapping) 3737 3738 with self.assertRaises(TypeError): 3739 issubclass(MMB[str, str], typing.Mapping) 3740 self.assertIsSubclass(MMC, MMA) 3741 3742 class I(typing.Iterable): ... 3743 self.assertNotIsSubclass(list, I) 3744 3745 class G(typing.Generator[int, int, int]): ... 3746 def g(): yield 0 3747 self.assertIsSubclass(G, typing.Generator) 3748 self.assertIsSubclass(G, typing.Iterable) 3749 self.assertIsSubclass(G, collections.abc.Generator) 3750 self.assertIsSubclass(G, collections.abc.Iterable) 3751 self.assertNotIsSubclass(type(g), G) 3752 3753 def test_subclassing_async_generator(self): 3754 class G(typing.AsyncGenerator[int, int]): 3755 def asend(self, value): 3756 pass 3757 def athrow(self, typ, val=None, tb=None): 3758 pass 3759 3760 ns = {} 3761 exec('async def g(): yield 0', globals(), ns) 3762 g = ns['g'] 3763 self.assertIsSubclass(G, typing.AsyncGenerator) 3764 self.assertIsSubclass(G, typing.AsyncIterable) 3765 self.assertIsSubclass(G, collections.abc.AsyncGenerator) 3766 self.assertIsSubclass(G, collections.abc.AsyncIterable) 3767 self.assertNotIsSubclass(type(g), G) 3768 3769 instance = G() 3770 self.assertIsInstance(instance, typing.AsyncGenerator) 3771 self.assertIsInstance(instance, typing.AsyncIterable) 3772 self.assertIsInstance(instance, collections.abc.AsyncGenerator) 3773 self.assertIsInstance(instance, collections.abc.AsyncIterable) 3774 self.assertNotIsInstance(type(g), G) 3775 self.assertNotIsInstance(g, G) 3776 3777 def test_subclassing_subclasshook(self): 3778 3779 class Base(typing.Iterable): 3780 @classmethod 3781 def __subclasshook__(cls, other): 3782 if other.__name__ == 'Foo': 3783 return True 3784 else: 3785 return False 3786 3787 class C(Base): ... 3788 class Foo: ... 3789 class Bar: ... 3790 self.assertIsSubclass(Foo, Base) 3791 self.assertIsSubclass(Foo, C) 3792 self.assertNotIsSubclass(Bar, C) 3793 3794 def test_subclassing_register(self): 3795 3796 class A(typing.Container): ... 3797 class B(A): ... 3798 3799 class C: ... 3800 A.register(C) 3801 self.assertIsSubclass(C, A) 3802 self.assertNotIsSubclass(C, B) 3803 3804 class D: ... 3805 B.register(D) 3806 self.assertIsSubclass(D, A) 3807 self.assertIsSubclass(D, B) 3808 3809 class M(): ... 3810 collections.abc.MutableMapping.register(M) 3811 self.assertIsSubclass(M, typing.Mapping) 3812 3813 def test_collections_as_base(self): 3814 3815 class M(collections.abc.Mapping): ... 3816 self.assertIsSubclass(M, typing.Mapping) 3817 self.assertIsSubclass(M, typing.Iterable) 3818 3819 class S(collections.abc.MutableSequence): ... 3820 self.assertIsSubclass(S, typing.MutableSequence) 3821 self.assertIsSubclass(S, typing.Iterable) 3822 3823 class I(collections.abc.Iterable): ... 3824 self.assertIsSubclass(I, typing.Iterable) 3825 3826 class A(collections.abc.Mapping, metaclass=abc.ABCMeta): ... 3827 class B: ... 3828 A.register(B) 3829 self.assertIsSubclass(B, typing.Mapping) 3830 3831 3832class OtherABCTests(BaseTestCase): 3833 3834 def test_contextmanager(self): 3835 @contextlib.contextmanager 3836 def manager(): 3837 yield 42 3838 3839 cm = manager() 3840 self.assertIsInstance(cm, typing.ContextManager) 3841 self.assertNotIsInstance(42, typing.ContextManager) 3842 3843 @skipUnless(ASYNCIO, 'Python 3.5 required') 3844 def test_async_contextmanager(self): 3845 class NotACM: 3846 pass 3847 self.assertIsInstance(ACM(), typing.AsyncContextManager) 3848 self.assertNotIsInstance(NotACM(), typing.AsyncContextManager) 3849 @contextlib.contextmanager 3850 def manager(): 3851 yield 42 3852 3853 cm = manager() 3854 self.assertNotIsInstance(cm, typing.AsyncContextManager) 3855 self.assertEqual(typing.AsyncContextManager[int].__args__, (int,)) 3856 with self.assertRaises(TypeError): 3857 isinstance(42, typing.AsyncContextManager[int]) 3858 with self.assertRaises(TypeError): 3859 typing.AsyncContextManager[int, str] 3860 3861 3862class TypeTests(BaseTestCase): 3863 3864 def test_type_basic(self): 3865 3866 class User: pass 3867 class BasicUser(User): pass 3868 class ProUser(User): pass 3869 3870 def new_user(user_class: Type[User]) -> User: 3871 return user_class() 3872 3873 new_user(BasicUser) 3874 3875 def test_type_typevar(self): 3876 3877 class User: pass 3878 class BasicUser(User): pass 3879 class ProUser(User): pass 3880 3881 U = TypeVar('U', bound=User) 3882 3883 def new_user(user_class: Type[U]) -> U: 3884 return user_class() 3885 3886 new_user(BasicUser) 3887 3888 def test_type_optional(self): 3889 A = Optional[Type[BaseException]] 3890 3891 def foo(a: A) -> Optional[BaseException]: 3892 if a is None: 3893 return None 3894 else: 3895 return a() 3896 3897 assert isinstance(foo(KeyboardInterrupt), KeyboardInterrupt) 3898 assert foo(None) is None 3899 3900 3901class NewTypeTests(BaseTestCase): 3902 @classmethod 3903 def setUpClass(cls): 3904 global UserId 3905 UserId = NewType('UserId', int) 3906 cls.UserName = NewType(cls.__qualname__ + '.UserName', str) 3907 3908 @classmethod 3909 def tearDownClass(cls): 3910 global UserId 3911 del UserId 3912 del cls.UserName 3913 3914 def tearDown(self): 3915 self.clear_caches() 3916 3917 def test_basic(self): 3918 self.assertIsInstance(UserId(5), int) 3919 self.assertIsInstance(self.UserName('Joe'), str) 3920 self.assertEqual(UserId(5) + 1, 6) 3921 3922 def test_errors(self): 3923 with self.assertRaises(TypeError): 3924 issubclass(UserId, int) 3925 with self.assertRaises(TypeError): 3926 class D(UserId): 3927 pass 3928 3929 def test_or(self): 3930 for cls in (int, self.UserName): 3931 with self.subTest(cls=cls): 3932 self.assertEqual(UserId | cls, Union[UserId, cls]) 3933 self.assertEqual(cls | UserId, Union[cls, UserId]) 3934 3935 self.assertEqual(get_args(UserId | cls), (UserId, cls)) 3936 self.assertEqual(get_args(cls | UserId), (cls, UserId)) 3937 3938 def test_special_attrs(self): 3939 self.assertEqual(UserId.__name__, 'UserId') 3940 self.assertEqual(UserId.__qualname__, 'UserId') 3941 self.assertEqual(UserId.__module__, __name__) 3942 self.assertEqual(UserId.__supertype__, int) 3943 3944 UserName = self.UserName 3945 self.assertEqual(UserName.__name__, 'UserName') 3946 self.assertEqual(UserName.__qualname__, 3947 self.__class__.__qualname__ + '.UserName') 3948 self.assertEqual(UserName.__module__, __name__) 3949 self.assertEqual(UserName.__supertype__, str) 3950 3951 def test_repr(self): 3952 self.assertEqual(repr(UserId), f'{__name__}.UserId') 3953 self.assertEqual(repr(self.UserName), 3954 f'{__name__}.{self.__class__.__qualname__}.UserName') 3955 3956 def test_pickle(self): 3957 UserAge = NewType('UserAge', float) 3958 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 3959 with self.subTest(proto=proto): 3960 pickled = pickle.dumps(UserId, proto) 3961 loaded = pickle.loads(pickled) 3962 self.assertIs(loaded, UserId) 3963 3964 pickled = pickle.dumps(self.UserName, proto) 3965 loaded = pickle.loads(pickled) 3966 self.assertIs(loaded, self.UserName) 3967 3968 with self.assertRaises(pickle.PicklingError): 3969 pickle.dumps(UserAge, proto) 3970 3971 def test_missing__name__(self): 3972 code = ("import typing\n" 3973 "NT = typing.NewType('NT', int)\n" 3974 ) 3975 exec(code, {}) 3976 3977 3978class NamedTupleTests(BaseTestCase): 3979 class NestedEmployee(NamedTuple): 3980 name: str 3981 cool: int 3982 3983 def test_basics(self): 3984 Emp = NamedTuple('Emp', [('name', str), ('id', int)]) 3985 self.assertIsSubclass(Emp, tuple) 3986 joe = Emp('Joe', 42) 3987 jim = Emp(name='Jim', id=1) 3988 self.assertIsInstance(joe, Emp) 3989 self.assertIsInstance(joe, tuple) 3990 self.assertEqual(joe.name, 'Joe') 3991 self.assertEqual(joe.id, 42) 3992 self.assertEqual(jim.name, 'Jim') 3993 self.assertEqual(jim.id, 1) 3994 self.assertEqual(Emp.__name__, 'Emp') 3995 self.assertEqual(Emp._fields, ('name', 'id')) 3996 self.assertEqual(Emp.__annotations__, 3997 collections.OrderedDict([('name', str), ('id', int)])) 3998 3999 def test_namedtuple_pyversion(self): 4000 if sys.version_info[:2] < (3, 6): 4001 with self.assertRaises(TypeError): 4002 NamedTuple('Name', one=int, other=str) 4003 with self.assertRaises(TypeError): 4004 class NotYet(NamedTuple): 4005 whatever = 0 4006 4007 def test_annotation_usage(self): 4008 tim = CoolEmployee('Tim', 9000) 4009 self.assertIsInstance(tim, CoolEmployee) 4010 self.assertIsInstance(tim, tuple) 4011 self.assertEqual(tim.name, 'Tim') 4012 self.assertEqual(tim.cool, 9000) 4013 self.assertEqual(CoolEmployee.__name__, 'CoolEmployee') 4014 self.assertEqual(CoolEmployee._fields, ('name', 'cool')) 4015 self.assertEqual(CoolEmployee.__annotations__, 4016 collections.OrderedDict(name=str, cool=int)) 4017 4018 def test_annotation_usage_with_default(self): 4019 jelle = CoolEmployeeWithDefault('Jelle') 4020 self.assertIsInstance(jelle, CoolEmployeeWithDefault) 4021 self.assertIsInstance(jelle, tuple) 4022 self.assertEqual(jelle.name, 'Jelle') 4023 self.assertEqual(jelle.cool, 0) 4024 cooler_employee = CoolEmployeeWithDefault('Sjoerd', 1) 4025 self.assertEqual(cooler_employee.cool, 1) 4026 4027 self.assertEqual(CoolEmployeeWithDefault.__name__, 'CoolEmployeeWithDefault') 4028 self.assertEqual(CoolEmployeeWithDefault._fields, ('name', 'cool')) 4029 self.assertEqual(CoolEmployeeWithDefault.__annotations__, 4030 dict(name=str, cool=int)) 4031 self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0)) 4032 4033 with self.assertRaises(TypeError): 4034 class NonDefaultAfterDefault(NamedTuple): 4035 x: int = 3 4036 y: int 4037 4038 def test_annotation_usage_with_methods(self): 4039 self.assertEqual(XMeth(1).double(), 2) 4040 self.assertEqual(XMeth(42).x, XMeth(42)[0]) 4041 self.assertEqual(str(XRepr(42)), '42 -> 1') 4042 self.assertEqual(XRepr(1, 2) + XRepr(3), 0) 4043 4044 with self.assertRaises(AttributeError): 4045 class XMethBad(NamedTuple): 4046 x: int 4047 def _fields(self): 4048 return 'no chance for this' 4049 4050 with self.assertRaises(AttributeError): 4051 class XMethBad2(NamedTuple): 4052 x: int 4053 def _source(self): 4054 return 'no chance for this as well' 4055 4056 def test_multiple_inheritance(self): 4057 class A: 4058 pass 4059 with self.assertRaises(TypeError): 4060 class X(NamedTuple, A): 4061 x: int 4062 4063 def test_namedtuple_keyword_usage(self): 4064 LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int) 4065 nick = LocalEmployee('Nick', 25) 4066 self.assertIsInstance(nick, tuple) 4067 self.assertEqual(nick.name, 'Nick') 4068 self.assertEqual(LocalEmployee.__name__, 'LocalEmployee') 4069 self.assertEqual(LocalEmployee._fields, ('name', 'age')) 4070 self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int)) 4071 with self.assertRaises(TypeError): 4072 NamedTuple('Name', [('x', int)], y=str) 4073 with self.assertRaises(TypeError): 4074 NamedTuple('Name', x=1, y='a') 4075 4076 def test_namedtuple_special_keyword_names(self): 4077 NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list) 4078 self.assertEqual(NT.__name__, 'NT') 4079 self.assertEqual(NT._fields, ('cls', 'self', 'typename', 'fields')) 4080 a = NT(cls=str, self=42, typename='foo', fields=[('bar', tuple)]) 4081 self.assertEqual(a.cls, str) 4082 self.assertEqual(a.self, 42) 4083 self.assertEqual(a.typename, 'foo') 4084 self.assertEqual(a.fields, [('bar', tuple)]) 4085 4086 def test_empty_namedtuple(self): 4087 NT = NamedTuple('NT') 4088 4089 class CNT(NamedTuple): 4090 pass # empty body 4091 4092 for struct in [NT, CNT]: 4093 with self.subTest(struct=struct): 4094 self.assertEqual(struct._fields, ()) 4095 self.assertEqual(struct._field_defaults, {}) 4096 self.assertEqual(struct.__annotations__, {}) 4097 self.assertIsInstance(struct(), struct) 4098 4099 def test_namedtuple_errors(self): 4100 with self.assertRaises(TypeError): 4101 NamedTuple.__new__() 4102 with self.assertRaises(TypeError): 4103 NamedTuple() 4104 with self.assertRaises(TypeError): 4105 NamedTuple('Emp', [('name', str)], None) 4106 with self.assertRaises(ValueError): 4107 NamedTuple('Emp', [('_name', str)]) 4108 with self.assertRaises(TypeError): 4109 NamedTuple(typename='Emp', name=str, id=int) 4110 with self.assertRaises(TypeError): 4111 NamedTuple('Emp', fields=[('name', str), ('id', int)]) 4112 4113 def test_copy_and_pickle(self): 4114 global Emp # pickle wants to reference the class by name 4115 Emp = NamedTuple('Emp', [('name', str), ('cool', int)]) 4116 for cls in Emp, CoolEmployee, self.NestedEmployee: 4117 with self.subTest(cls=cls): 4118 jane = cls('jane', 37) 4119 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 4120 z = pickle.dumps(jane, proto) 4121 jane2 = pickle.loads(z) 4122 self.assertEqual(jane2, jane) 4123 self.assertIsInstance(jane2, cls) 4124 4125 jane2 = copy(jane) 4126 self.assertEqual(jane2, jane) 4127 self.assertIsInstance(jane2, cls) 4128 4129 jane2 = deepcopy(jane) 4130 self.assertEqual(jane2, jane) 4131 self.assertIsInstance(jane2, cls) 4132 4133 4134class TypedDictTests(BaseTestCase): 4135 def test_basics_functional_syntax(self): 4136 Emp = TypedDict('Emp', {'name': str, 'id': int}) 4137 self.assertIsSubclass(Emp, dict) 4138 self.assertIsSubclass(Emp, typing.MutableMapping) 4139 self.assertNotIsSubclass(Emp, collections.abc.Sequence) 4140 jim = Emp(name='Jim', id=1) 4141 self.assertIs(type(jim), dict) 4142 self.assertEqual(jim['name'], 'Jim') 4143 self.assertEqual(jim['id'], 1) 4144 self.assertEqual(Emp.__name__, 'Emp') 4145 self.assertEqual(Emp.__module__, __name__) 4146 self.assertEqual(Emp.__bases__, (dict,)) 4147 self.assertEqual(Emp.__annotations__, {'name': str, 'id': int}) 4148 self.assertEqual(Emp.__total__, True) 4149 4150 def test_basics_keywords_syntax(self): 4151 Emp = TypedDict('Emp', name=str, id=int) 4152 self.assertIsSubclass(Emp, dict) 4153 self.assertIsSubclass(Emp, typing.MutableMapping) 4154 self.assertNotIsSubclass(Emp, collections.abc.Sequence) 4155 jim = Emp(name='Jim', id=1) 4156 self.assertIs(type(jim), dict) 4157 self.assertEqual(jim['name'], 'Jim') 4158 self.assertEqual(jim['id'], 1) 4159 self.assertEqual(Emp.__name__, 'Emp') 4160 self.assertEqual(Emp.__module__, __name__) 4161 self.assertEqual(Emp.__bases__, (dict,)) 4162 self.assertEqual(Emp.__annotations__, {'name': str, 'id': int}) 4163 self.assertEqual(Emp.__total__, True) 4164 4165 def test_typeddict_special_keyword_names(self): 4166 TD = TypedDict("TD", cls=type, self=object, typename=str, _typename=int, fields=list, _fields=dict) 4167 self.assertEqual(TD.__name__, 'TD') 4168 self.assertEqual(TD.__annotations__, {'cls': type, 'self': object, 'typename': str, '_typename': int, 'fields': list, '_fields': dict}) 4169 a = TD(cls=str, self=42, typename='foo', _typename=53, fields=[('bar', tuple)], _fields={'baz', set}) 4170 self.assertEqual(a['cls'], str) 4171 self.assertEqual(a['self'], 42) 4172 self.assertEqual(a['typename'], 'foo') 4173 self.assertEqual(a['_typename'], 53) 4174 self.assertEqual(a['fields'], [('bar', tuple)]) 4175 self.assertEqual(a['_fields'], {'baz', set}) 4176 4177 def test_typeddict_create_errors(self): 4178 with self.assertRaises(TypeError): 4179 TypedDict.__new__() 4180 with self.assertRaises(TypeError): 4181 TypedDict() 4182 with self.assertRaises(TypeError): 4183 TypedDict('Emp', [('name', str)], None) 4184 4185 with self.assertRaises(TypeError): 4186 TypedDict(_typename='Emp', name=str, id=int) 4187 with self.assertRaises(TypeError): 4188 TypedDict('Emp', _fields={'name': str, 'id': int}) 4189 4190 def test_typeddict_errors(self): 4191 Emp = TypedDict('Emp', {'name': str, 'id': int}) 4192 self.assertEqual(TypedDict.__module__, 'typing') 4193 jim = Emp(name='Jim', id=1) 4194 with self.assertRaises(TypeError): 4195 isinstance({}, Emp) 4196 with self.assertRaises(TypeError): 4197 isinstance(jim, Emp) 4198 with self.assertRaises(TypeError): 4199 issubclass(dict, Emp) 4200 with self.assertRaises(TypeError): 4201 TypedDict('Hi', x=1) 4202 with self.assertRaises(TypeError): 4203 TypedDict('Hi', [('x', int), ('y', 1)]) 4204 with self.assertRaises(TypeError): 4205 TypedDict('Hi', [('x', int)], y=int) 4206 4207 def test_py36_class_syntax_usage(self): 4208 self.assertEqual(LabelPoint2D.__name__, 'LabelPoint2D') 4209 self.assertEqual(LabelPoint2D.__module__, __name__) 4210 self.assertEqual(LabelPoint2D.__annotations__, {'x': int, 'y': int, 'label': str}) 4211 self.assertEqual(LabelPoint2D.__bases__, (dict,)) 4212 self.assertEqual(LabelPoint2D.__total__, True) 4213 self.assertNotIsSubclass(LabelPoint2D, typing.Sequence) 4214 not_origin = Point2D(x=0, y=1) 4215 self.assertEqual(not_origin['x'], 0) 4216 self.assertEqual(not_origin['y'], 1) 4217 other = LabelPoint2D(x=0, y=1, label='hi') 4218 self.assertEqual(other['label'], 'hi') 4219 4220 def test_pickle(self): 4221 global EmpD # pickle wants to reference the class by name 4222 EmpD = TypedDict('EmpD', name=str, id=int) 4223 jane = EmpD({'name': 'jane', 'id': 37}) 4224 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 4225 z = pickle.dumps(jane, proto) 4226 jane2 = pickle.loads(z) 4227 self.assertEqual(jane2, jane) 4228 self.assertEqual(jane2, {'name': 'jane', 'id': 37}) 4229 ZZ = pickle.dumps(EmpD, proto) 4230 EmpDnew = pickle.loads(ZZ) 4231 self.assertEqual(EmpDnew({'name': 'jane', 'id': 37}), jane) 4232 4233 def test_optional(self): 4234 EmpD = TypedDict('EmpD', name=str, id=int) 4235 4236 self.assertEqual(typing.Optional[EmpD], typing.Union[None, EmpD]) 4237 self.assertNotEqual(typing.List[EmpD], typing.Tuple[EmpD]) 4238 4239 def test_total(self): 4240 D = TypedDict('D', {'x': int}, total=False) 4241 self.assertEqual(D(), {}) 4242 self.assertEqual(D(x=1), {'x': 1}) 4243 self.assertEqual(D.__total__, False) 4244 self.assertEqual(D.__required_keys__, frozenset()) 4245 self.assertEqual(D.__optional_keys__, {'x'}) 4246 4247 self.assertEqual(Options(), {}) 4248 self.assertEqual(Options(log_level=2), {'log_level': 2}) 4249 self.assertEqual(Options.__total__, False) 4250 self.assertEqual(Options.__required_keys__, frozenset()) 4251 self.assertEqual(Options.__optional_keys__, {'log_level', 'log_path'}) 4252 4253 def test_optional_keys(self): 4254 class Point2Dor3D(Point2D, total=False): 4255 z: int 4256 4257 assert Point2Dor3D.__required_keys__ == frozenset(['x', 'y']) 4258 assert Point2Dor3D.__optional_keys__ == frozenset(['z']) 4259 4260 def test_keys_inheritance(self): 4261 class BaseAnimal(TypedDict): 4262 name: str 4263 4264 class Animal(BaseAnimal, total=False): 4265 voice: str 4266 tail: bool 4267 4268 class Cat(Animal): 4269 fur_color: str 4270 4271 assert BaseAnimal.__required_keys__ == frozenset(['name']) 4272 assert BaseAnimal.__optional_keys__ == frozenset([]) 4273 assert BaseAnimal.__annotations__ == {'name': str} 4274 4275 assert Animal.__required_keys__ == frozenset(['name']) 4276 assert Animal.__optional_keys__ == frozenset(['tail', 'voice']) 4277 assert Animal.__annotations__ == { 4278 'name': str, 4279 'tail': bool, 4280 'voice': str, 4281 } 4282 4283 assert Cat.__required_keys__ == frozenset(['name', 'fur_color']) 4284 assert Cat.__optional_keys__ == frozenset(['tail', 'voice']) 4285 assert Cat.__annotations__ == { 4286 'fur_color': str, 4287 'name': str, 4288 'tail': bool, 4289 'voice': str, 4290 } 4291 4292 def test_is_typeddict(self): 4293 assert is_typeddict(Point2D) is True 4294 assert is_typeddict(Union[str, int]) is False 4295 # classes, not instances 4296 assert is_typeddict(Point2D()) is False 4297 4298 def test_get_type_hints(self): 4299 self.assertEqual( 4300 get_type_hints(Bar), 4301 {'a': typing.Optional[int], 'b': int} 4302 ) 4303 4304 4305class IOTests(BaseTestCase): 4306 4307 def test_io(self): 4308 4309 def stuff(a: IO) -> AnyStr: 4310 return a.readline() 4311 4312 a = stuff.__annotations__['a'] 4313 self.assertEqual(a.__parameters__, (AnyStr,)) 4314 4315 def test_textio(self): 4316 4317 def stuff(a: TextIO) -> str: 4318 return a.readline() 4319 4320 a = stuff.__annotations__['a'] 4321 self.assertEqual(a.__parameters__, ()) 4322 4323 def test_binaryio(self): 4324 4325 def stuff(a: BinaryIO) -> bytes: 4326 return a.readline() 4327 4328 a = stuff.__annotations__['a'] 4329 self.assertEqual(a.__parameters__, ()) 4330 4331 def test_io_submodule(self): 4332 from typing.io import IO, TextIO, BinaryIO, __all__, __name__ 4333 self.assertIs(IO, typing.IO) 4334 self.assertIs(TextIO, typing.TextIO) 4335 self.assertIs(BinaryIO, typing.BinaryIO) 4336 self.assertEqual(set(__all__), set(['IO', 'TextIO', 'BinaryIO'])) 4337 self.assertEqual(__name__, 'typing.io') 4338 4339 4340class RETests(BaseTestCase): 4341 # Much of this is really testing _TypeAlias. 4342 4343 def test_basics(self): 4344 pat = re.compile('[a-z]+', re.I) 4345 self.assertIsSubclass(pat.__class__, Pattern) 4346 self.assertIsSubclass(type(pat), Pattern) 4347 self.assertIsInstance(pat, Pattern) 4348 4349 mat = pat.search('12345abcde.....') 4350 self.assertIsSubclass(mat.__class__, Match) 4351 self.assertIsSubclass(type(mat), Match) 4352 self.assertIsInstance(mat, Match) 4353 4354 # these should just work 4355 Pattern[Union[str, bytes]] 4356 Match[Union[bytes, str]] 4357 4358 def test_alias_equality(self): 4359 self.assertEqual(Pattern[str], Pattern[str]) 4360 self.assertNotEqual(Pattern[str], Pattern[bytes]) 4361 self.assertNotEqual(Pattern[str], Match[str]) 4362 self.assertNotEqual(Pattern[str], str) 4363 4364 def test_errors(self): 4365 m = Match[Union[str, bytes]] 4366 with self.assertRaises(TypeError): 4367 m[str] 4368 with self.assertRaises(TypeError): 4369 # We don't support isinstance(). 4370 isinstance(42, Pattern[str]) 4371 with self.assertRaises(TypeError): 4372 # We don't support issubclass(). 4373 issubclass(Pattern[bytes], Pattern[str]) 4374 4375 def test_repr(self): 4376 self.assertEqual(repr(Pattern), 'typing.Pattern') 4377 self.assertEqual(repr(Pattern[str]), 'typing.Pattern[str]') 4378 self.assertEqual(repr(Pattern[bytes]), 'typing.Pattern[bytes]') 4379 self.assertEqual(repr(Match), 'typing.Match') 4380 self.assertEqual(repr(Match[str]), 'typing.Match[str]') 4381 self.assertEqual(repr(Match[bytes]), 'typing.Match[bytes]') 4382 4383 def test_re_submodule(self): 4384 from typing.re import Match, Pattern, __all__, __name__ 4385 self.assertIs(Match, typing.Match) 4386 self.assertIs(Pattern, typing.Pattern) 4387 self.assertEqual(set(__all__), set(['Match', 'Pattern'])) 4388 self.assertEqual(__name__, 'typing.re') 4389 4390 def test_cannot_subclass(self): 4391 with self.assertRaises(TypeError) as ex: 4392 4393 class A(typing.Match): 4394 pass 4395 4396 self.assertEqual(str(ex.exception), 4397 "type 're.Match' is not an acceptable base type") 4398 4399 4400class AnnotatedTests(BaseTestCase): 4401 4402 def test_repr(self): 4403 self.assertEqual( 4404 repr(Annotated[int, 4, 5]), 4405 "typing.Annotated[int, 4, 5]" 4406 ) 4407 self.assertEqual( 4408 repr(Annotated[List[int], 4, 5]), 4409 "typing.Annotated[typing.List[int], 4, 5]" 4410 ) 4411 4412 def test_flatten(self): 4413 A = Annotated[Annotated[int, 4], 5] 4414 self.assertEqual(A, Annotated[int, 4, 5]) 4415 self.assertEqual(A.__metadata__, (4, 5)) 4416 self.assertEqual(A.__origin__, int) 4417 4418 def test_specialize(self): 4419 L = Annotated[List[T], "my decoration"] 4420 LI = Annotated[List[int], "my decoration"] 4421 self.assertEqual(L[int], Annotated[List[int], "my decoration"]) 4422 self.assertEqual(L[int].__metadata__, ("my decoration",)) 4423 self.assertEqual(L[int].__origin__, List[int]) 4424 with self.assertRaises(TypeError): 4425 LI[int] 4426 with self.assertRaises(TypeError): 4427 L[int, float] 4428 4429 def test_hash_eq(self): 4430 self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1) 4431 self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4]) 4432 self.assertNotEqual(Annotated[int, 4, 5], Annotated[str, 4, 5]) 4433 self.assertNotEqual(Annotated[int, 4], Annotated[int, 4, 4]) 4434 self.assertEqual( 4435 {Annotated[int, 4, 5], Annotated[int, 4, 5], Annotated[T, 4, 5]}, 4436 {Annotated[int, 4, 5], Annotated[T, 4, 5]} 4437 ) 4438 4439 def test_instantiate(self): 4440 class C: 4441 classvar = 4 4442 4443 def __init__(self, x): 4444 self.x = x 4445 4446 def __eq__(self, other): 4447 if not isinstance(other, C): 4448 return NotImplemented 4449 return other.x == self.x 4450 4451 A = Annotated[C, "a decoration"] 4452 a = A(5) 4453 c = C(5) 4454 self.assertEqual(a, c) 4455 self.assertEqual(a.x, c.x) 4456 self.assertEqual(a.classvar, c.classvar) 4457 4458 def test_instantiate_generic(self): 4459 MyCount = Annotated[typing.Counter[T], "my decoration"] 4460 self.assertEqual(MyCount([4, 4, 5]), {4: 2, 5: 1}) 4461 self.assertEqual(MyCount[int]([4, 4, 5]), {4: 2, 5: 1}) 4462 4463 def test_cannot_instantiate_forward(self): 4464 A = Annotated["int", (5, 6)] 4465 with self.assertRaises(TypeError): 4466 A(5) 4467 4468 def test_cannot_instantiate_type_var(self): 4469 A = Annotated[T, (5, 6)] 4470 with self.assertRaises(TypeError): 4471 A(5) 4472 4473 def test_cannot_getattr_typevar(self): 4474 with self.assertRaises(AttributeError): 4475 Annotated[T, (5, 7)].x 4476 4477 def test_attr_passthrough(self): 4478 class C: 4479 classvar = 4 4480 4481 A = Annotated[C, "a decoration"] 4482 self.assertEqual(A.classvar, 4) 4483 A.x = 5 4484 self.assertEqual(C.x, 5) 4485 4486 def test_hash_eq(self): 4487 self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1) 4488 self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4]) 4489 self.assertNotEqual(Annotated[int, 4, 5], Annotated[str, 4, 5]) 4490 self.assertNotEqual(Annotated[int, 4], Annotated[int, 4, 4]) 4491 self.assertEqual( 4492 {Annotated[int, 4, 5], Annotated[int, 4, 5], Annotated[T, 4, 5]}, 4493 {Annotated[int, 4, 5], Annotated[T, 4, 5]} 4494 ) 4495 4496 def test_cannot_subclass(self): 4497 with self.assertRaisesRegex(TypeError, "Cannot subclass .*Annotated"): 4498 class C(Annotated): 4499 pass 4500 4501 def test_cannot_check_instance(self): 4502 with self.assertRaises(TypeError): 4503 isinstance(5, Annotated[int, "positive"]) 4504 4505 def test_cannot_check_subclass(self): 4506 with self.assertRaises(TypeError): 4507 issubclass(int, Annotated[int, "positive"]) 4508 4509 def test_pickle(self): 4510 samples = [typing.Any, typing.Union[int, str], 4511 typing.Optional[str], Tuple[int, ...], 4512 typing.Callable[[str], bytes]] 4513 4514 for t in samples: 4515 x = Annotated[t, "a"] 4516 4517 for prot in range(pickle.HIGHEST_PROTOCOL + 1): 4518 with self.subTest(protocol=prot, type=t): 4519 pickled = pickle.dumps(x, prot) 4520 restored = pickle.loads(pickled) 4521 self.assertEqual(x, restored) 4522 4523 global _Annotated_test_G 4524 4525 class _Annotated_test_G(Generic[T]): 4526 x = 1 4527 4528 G = Annotated[_Annotated_test_G[int], "A decoration"] 4529 G.foo = 42 4530 G.bar = 'abc' 4531 4532 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 4533 z = pickle.dumps(G, proto) 4534 x = pickle.loads(z) 4535 self.assertEqual(x.foo, 42) 4536 self.assertEqual(x.bar, 'abc') 4537 self.assertEqual(x.x, 1) 4538 4539 def test_subst(self): 4540 dec = "a decoration" 4541 dec2 = "another decoration" 4542 4543 S = Annotated[T, dec2] 4544 self.assertEqual(S[int], Annotated[int, dec2]) 4545 4546 self.assertEqual(S[Annotated[int, dec]], Annotated[int, dec, dec2]) 4547 L = Annotated[List[T], dec] 4548 4549 self.assertEqual(L[int], Annotated[List[int], dec]) 4550 with self.assertRaises(TypeError): 4551 L[int, int] 4552 4553 self.assertEqual(S[L[int]], Annotated[List[int], dec, dec2]) 4554 4555 D = Annotated[typing.Dict[KT, VT], dec] 4556 self.assertEqual(D[str, int], Annotated[typing.Dict[str, int], dec]) 4557 with self.assertRaises(TypeError): 4558 D[int] 4559 4560 It = Annotated[int, dec] 4561 with self.assertRaises(TypeError): 4562 It[None] 4563 4564 LI = L[int] 4565 with self.assertRaises(TypeError): 4566 LI[None] 4567 4568 def test_annotated_in_other_types(self): 4569 X = List[Annotated[T, 5]] 4570 self.assertEqual(X[int], List[Annotated[int, 5]]) 4571 4572 def test_annotated_mro(self): 4573 class X(Annotated[int, (1, 10)]): ... 4574 self.assertEqual(X.__mro__, (X, int, object), 4575 "Annotated should be transparent.") 4576 4577 4578class TypeAliasTests(BaseTestCase): 4579 def test_canonical_usage_with_variable_annotation(self): 4580 Alias: TypeAlias = Employee 4581 4582 def test_canonical_usage_with_type_comment(self): 4583 Alias = Employee # type: TypeAlias 4584 4585 def test_cannot_instantiate(self): 4586 with self.assertRaises(TypeError): 4587 TypeAlias() 4588 4589 def test_no_isinstance(self): 4590 with self.assertRaises(TypeError): 4591 isinstance(42, TypeAlias) 4592 4593 def test_no_issubclass(self): 4594 with self.assertRaises(TypeError): 4595 issubclass(Employee, TypeAlias) 4596 4597 with self.assertRaises(TypeError): 4598 issubclass(TypeAlias, Employee) 4599 4600 def test_cannot_subclass(self): 4601 with self.assertRaises(TypeError): 4602 class C(TypeAlias): 4603 pass 4604 4605 with self.assertRaises(TypeError): 4606 class C(type(TypeAlias)): 4607 pass 4608 4609 def test_repr(self): 4610 self.assertEqual(repr(TypeAlias), 'typing.TypeAlias') 4611 4612 def test_cannot_subscript(self): 4613 with self.assertRaises(TypeError): 4614 TypeAlias[int] 4615 4616 4617class ParamSpecTests(BaseTestCase): 4618 4619 def test_basic_plain(self): 4620 P = ParamSpec('P') 4621 self.assertEqual(P, P) 4622 self.assertIsInstance(P, ParamSpec) 4623 4624 def test_valid_uses(self): 4625 P = ParamSpec('P') 4626 T = TypeVar('T') 4627 C1 = Callable[P, int] 4628 self.assertEqual(C1.__args__, (P, int)) 4629 self.assertEqual(C1.__parameters__, (P,)) 4630 C2 = Callable[P, T] 4631 self.assertEqual(C2.__args__, (P, T)) 4632 self.assertEqual(C2.__parameters__, (P, T)) 4633 # Test collections.abc.Callable too. 4634 C3 = collections.abc.Callable[P, int] 4635 self.assertEqual(C3.__args__, (P, int)) 4636 self.assertEqual(C3.__parameters__, (P,)) 4637 C4 = collections.abc.Callable[P, T] 4638 self.assertEqual(C4.__args__, (P, T)) 4639 self.assertEqual(C4.__parameters__, (P, T)) 4640 4641 def test_args_kwargs(self): 4642 P = ParamSpec('P') 4643 self.assertIn('args', dir(P)) 4644 self.assertIn('kwargs', dir(P)) 4645 self.assertIsInstance(P.args, ParamSpecArgs) 4646 self.assertIsInstance(P.kwargs, ParamSpecKwargs) 4647 self.assertIs(P.args.__origin__, P) 4648 self.assertIs(P.kwargs.__origin__, P) 4649 self.assertEqual(repr(P.args), "P.args") 4650 self.assertEqual(repr(P.kwargs), "P.kwargs") 4651 4652 def test_user_generics(self): 4653 T = TypeVar("T") 4654 P = ParamSpec("P") 4655 P_2 = ParamSpec("P_2") 4656 4657 class X(Generic[T, P]): 4658 f: Callable[P, int] 4659 x: T 4660 G1 = X[int, P_2] 4661 self.assertEqual(G1.__args__, (int, P_2)) 4662 self.assertEqual(G1.__parameters__, (P_2,)) 4663 with self.assertRaisesRegex(TypeError, "few arguments for"): 4664 X[int] 4665 with self.assertRaisesRegex(TypeError, "many arguments for"): 4666 X[int, P_2, str] 4667 4668 G2 = X[int, Concatenate[int, P_2]] 4669 self.assertEqual(G2.__args__, (int, Concatenate[int, P_2])) 4670 self.assertEqual(G2.__parameters__, (P_2,)) 4671 4672 G3 = X[int, [int, bool]] 4673 self.assertEqual(G3.__args__, (int, (int, bool))) 4674 self.assertEqual(G3.__parameters__, ()) 4675 4676 G4 = X[int, ...] 4677 self.assertEqual(G4.__args__, (int, Ellipsis)) 4678 self.assertEqual(G4.__parameters__, ()) 4679 4680 class Z(Generic[P]): 4681 f: Callable[P, int] 4682 4683 G5 = Z[[int, str, bool]] 4684 self.assertEqual(G5.__args__, ((int, str, bool),)) 4685 self.assertEqual(G5.__parameters__, ()) 4686 4687 G6 = Z[int, str, bool] 4688 self.assertEqual(G6.__args__, ((int, str, bool),)) 4689 self.assertEqual(G6.__parameters__, ()) 4690 4691 # G5 and G6 should be equivalent according to the PEP 4692 self.assertEqual(G5.__args__, G6.__args__) 4693 self.assertEqual(G5.__origin__, G6.__origin__) 4694 self.assertEqual(G5.__parameters__, G6.__parameters__) 4695 self.assertEqual(G5, G6) 4696 4697 G7 = Z[int] 4698 self.assertEqual(G7.__args__, ((int,),)) 4699 self.assertEqual(G7.__parameters__, ()) 4700 4701 with self.assertRaisesRegex(TypeError, "many arguments for"): 4702 Z[[int, str], bool] 4703 with self.assertRaisesRegex(TypeError, "many arguments for"): 4704 Z[P_2, bool] 4705 4706 def test_multiple_paramspecs_in_user_generics(self): 4707 P = ParamSpec("P") 4708 P2 = ParamSpec("P2") 4709 4710 class X(Generic[P, P2]): 4711 f: Callable[P, int] 4712 g: Callable[P2, str] 4713 4714 G1 = X[[int, str], [bytes]] 4715 G2 = X[[int], [str, bytes]] 4716 self.assertNotEqual(G1, G2) 4717 self.assertEqual(G1.__args__, ((int, str), (bytes,))) 4718 self.assertEqual(G2.__args__, ((int,), (str, bytes))) 4719 4720 def test_no_paramspec_in__parameters__(self): 4721 # ParamSpec should not be found in __parameters__ 4722 # of generics. Usages outside Callable, Concatenate 4723 # and Generic are invalid. 4724 T = TypeVar("T") 4725 P = ParamSpec("P") 4726 self.assertNotIn(P, List[P].__parameters__) 4727 self.assertIn(T, Tuple[T, P].__parameters__) 4728 4729 # Test for consistency with builtin generics. 4730 self.assertNotIn(P, list[P].__parameters__) 4731 self.assertIn(T, tuple[T, P].__parameters__) 4732 4733 self.assertNotIn(P, (list[P] | int).__parameters__) 4734 self.assertIn(T, (tuple[T, P] | int).__parameters__) 4735 4736 def test_paramspec_in_nested_generics(self): 4737 # Although ParamSpec should not be found in __parameters__ of most 4738 # generics, they probably should be found when nested in 4739 # a valid location. 4740 T = TypeVar("T") 4741 P = ParamSpec("P") 4742 C1 = Callable[P, T] 4743 G1 = List[C1] 4744 G2 = list[C1] 4745 G3 = list[C1] | int 4746 self.assertEqual(G1.__parameters__, (P, T)) 4747 self.assertEqual(G2.__parameters__, (P, T)) 4748 self.assertEqual(G3.__parameters__, (P, T)) 4749 4750 4751class ConcatenateTests(BaseTestCase): 4752 def test_basics(self): 4753 P = ParamSpec('P') 4754 class MyClass: ... 4755 c = Concatenate[MyClass, P] 4756 self.assertNotEqual(c, Concatenate) 4757 4758 def test_valid_uses(self): 4759 P = ParamSpec('P') 4760 T = TypeVar('T') 4761 C1 = Callable[Concatenate[int, P], int] 4762 self.assertEqual(C1.__args__, (Concatenate[int, P], int)) 4763 self.assertEqual(C1.__parameters__, (P,)) 4764 C2 = Callable[Concatenate[int, T, P], T] 4765 self.assertEqual(C2.__args__, (Concatenate[int, T, P], T)) 4766 self.assertEqual(C2.__parameters__, (T, P)) 4767 4768 # Test collections.abc.Callable too. 4769 C3 = collections.abc.Callable[Concatenate[int, P], int] 4770 self.assertEqual(C3.__args__, (Concatenate[int, P], int)) 4771 self.assertEqual(C3.__parameters__, (P,)) 4772 C4 = collections.abc.Callable[Concatenate[int, T, P], T] 4773 self.assertEqual(C4.__args__, (Concatenate[int, T, P], T)) 4774 self.assertEqual(C4.__parameters__, (T, P)) 4775 4776 4777class TypeGuardTests(BaseTestCase): 4778 def test_basics(self): 4779 TypeGuard[int] # OK 4780 4781 def foo(arg) -> TypeGuard[int]: ... 4782 self.assertEqual(gth(foo), {'return': TypeGuard[int]}) 4783 4784 def test_repr(self): 4785 self.assertEqual(repr(TypeGuard), 'typing.TypeGuard') 4786 cv = TypeGuard[int] 4787 self.assertEqual(repr(cv), 'typing.TypeGuard[int]') 4788 cv = TypeGuard[Employee] 4789 self.assertEqual(repr(cv), 'typing.TypeGuard[%s.Employee]' % __name__) 4790 cv = TypeGuard[tuple[int]] 4791 self.assertEqual(repr(cv), 'typing.TypeGuard[tuple[int]]') 4792 4793 def test_cannot_subclass(self): 4794 with self.assertRaises(TypeError): 4795 class C(type(TypeGuard)): 4796 pass 4797 with self.assertRaises(TypeError): 4798 class C(type(TypeGuard[int])): 4799 pass 4800 4801 def test_cannot_init(self): 4802 with self.assertRaises(TypeError): 4803 TypeGuard() 4804 with self.assertRaises(TypeError): 4805 type(TypeGuard)() 4806 with self.assertRaises(TypeError): 4807 type(TypeGuard[Optional[int]])() 4808 4809 def test_no_isinstance(self): 4810 with self.assertRaises(TypeError): 4811 isinstance(1, TypeGuard[int]) 4812 with self.assertRaises(TypeError): 4813 issubclass(int, TypeGuard) 4814 4815 4816SpecialAttrsP = typing.ParamSpec('SpecialAttrsP') 4817SpecialAttrsT = typing.TypeVar('SpecialAttrsT', int, float, complex) 4818 4819 4820class SpecialAttrsTests(BaseTestCase): 4821 4822 def test_special_attrs(self): 4823 cls_to_check = { 4824 # ABC classes 4825 typing.AbstractSet: 'AbstractSet', 4826 typing.AsyncContextManager: 'AsyncContextManager', 4827 typing.AsyncGenerator: 'AsyncGenerator', 4828 typing.AsyncIterable: 'AsyncIterable', 4829 typing.AsyncIterator: 'AsyncIterator', 4830 typing.Awaitable: 'Awaitable', 4831 typing.ByteString: 'ByteString', 4832 typing.Callable: 'Callable', 4833 typing.ChainMap: 'ChainMap', 4834 typing.Collection: 'Collection', 4835 typing.Container: 'Container', 4836 typing.ContextManager: 'ContextManager', 4837 typing.Coroutine: 'Coroutine', 4838 typing.Counter: 'Counter', 4839 typing.DefaultDict: 'DefaultDict', 4840 typing.Deque: 'Deque', 4841 typing.Dict: 'Dict', 4842 typing.FrozenSet: 'FrozenSet', 4843 typing.Generator: 'Generator', 4844 typing.Hashable: 'Hashable', 4845 typing.ItemsView: 'ItemsView', 4846 typing.Iterable: 'Iterable', 4847 typing.Iterator: 'Iterator', 4848 typing.KeysView: 'KeysView', 4849 typing.List: 'List', 4850 typing.Mapping: 'Mapping', 4851 typing.MappingView: 'MappingView', 4852 typing.MutableMapping: 'MutableMapping', 4853 typing.MutableSequence: 'MutableSequence', 4854 typing.MutableSet: 'MutableSet', 4855 typing.OrderedDict: 'OrderedDict', 4856 typing.Reversible: 'Reversible', 4857 typing.Sequence: 'Sequence', 4858 typing.Set: 'Set', 4859 typing.Sized: 'Sized', 4860 typing.Tuple: 'Tuple', 4861 typing.Type: 'Type', 4862 typing.ValuesView: 'ValuesView', 4863 # Subscribed ABC classes 4864 typing.AbstractSet[Any]: 'AbstractSet', 4865 typing.AsyncContextManager[Any]: 'AsyncContextManager', 4866 typing.AsyncGenerator[Any, Any]: 'AsyncGenerator', 4867 typing.AsyncIterable[Any]: 'AsyncIterable', 4868 typing.AsyncIterator[Any]: 'AsyncIterator', 4869 typing.Awaitable[Any]: 'Awaitable', 4870 typing.Callable[[], Any]: 'Callable', 4871 typing.Callable[..., Any]: 'Callable', 4872 typing.ChainMap[Any, Any]: 'ChainMap', 4873 typing.Collection[Any]: 'Collection', 4874 typing.Container[Any]: 'Container', 4875 typing.ContextManager[Any]: 'ContextManager', 4876 typing.Coroutine[Any, Any, Any]: 'Coroutine', 4877 typing.Counter[Any]: 'Counter', 4878 typing.DefaultDict[Any, Any]: 'DefaultDict', 4879 typing.Deque[Any]: 'Deque', 4880 typing.Dict[Any, Any]: 'Dict', 4881 typing.FrozenSet[Any]: 'FrozenSet', 4882 typing.Generator[Any, Any, Any]: 'Generator', 4883 typing.ItemsView[Any, Any]: 'ItemsView', 4884 typing.Iterable[Any]: 'Iterable', 4885 typing.Iterator[Any]: 'Iterator', 4886 typing.KeysView[Any]: 'KeysView', 4887 typing.List[Any]: 'List', 4888 typing.Mapping[Any, Any]: 'Mapping', 4889 typing.MappingView[Any]: 'MappingView', 4890 typing.MutableMapping[Any, Any]: 'MutableMapping', 4891 typing.MutableSequence[Any]: 'MutableSequence', 4892 typing.MutableSet[Any]: 'MutableSet', 4893 typing.OrderedDict[Any, Any]: 'OrderedDict', 4894 typing.Reversible[Any]: 'Reversible', 4895 typing.Sequence[Any]: 'Sequence', 4896 typing.Set[Any]: 'Set', 4897 typing.Tuple[Any]: 'Tuple', 4898 typing.Tuple[Any, ...]: 'Tuple', 4899 typing.Type[Any]: 'Type', 4900 typing.ValuesView[Any]: 'ValuesView', 4901 # Special Forms 4902 typing.Annotated: 'Annotated', 4903 typing.Any: 'Any', 4904 typing.ClassVar: 'ClassVar', 4905 typing.Concatenate: 'Concatenate', 4906 typing.Final: 'Final', 4907 typing.ForwardRef: 'ForwardRef', 4908 typing.Literal: 'Literal', 4909 typing.NewType: 'NewType', 4910 typing.NoReturn: 'NoReturn', 4911 typing.Optional: 'Optional', 4912 typing.TypeAlias: 'TypeAlias', 4913 typing.TypeGuard: 'TypeGuard', 4914 typing.TypeVar: 'TypeVar', 4915 typing.Union: 'Union', 4916 # Subscribed special forms 4917 typing.Annotated[Any, "Annotation"]: 'Annotated', 4918 typing.ClassVar[Any]: 'ClassVar', 4919 typing.Concatenate[Any, SpecialAttrsP]: 'Concatenate', 4920 typing.Final[Any]: 'Final', 4921 typing.Literal[Any]: 'Literal', 4922 typing.Literal[1, 2]: 'Literal', 4923 typing.Literal[True, 2]: 'Literal', 4924 typing.Optional[Any]: 'Optional', 4925 typing.TypeGuard[Any]: 'TypeGuard', 4926 typing.Union[Any]: 'Any', 4927 typing.Union[int, float]: 'Union', 4928 # Incompatible special forms (tested in test_special_attrs2) 4929 # - typing.ForwardRef('set[Any]') 4930 # - typing.NewType('TypeName', Any) 4931 # - typing.ParamSpec('SpecialAttrsP') 4932 # - typing.TypeVar('T') 4933 } 4934 4935 for cls, name in cls_to_check.items(): 4936 with self.subTest(cls=cls): 4937 self.assertEqual(cls.__name__, name, str(cls)) 4938 self.assertEqual(cls.__qualname__, name, str(cls)) 4939 self.assertEqual(cls.__module__, 'typing', str(cls)) 4940 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 4941 s = pickle.dumps(cls, proto) 4942 loaded = pickle.loads(s) 4943 self.assertIs(cls, loaded) 4944 4945 TypeName = typing.NewType('SpecialAttrsTests.TypeName', Any) 4946 4947 def test_special_attrs2(self): 4948 # Forward refs provide a different introspection API. __name__ and 4949 # __qualname__ make little sense for forward refs as they can store 4950 # complex typing expressions. 4951 fr = typing.ForwardRef('set[Any]') 4952 self.assertFalse(hasattr(fr, '__name__')) 4953 self.assertFalse(hasattr(fr, '__qualname__')) 4954 self.assertEqual(fr.__module__, 'typing') 4955 # Forward refs are currently unpicklable. 4956 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 4957 with self.assertRaises(TypeError) as exc: 4958 pickle.dumps(fr, proto) 4959 4960 self.assertEqual(SpecialAttrsTests.TypeName.__name__, 'TypeName') 4961 self.assertEqual( 4962 SpecialAttrsTests.TypeName.__qualname__, 4963 'SpecialAttrsTests.TypeName', 4964 ) 4965 self.assertEqual( 4966 SpecialAttrsTests.TypeName.__module__, 4967 'test.test_typing', 4968 ) 4969 # NewTypes are picklable assuming correct qualname information. 4970 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 4971 s = pickle.dumps(SpecialAttrsTests.TypeName, proto) 4972 loaded = pickle.loads(s) 4973 self.assertIs(SpecialAttrsTests.TypeName, loaded) 4974 4975 # Type variables don't support non-global instantiation per PEP 484 4976 # restriction that "The argument to TypeVar() must be a string equal 4977 # to the variable name to which it is assigned". Thus, providing 4978 # __qualname__ is unnecessary. 4979 self.assertEqual(SpecialAttrsT.__name__, 'SpecialAttrsT') 4980 self.assertFalse(hasattr(SpecialAttrsT, '__qualname__')) 4981 self.assertEqual(SpecialAttrsT.__module__, 'test.test_typing') 4982 # Module-level type variables are picklable. 4983 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 4984 s = pickle.dumps(SpecialAttrsT, proto) 4985 loaded = pickle.loads(s) 4986 self.assertIs(SpecialAttrsT, loaded) 4987 4988 self.assertEqual(SpecialAttrsP.__name__, 'SpecialAttrsP') 4989 self.assertFalse(hasattr(SpecialAttrsP, '__qualname__')) 4990 self.assertEqual(SpecialAttrsP.__module__, 'test.test_typing') 4991 # Module-level ParamSpecs are picklable. 4992 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 4993 s = pickle.dumps(SpecialAttrsP, proto) 4994 loaded = pickle.loads(s) 4995 self.assertIs(SpecialAttrsP, loaded) 4996 4997class AllTests(BaseTestCase): 4998 """Tests for __all__.""" 4999 5000 def test_all(self): 5001 from typing import __all__ as a 5002 # Just spot-check the first and last of every category. 5003 self.assertIn('AbstractSet', a) 5004 self.assertIn('ValuesView', a) 5005 self.assertIn('cast', a) 5006 self.assertIn('overload', a) 5007 if hasattr(contextlib, 'AbstractContextManager'): 5008 self.assertIn('ContextManager', a) 5009 # Check that io and re are not exported. 5010 self.assertNotIn('io', a) 5011 self.assertNotIn('re', a) 5012 # Spot-check that stdlib modules aren't exported. 5013 self.assertNotIn('os', a) 5014 self.assertNotIn('sys', a) 5015 # Check that Text is defined. 5016 self.assertIn('Text', a) 5017 # Check previously missing classes. 5018 self.assertIn('SupportsBytes', a) 5019 self.assertIn('SupportsComplex', a) 5020 5021 def test_all_exported_names(self): 5022 import typing 5023 5024 actual_all = set(typing.__all__) 5025 computed_all = { 5026 k for k, v in vars(typing).items() 5027 # explicitly exported, not a thing with __module__ 5028 if k in actual_all or ( 5029 # avoid private names 5030 not k.startswith('_') and 5031 # avoid things in the io / re typing submodules 5032 k not in typing.io.__all__ and 5033 k not in typing.re.__all__ and 5034 k not in {'io', 're'} and 5035 # there's a few types and metaclasses that aren't exported 5036 not k.endswith(('Meta', '_contra', '_co')) and 5037 not k.upper() == k and 5038 # but export all things that have __module__ == 'typing' 5039 getattr(v, '__module__', None) == typing.__name__ 5040 ) 5041 } 5042 self.assertSetEqual(computed_all, actual_all) 5043 5044 5045 5046if __name__ == '__main__': 5047 main() 5048