1import contextlib 2import collections 3import collections.abc 4from collections import defaultdict 5from functools import lru_cache, wraps, reduce 6import gc 7import inspect 8import itertools 9import operator 10import pickle 11import re 12import sys 13from unittest import TestCase, main, skip 14from unittest.mock import patch 15from copy import copy, deepcopy 16 17from typing import Any, NoReturn, Never, assert_never 18from typing import overload, get_overloads, clear_overloads 19from typing import TypeVar, TypeVarTuple, Unpack, AnyStr 20from typing import T, KT, VT # Not in __all__. 21from typing import Union, Optional, Literal 22from typing import Tuple, List, Dict, MutableMapping 23from typing import Callable 24from typing import Generic, ClassVar, Final, final, Protocol 25from typing import assert_type, cast, runtime_checkable 26from typing import get_type_hints 27from typing import get_origin, get_args, get_protocol_members 28from typing import override 29from typing import is_typeddict, is_protocol 30from typing import reveal_type 31from typing import dataclass_transform 32from typing import no_type_check, no_type_check_decorator 33from typing import Type 34from typing import NamedTuple, NotRequired, Required, ReadOnly, TypedDict 35from typing import IO, TextIO, BinaryIO 36from typing import Pattern, Match 37from typing import Annotated, ForwardRef 38from typing import Self, LiteralString 39from typing import TypeAlias 40from typing import ParamSpec, Concatenate, ParamSpecArgs, ParamSpecKwargs 41from typing import TypeGuard, TypeIs, NoDefault 42import abc 43import textwrap 44import typing 45import weakref 46import types 47 48from test.support import captured_stderr, cpython_only, infinite_recursion, requires_docstrings, import_helper 49from test.typinganndata import ann_module695, mod_generics_cache, _typed_dict_helper 50 51 52CANNOT_SUBCLASS_TYPE = 'Cannot subclass special typing classes' 53NOT_A_BASE_TYPE = "type 'typing.%s' is not an acceptable base type" 54CANNOT_SUBCLASS_INSTANCE = 'Cannot subclass an instance of %s' 55 56 57class BaseTestCase(TestCase): 58 59 def assertIsSubclass(self, cls, class_or_tuple, msg=None): 60 if not issubclass(cls, class_or_tuple): 61 message = '%r is not a subclass of %r' % (cls, class_or_tuple) 62 if msg is not None: 63 message += ' : %s' % msg 64 raise self.failureException(message) 65 66 def assertNotIsSubclass(self, cls, class_or_tuple, msg=None): 67 if issubclass(cls, class_or_tuple): 68 message = '%r is a subclass of %r' % (cls, class_or_tuple) 69 if msg is not None: 70 message += ' : %s' % msg 71 raise self.failureException(message) 72 73 def clear_caches(self): 74 for f in typing._cleanups: 75 f() 76 77 78def all_pickle_protocols(test_func): 79 """Runs `test_func` with various values for `proto` argument.""" 80 81 @wraps(test_func) 82 def wrapper(self): 83 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 84 with self.subTest(pickle_proto=proto): 85 test_func(self, proto=proto) 86 87 return wrapper 88 89 90class Employee: 91 pass 92 93 94class Manager(Employee): 95 pass 96 97 98class Founder(Employee): 99 pass 100 101 102class ManagingFounder(Manager, Founder): 103 pass 104 105 106class AnyTests(BaseTestCase): 107 108 def test_any_instance_type_error(self): 109 with self.assertRaises(TypeError): 110 isinstance(42, Any) 111 112 def test_repr(self): 113 self.assertEqual(repr(Any), 'typing.Any') 114 115 class Sub(Any): pass 116 self.assertEqual( 117 repr(Sub), 118 f"<class '{__name__}.AnyTests.test_repr.<locals>.Sub'>", 119 ) 120 121 def test_errors(self): 122 with self.assertRaises(TypeError): 123 issubclass(42, Any) 124 with self.assertRaises(TypeError): 125 Any[int] # Any is not a generic type. 126 127 def test_can_subclass(self): 128 class Mock(Any): pass 129 self.assertTrue(issubclass(Mock, Any)) 130 self.assertIsInstance(Mock(), Mock) 131 132 class Something: pass 133 self.assertFalse(issubclass(Something, Any)) 134 self.assertNotIsInstance(Something(), Mock) 135 136 class MockSomething(Something, Mock): pass 137 self.assertTrue(issubclass(MockSomething, Any)) 138 ms = MockSomething() 139 self.assertIsInstance(ms, MockSomething) 140 self.assertIsInstance(ms, Something) 141 self.assertIsInstance(ms, Mock) 142 143 def test_subclassing_with_custom_constructor(self): 144 class Sub(Any): 145 def __init__(self, *args, **kwargs): pass 146 # The instantiation must not fail. 147 Sub(0, s="") 148 149 def test_multiple_inheritance_with_custom_constructors(self): 150 class Foo: 151 def __init__(self, x): 152 self.x = x 153 154 class Bar(Any, Foo): 155 def __init__(self, x, y): 156 self.y = y 157 super().__init__(x) 158 159 b = Bar(1, 2) 160 self.assertEqual(b.x, 1) 161 self.assertEqual(b.y, 2) 162 163 def test_cannot_instantiate(self): 164 with self.assertRaises(TypeError): 165 Any() 166 with self.assertRaises(TypeError): 167 type(Any)() 168 169 def test_any_works_with_alias(self): 170 # These expressions must simply not fail. 171 typing.Match[Any] 172 typing.Pattern[Any] 173 typing.IO[Any] 174 175 176class BottomTypeTestsMixin: 177 bottom_type: ClassVar[Any] 178 179 def test_equality(self): 180 self.assertEqual(self.bottom_type, self.bottom_type) 181 self.assertIs(self.bottom_type, self.bottom_type) 182 self.assertNotEqual(self.bottom_type, None) 183 184 def test_get_origin(self): 185 self.assertIs(get_origin(self.bottom_type), None) 186 187 def test_instance_type_error(self): 188 with self.assertRaises(TypeError): 189 isinstance(42, self.bottom_type) 190 191 def test_subclass_type_error(self): 192 with self.assertRaises(TypeError): 193 issubclass(Employee, self.bottom_type) 194 with self.assertRaises(TypeError): 195 issubclass(NoReturn, self.bottom_type) 196 197 def test_not_generic(self): 198 with self.assertRaises(TypeError): 199 self.bottom_type[int] 200 201 def test_cannot_subclass(self): 202 with self.assertRaisesRegex(TypeError, 203 'Cannot subclass ' + re.escape(str(self.bottom_type))): 204 class A(self.bottom_type): 205 pass 206 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 207 class B(type(self.bottom_type)): 208 pass 209 210 def test_cannot_instantiate(self): 211 with self.assertRaises(TypeError): 212 self.bottom_type() 213 with self.assertRaises(TypeError): 214 type(self.bottom_type)() 215 216 217class NoReturnTests(BottomTypeTestsMixin, BaseTestCase): 218 bottom_type = NoReturn 219 220 def test_repr(self): 221 self.assertEqual(repr(NoReturn), 'typing.NoReturn') 222 223 def test_get_type_hints(self): 224 def some(arg: NoReturn) -> NoReturn: ... 225 def some_str(arg: 'NoReturn') -> 'typing.NoReturn': ... 226 227 expected = {'arg': NoReturn, 'return': NoReturn} 228 for target in [some, some_str]: 229 with self.subTest(target=target): 230 self.assertEqual(gth(target), expected) 231 232 def test_not_equality(self): 233 self.assertNotEqual(NoReturn, Never) 234 self.assertNotEqual(Never, NoReturn) 235 236 237class NeverTests(BottomTypeTestsMixin, BaseTestCase): 238 bottom_type = Never 239 240 def test_repr(self): 241 self.assertEqual(repr(Never), 'typing.Never') 242 243 def test_get_type_hints(self): 244 def some(arg: Never) -> Never: ... 245 def some_str(arg: 'Never') -> 'typing.Never': ... 246 247 expected = {'arg': Never, 'return': Never} 248 for target in [some, some_str]: 249 with self.subTest(target=target): 250 self.assertEqual(gth(target), expected) 251 252 253class AssertNeverTests(BaseTestCase): 254 def test_exception(self): 255 with self.assertRaises(AssertionError): 256 assert_never(None) 257 258 value = "some value" 259 with self.assertRaisesRegex(AssertionError, value): 260 assert_never(value) 261 262 # Make sure a huge value doesn't get printed in its entirety 263 huge_value = "a" * 10000 264 with self.assertRaises(AssertionError) as cm: 265 assert_never(huge_value) 266 self.assertLess( 267 len(cm.exception.args[0]), 268 typing._ASSERT_NEVER_REPR_MAX_LENGTH * 2, 269 ) 270 271 272class SelfTests(BaseTestCase): 273 def test_equality(self): 274 self.assertEqual(Self, Self) 275 self.assertIs(Self, Self) 276 self.assertNotEqual(Self, None) 277 278 def test_basics(self): 279 class Foo: 280 def bar(self) -> Self: ... 281 class FooStr: 282 def bar(self) -> 'Self': ... 283 class FooStrTyping: 284 def bar(self) -> 'typing.Self': ... 285 286 for target in [Foo, FooStr, FooStrTyping]: 287 with self.subTest(target=target): 288 self.assertEqual(gth(target.bar), {'return': Self}) 289 self.assertIs(get_origin(Self), None) 290 291 def test_repr(self): 292 self.assertEqual(repr(Self), 'typing.Self') 293 294 def test_cannot_subscript(self): 295 with self.assertRaises(TypeError): 296 Self[int] 297 298 def test_cannot_subclass(self): 299 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 300 class C(type(Self)): 301 pass 302 with self.assertRaisesRegex(TypeError, 303 r'Cannot subclass typing\.Self'): 304 class D(Self): 305 pass 306 307 def test_cannot_init(self): 308 with self.assertRaises(TypeError): 309 Self() 310 with self.assertRaises(TypeError): 311 type(Self)() 312 313 def test_no_isinstance(self): 314 with self.assertRaises(TypeError): 315 isinstance(1, Self) 316 with self.assertRaises(TypeError): 317 issubclass(int, Self) 318 319 def test_alias(self): 320 # TypeAliases are not actually part of the spec 321 alias_1 = Tuple[Self, Self] 322 alias_2 = List[Self] 323 alias_3 = ClassVar[Self] 324 self.assertEqual(get_args(alias_1), (Self, Self)) 325 self.assertEqual(get_args(alias_2), (Self,)) 326 self.assertEqual(get_args(alias_3), (Self,)) 327 328 329class LiteralStringTests(BaseTestCase): 330 def test_equality(self): 331 self.assertEqual(LiteralString, LiteralString) 332 self.assertIs(LiteralString, LiteralString) 333 self.assertNotEqual(LiteralString, None) 334 335 def test_basics(self): 336 class Foo: 337 def bar(self) -> LiteralString: ... 338 class FooStr: 339 def bar(self) -> 'LiteralString': ... 340 class FooStrTyping: 341 def bar(self) -> 'typing.LiteralString': ... 342 343 for target in [Foo, FooStr, FooStrTyping]: 344 with self.subTest(target=target): 345 self.assertEqual(gth(target.bar), {'return': LiteralString}) 346 self.assertIs(get_origin(LiteralString), None) 347 348 def test_repr(self): 349 self.assertEqual(repr(LiteralString), 'typing.LiteralString') 350 351 def test_cannot_subscript(self): 352 with self.assertRaises(TypeError): 353 LiteralString[int] 354 355 def test_cannot_subclass(self): 356 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 357 class C(type(LiteralString)): 358 pass 359 with self.assertRaisesRegex(TypeError, 360 r'Cannot subclass typing\.LiteralString'): 361 class D(LiteralString): 362 pass 363 364 def test_cannot_init(self): 365 with self.assertRaises(TypeError): 366 LiteralString() 367 with self.assertRaises(TypeError): 368 type(LiteralString)() 369 370 def test_no_isinstance(self): 371 with self.assertRaises(TypeError): 372 isinstance(1, LiteralString) 373 with self.assertRaises(TypeError): 374 issubclass(int, LiteralString) 375 376 def test_alias(self): 377 alias_1 = Tuple[LiteralString, LiteralString] 378 alias_2 = List[LiteralString] 379 alias_3 = ClassVar[LiteralString] 380 self.assertEqual(get_args(alias_1), (LiteralString, LiteralString)) 381 self.assertEqual(get_args(alias_2), (LiteralString,)) 382 self.assertEqual(get_args(alias_3), (LiteralString,)) 383 384class TypeVarTests(BaseTestCase): 385 def test_basic_plain(self): 386 T = TypeVar('T') 387 # T equals itself. 388 self.assertEqual(T, T) 389 # T is an instance of TypeVar 390 self.assertIsInstance(T, TypeVar) 391 self.assertEqual(T.__name__, 'T') 392 self.assertEqual(T.__constraints__, ()) 393 self.assertIs(T.__bound__, None) 394 self.assertIs(T.__covariant__, False) 395 self.assertIs(T.__contravariant__, False) 396 self.assertIs(T.__infer_variance__, False) 397 self.assertEqual(T.__module__, __name__) 398 399 def test_basic_with_exec(self): 400 ns = {} 401 exec('from typing import TypeVar; T = TypeVar("T", bound=float)', ns, ns) 402 T = ns['T'] 403 self.assertIsInstance(T, TypeVar) 404 self.assertEqual(T.__name__, 'T') 405 self.assertEqual(T.__constraints__, ()) 406 self.assertIs(T.__bound__, float) 407 self.assertIs(T.__covariant__, False) 408 self.assertIs(T.__contravariant__, False) 409 self.assertIs(T.__infer_variance__, False) 410 self.assertIs(T.__module__, None) 411 412 def test_attributes(self): 413 T_bound = TypeVar('T_bound', bound=int) 414 self.assertEqual(T_bound.__name__, 'T_bound') 415 self.assertEqual(T_bound.__constraints__, ()) 416 self.assertIs(T_bound.__bound__, int) 417 418 T_constraints = TypeVar('T_constraints', int, str) 419 self.assertEqual(T_constraints.__name__, 'T_constraints') 420 self.assertEqual(T_constraints.__constraints__, (int, str)) 421 self.assertIs(T_constraints.__bound__, None) 422 423 T_co = TypeVar('T_co', covariant=True) 424 self.assertEqual(T_co.__name__, 'T_co') 425 self.assertIs(T_co.__covariant__, True) 426 self.assertIs(T_co.__contravariant__, False) 427 self.assertIs(T_co.__infer_variance__, False) 428 429 T_contra = TypeVar('T_contra', contravariant=True) 430 self.assertEqual(T_contra.__name__, 'T_contra') 431 self.assertIs(T_contra.__covariant__, False) 432 self.assertIs(T_contra.__contravariant__, True) 433 self.assertIs(T_contra.__infer_variance__, False) 434 435 T_infer = TypeVar('T_infer', infer_variance=True) 436 self.assertEqual(T_infer.__name__, 'T_infer') 437 self.assertIs(T_infer.__covariant__, False) 438 self.assertIs(T_infer.__contravariant__, False) 439 self.assertIs(T_infer.__infer_variance__, True) 440 441 def test_typevar_instance_type_error(self): 442 T = TypeVar('T') 443 with self.assertRaises(TypeError): 444 isinstance(42, T) 445 446 def test_typevar_subclass_type_error(self): 447 T = TypeVar('T') 448 with self.assertRaises(TypeError): 449 issubclass(int, T) 450 with self.assertRaises(TypeError): 451 issubclass(T, int) 452 453 def test_constrained_error(self): 454 with self.assertRaises(TypeError): 455 X = TypeVar('X', int) 456 X 457 458 def test_union_unique(self): 459 X = TypeVar('X') 460 Y = TypeVar('Y') 461 self.assertNotEqual(X, Y) 462 self.assertEqual(Union[X], X) 463 self.assertNotEqual(Union[X], Union[X, Y]) 464 self.assertEqual(Union[X, X], X) 465 self.assertNotEqual(Union[X, int], Union[X]) 466 self.assertNotEqual(Union[X, int], Union[int]) 467 self.assertEqual(Union[X, int].__args__, (X, int)) 468 self.assertEqual(Union[X, int].__parameters__, (X,)) 469 self.assertIs(Union[X, int].__origin__, Union) 470 471 def test_or(self): 472 X = TypeVar('X') 473 # use a string because str doesn't implement 474 # __or__/__ror__ itself 475 self.assertEqual(X | "x", Union[X, "x"]) 476 self.assertEqual("x" | X, Union["x", X]) 477 # make sure the order is correct 478 self.assertEqual(get_args(X | "x"), (X, ForwardRef("x"))) 479 self.assertEqual(get_args("x" | X), (ForwardRef("x"), X)) 480 481 def test_union_constrained(self): 482 A = TypeVar('A', str, bytes) 483 self.assertNotEqual(Union[A, str], Union[A]) 484 485 def test_repr(self): 486 self.assertEqual(repr(T), '~T') 487 self.assertEqual(repr(KT), '~KT') 488 self.assertEqual(repr(VT), '~VT') 489 self.assertEqual(repr(AnyStr), '~AnyStr') 490 T_co = TypeVar('T_co', covariant=True) 491 self.assertEqual(repr(T_co), '+T_co') 492 T_contra = TypeVar('T_contra', contravariant=True) 493 self.assertEqual(repr(T_contra), '-T_contra') 494 495 def test_no_redefinition(self): 496 self.assertNotEqual(TypeVar('T'), TypeVar('T')) 497 self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str)) 498 499 def test_cannot_subclass(self): 500 with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'TypeVar'): 501 class V(TypeVar): pass 502 T = TypeVar("T") 503 with self.assertRaisesRegex(TypeError, 504 CANNOT_SUBCLASS_INSTANCE % 'TypeVar'): 505 class W(T): pass 506 507 def test_cannot_instantiate_vars(self): 508 with self.assertRaises(TypeError): 509 TypeVar('A')() 510 511 def test_bound_errors(self): 512 with self.assertRaises(TypeError): 513 TypeVar('X', bound=Union) 514 with self.assertRaises(TypeError): 515 TypeVar('X', str, float, bound=Employee) 516 with self.assertRaisesRegex(TypeError, 517 r"Bound must be a type\. Got \(1, 2\)\."): 518 TypeVar('X', bound=(1, 2)) 519 520 def test_missing__name__(self): 521 # See bpo-39942 522 code = ("import typing\n" 523 "T = typing.TypeVar('T')\n" 524 ) 525 exec(code, {}) 526 527 def test_no_bivariant(self): 528 with self.assertRaises(ValueError): 529 TypeVar('T', covariant=True, contravariant=True) 530 531 def test_cannot_combine_explicit_and_infer(self): 532 with self.assertRaises(ValueError): 533 TypeVar('T', covariant=True, infer_variance=True) 534 with self.assertRaises(ValueError): 535 TypeVar('T', contravariant=True, infer_variance=True) 536 537 def test_var_substitution(self): 538 T = TypeVar('T') 539 subst = T.__typing_subst__ 540 self.assertIs(subst(int), int) 541 self.assertEqual(subst(list[int]), list[int]) 542 self.assertEqual(subst(List[int]), List[int]) 543 self.assertEqual(subst(List), List) 544 self.assertIs(subst(Any), Any) 545 self.assertIs(subst(None), type(None)) 546 self.assertIs(subst(T), T) 547 self.assertEqual(subst(int|str), int|str) 548 self.assertEqual(subst(Union[int, str]), Union[int, str]) 549 550 def test_bad_var_substitution(self): 551 T = TypeVar('T') 552 bad_args = ( 553 (), (int, str), Union, 554 Generic, Generic[T], Protocol, Protocol[T], 555 Final, Final[int], ClassVar, ClassVar[int], 556 ) 557 for arg in bad_args: 558 with self.subTest(arg=arg): 559 with self.assertRaises(TypeError): 560 T.__typing_subst__(arg) 561 with self.assertRaises(TypeError): 562 List[T][arg] 563 with self.assertRaises(TypeError): 564 list[T][arg] 565 566 def test_many_weakrefs(self): 567 # gh-108295: this used to segfault 568 for cls in (ParamSpec, TypeVarTuple, TypeVar): 569 with self.subTest(cls=cls): 570 vals = weakref.WeakValueDictionary() 571 572 for x in range(10): 573 vals[x] = cls(str(x)) 574 del vals 575 576 def test_constructor(self): 577 T = TypeVar(name="T") 578 self.assertEqual(T.__name__, "T") 579 self.assertEqual(T.__constraints__, ()) 580 self.assertIs(T.__bound__, None) 581 self.assertIs(T.__default__, typing.NoDefault) 582 self.assertIs(T.__covariant__, False) 583 self.assertIs(T.__contravariant__, False) 584 self.assertIs(T.__infer_variance__, False) 585 586 T = TypeVar(name="T", bound=type) 587 self.assertEqual(T.__name__, "T") 588 self.assertEqual(T.__constraints__, ()) 589 self.assertIs(T.__bound__, type) 590 self.assertIs(T.__default__, typing.NoDefault) 591 self.assertIs(T.__covariant__, False) 592 self.assertIs(T.__contravariant__, False) 593 self.assertIs(T.__infer_variance__, False) 594 595 T = TypeVar(name="T", default=()) 596 self.assertEqual(T.__name__, "T") 597 self.assertEqual(T.__constraints__, ()) 598 self.assertIs(T.__bound__, None) 599 self.assertIs(T.__default__, ()) 600 self.assertIs(T.__covariant__, False) 601 self.assertIs(T.__contravariant__, False) 602 self.assertIs(T.__infer_variance__, False) 603 604 T = TypeVar(name="T", covariant=True) 605 self.assertEqual(T.__name__, "T") 606 self.assertEqual(T.__constraints__, ()) 607 self.assertIs(T.__bound__, None) 608 self.assertIs(T.__default__, typing.NoDefault) 609 self.assertIs(T.__covariant__, True) 610 self.assertIs(T.__contravariant__, False) 611 self.assertIs(T.__infer_variance__, False) 612 613 T = TypeVar(name="T", contravariant=True) 614 self.assertEqual(T.__name__, "T") 615 self.assertEqual(T.__constraints__, ()) 616 self.assertIs(T.__bound__, None) 617 self.assertIs(T.__default__, typing.NoDefault) 618 self.assertIs(T.__covariant__, False) 619 self.assertIs(T.__contravariant__, True) 620 self.assertIs(T.__infer_variance__, False) 621 622 T = TypeVar(name="T", infer_variance=True) 623 self.assertEqual(T.__name__, "T") 624 self.assertEqual(T.__constraints__, ()) 625 self.assertIs(T.__bound__, None) 626 self.assertIs(T.__default__, typing.NoDefault) 627 self.assertIs(T.__covariant__, False) 628 self.assertIs(T.__contravariant__, False) 629 self.assertIs(T.__infer_variance__, True) 630 631 632class TypeParameterDefaultsTests(BaseTestCase): 633 def test_typevar(self): 634 T = TypeVar('T', default=int) 635 self.assertEqual(T.__default__, int) 636 self.assertTrue(T.has_default()) 637 self.assertIsInstance(T, TypeVar) 638 639 class A(Generic[T]): ... 640 Alias = Optional[T] 641 642 def test_typevar_none(self): 643 U = TypeVar('U') 644 U_None = TypeVar('U_None', default=None) 645 self.assertIs(U.__default__, NoDefault) 646 self.assertFalse(U.has_default()) 647 self.assertIs(U_None.__default__, None) 648 self.assertTrue(U_None.has_default()) 649 650 class X[T]: ... 651 T, = X.__type_params__ 652 self.assertIs(T.__default__, NoDefault) 653 self.assertFalse(T.has_default()) 654 655 def test_paramspec(self): 656 P = ParamSpec('P', default=(str, int)) 657 self.assertEqual(P.__default__, (str, int)) 658 self.assertTrue(P.has_default()) 659 self.assertIsInstance(P, ParamSpec) 660 661 class A(Generic[P]): ... 662 Alias = typing.Callable[P, None] 663 664 P_default = ParamSpec('P_default', default=...) 665 self.assertIs(P_default.__default__, ...) 666 667 def test_paramspec_none(self): 668 U = ParamSpec('U') 669 U_None = ParamSpec('U_None', default=None) 670 self.assertIs(U.__default__, NoDefault) 671 self.assertFalse(U.has_default()) 672 self.assertIs(U_None.__default__, None) 673 self.assertTrue(U_None.has_default()) 674 675 class X[**P]: ... 676 P, = X.__type_params__ 677 self.assertIs(P.__default__, NoDefault) 678 self.assertFalse(P.has_default()) 679 680 def test_typevartuple(self): 681 Ts = TypeVarTuple('Ts', default=Unpack[Tuple[str, int]]) 682 self.assertEqual(Ts.__default__, Unpack[Tuple[str, int]]) 683 self.assertTrue(Ts.has_default()) 684 self.assertIsInstance(Ts, TypeVarTuple) 685 686 class A(Generic[Unpack[Ts]]): ... 687 Alias = Optional[Unpack[Ts]] 688 689 def test_typevartuple_specialization(self): 690 T = TypeVar("T") 691 Ts = TypeVarTuple('Ts', default=Unpack[Tuple[str, int]]) 692 self.assertEqual(Ts.__default__, Unpack[Tuple[str, int]]) 693 class A(Generic[T, Unpack[Ts]]): ... 694 self.assertEqual(A[float].__args__, (float, str, int)) 695 self.assertEqual(A[float, range].__args__, (float, range)) 696 self.assertEqual(A[float, *tuple[int, ...]].__args__, (float, *tuple[int, ...])) 697 698 def test_typevar_and_typevartuple_specialization(self): 699 T = TypeVar("T") 700 U = TypeVar("U", default=float) 701 Ts = TypeVarTuple('Ts', default=Unpack[Tuple[str, int]]) 702 self.assertEqual(Ts.__default__, Unpack[Tuple[str, int]]) 703 class A(Generic[T, U, Unpack[Ts]]): ... 704 self.assertEqual(A[int].__args__, (int, float, str, int)) 705 self.assertEqual(A[int, str].__args__, (int, str, str, int)) 706 self.assertEqual(A[int, str, range].__args__, (int, str, range)) 707 self.assertEqual(A[int, str, *tuple[int, ...]].__args__, (int, str, *tuple[int, ...])) 708 709 def test_no_default_after_typevar_tuple(self): 710 T = TypeVar("T", default=int) 711 Ts = TypeVarTuple("Ts") 712 Ts_default = TypeVarTuple("Ts_default", default=Unpack[Tuple[str, int]]) 713 714 with self.assertRaises(TypeError): 715 class X(Generic[*Ts, T]): ... 716 717 with self.assertRaises(TypeError): 718 class Y(Generic[*Ts_default, T]): ... 719 720 def test_allow_default_after_non_default_in_alias(self): 721 T_default = TypeVar('T_default', default=int) 722 T = TypeVar('T') 723 Ts = TypeVarTuple('Ts') 724 725 a1 = Callable[[T_default], T] 726 self.assertEqual(a1.__args__, (T_default, T)) 727 728 a2 = dict[T_default, T] 729 self.assertEqual(a2.__args__, (T_default, T)) 730 731 a3 = typing.Dict[T_default, T] 732 self.assertEqual(a3.__args__, (T_default, T)) 733 734 a4 = Callable[*Ts, T] 735 self.assertEqual(a4.__args__, (*Ts, T)) 736 737 def test_paramspec_specialization(self): 738 T = TypeVar("T") 739 P = ParamSpec('P', default=[str, int]) 740 self.assertEqual(P.__default__, [str, int]) 741 class A(Generic[T, P]): ... 742 self.assertEqual(A[float].__args__, (float, (str, int))) 743 self.assertEqual(A[float, [range]].__args__, (float, (range,))) 744 745 def test_typevar_and_paramspec_specialization(self): 746 T = TypeVar("T") 747 U = TypeVar("U", default=float) 748 P = ParamSpec('P', default=[str, int]) 749 self.assertEqual(P.__default__, [str, int]) 750 class A(Generic[T, U, P]): ... 751 self.assertEqual(A[float].__args__, (float, float, (str, int))) 752 self.assertEqual(A[float, int].__args__, (float, int, (str, int))) 753 self.assertEqual(A[float, int, [range]].__args__, (float, int, (range,))) 754 755 def test_paramspec_and_typevar_specialization(self): 756 T = TypeVar("T") 757 P = ParamSpec('P', default=[str, int]) 758 U = TypeVar("U", default=float) 759 self.assertEqual(P.__default__, [str, int]) 760 class A(Generic[T, P, U]): ... 761 self.assertEqual(A[float].__args__, (float, (str, int), float)) 762 self.assertEqual(A[float, [range]].__args__, (float, (range,), float)) 763 self.assertEqual(A[float, [range], int].__args__, (float, (range,), int)) 764 765 def test_typevartuple_none(self): 766 U = TypeVarTuple('U') 767 U_None = TypeVarTuple('U_None', default=None) 768 self.assertIs(U.__default__, NoDefault) 769 self.assertFalse(U.has_default()) 770 self.assertIs(U_None.__default__, None) 771 self.assertTrue(U_None.has_default()) 772 773 class X[**Ts]: ... 774 Ts, = X.__type_params__ 775 self.assertIs(Ts.__default__, NoDefault) 776 self.assertFalse(Ts.has_default()) 777 778 def test_no_default_after_non_default(self): 779 DefaultStrT = TypeVar('DefaultStrT', default=str) 780 T = TypeVar('T') 781 782 with self.assertRaisesRegex( 783 TypeError, r"Type parameter ~T without a default follows type parameter with a default" 784 ): 785 Test = Generic[DefaultStrT, T] 786 787 def test_need_more_params(self): 788 DefaultStrT = TypeVar('DefaultStrT', default=str) 789 T = TypeVar('T') 790 U = TypeVar('U') 791 792 class A(Generic[T, U, DefaultStrT]): ... 793 A[int, bool] 794 A[int, bool, str] 795 796 with self.assertRaisesRegex( 797 TypeError, r"Too few arguments for .+; actual 1, expected at least 2" 798 ): 799 Test = A[int] 800 801 def test_pickle(self): 802 global U, U_co, U_contra, U_default # pickle wants to reference the class by name 803 U = TypeVar('U') 804 U_co = TypeVar('U_co', covariant=True) 805 U_contra = TypeVar('U_contra', contravariant=True) 806 U_default = TypeVar('U_default', default=int) 807 for proto in range(pickle.HIGHEST_PROTOCOL): 808 for typevar in (U, U_co, U_contra, U_default): 809 z = pickle.loads(pickle.dumps(typevar, proto)) 810 self.assertEqual(z.__name__, typevar.__name__) 811 self.assertEqual(z.__covariant__, typevar.__covariant__) 812 self.assertEqual(z.__contravariant__, typevar.__contravariant__) 813 self.assertEqual(z.__bound__, typevar.__bound__) 814 self.assertEqual(z.__default__, typevar.__default__) 815 816 817def template_replace(templates: list[str], replacements: dict[str, list[str]]) -> list[tuple[str]]: 818 """Renders templates with possible combinations of replacements. 819 820 Example 1: Suppose that: 821 templates = ["dog_breed are awesome", "dog_breed are cool"] 822 replacements = ["dog_breed": ["Huskies", "Beagles"]] 823 Then we would return: 824 [ 825 ("Huskies are awesome", "Huskies are cool"), 826 ("Beagles are awesome", "Beagles are cool") 827 ] 828 829 Example 2: Suppose that: 830 templates = ["Huskies are word1 but also word2"] 831 replacements = {"word1": ["playful", "cute"], 832 "word2": ["feisty", "tiring"]} 833 Then we would return: 834 [ 835 ("Huskies are playful but also feisty"), 836 ("Huskies are playful but also tiring"), 837 ("Huskies are cute but also feisty"), 838 ("Huskies are cute but also tiring") 839 ] 840 841 Note that if any of the replacements do not occur in any template: 842 templates = ["Huskies are word1", "Beagles!"] 843 replacements = {"word1": ["playful", "cute"], 844 "word2": ["feisty", "tiring"]} 845 Then we do not generate duplicates, returning: 846 [ 847 ("Huskies are playful", "Beagles!"), 848 ("Huskies are cute", "Beagles!") 849 ] 850 """ 851 # First, build a structure like: 852 # [ 853 # [("word1", "playful"), ("word1", "cute")], 854 # [("word2", "feisty"), ("word2", "tiring")] 855 # ] 856 replacement_combos = [] 857 for original, possible_replacements in replacements.items(): 858 original_replacement_tuples = [] 859 for replacement in possible_replacements: 860 original_replacement_tuples.append((original, replacement)) 861 replacement_combos.append(original_replacement_tuples) 862 863 # Second, generate rendered templates, including possible duplicates. 864 rendered_templates = [] 865 for replacement_combo in itertools.product(*replacement_combos): 866 # replacement_combo would be e.g. 867 # [("word1", "playful"), ("word2", "feisty")] 868 templates_with_replacements = [] 869 for template in templates: 870 for original, replacement in replacement_combo: 871 template = template.replace(original, replacement) 872 templates_with_replacements.append(template) 873 rendered_templates.append(tuple(templates_with_replacements)) 874 875 # Finally, remove the duplicates (but keep the order). 876 rendered_templates_no_duplicates = [] 877 for x in rendered_templates: 878 # Inefficient, but should be fine for our purposes. 879 if x not in rendered_templates_no_duplicates: 880 rendered_templates_no_duplicates.append(x) 881 882 return rendered_templates_no_duplicates 883 884 885class TemplateReplacementTests(BaseTestCase): 886 887 def test_two_templates_two_replacements_yields_correct_renders(self): 888 actual = template_replace( 889 templates=["Cats are word1", "Dogs are word2"], 890 replacements={ 891 "word1": ["small", "cute"], 892 "word2": ["big", "fluffy"], 893 }, 894 ) 895 expected = [ 896 ("Cats are small", "Dogs are big"), 897 ("Cats are small", "Dogs are fluffy"), 898 ("Cats are cute", "Dogs are big"), 899 ("Cats are cute", "Dogs are fluffy"), 900 ] 901 self.assertEqual(actual, expected) 902 903 def test_no_duplicates_if_replacement_not_in_templates(self): 904 actual = template_replace( 905 templates=["Cats are word1", "Dogs!"], 906 replacements={ 907 "word1": ["small", "cute"], 908 "word2": ["big", "fluffy"], 909 }, 910 ) 911 expected = [ 912 ("Cats are small", "Dogs!"), 913 ("Cats are cute", "Dogs!"), 914 ] 915 self.assertEqual(actual, expected) 916 917 918class GenericAliasSubstitutionTests(BaseTestCase): 919 """Tests for type variable substitution in generic aliases. 920 921 For variadic cases, these tests should be regarded as the source of truth, 922 since we hadn't realised the full complexity of variadic substitution 923 at the time of finalizing PEP 646. For full discussion, see 924 https://github.com/python/cpython/issues/91162. 925 """ 926 927 def test_one_parameter(self): 928 T = TypeVar('T') 929 Ts = TypeVarTuple('Ts') 930 Ts2 = TypeVarTuple('Ts2') 931 932 class C(Generic[T]): pass 933 934 generics = ['C', 'list', 'List'] 935 tuple_types = ['tuple', 'Tuple'] 936 937 tests = [ 938 # Alias # Args # Expected result 939 ('generic[T]', '[()]', 'TypeError'), 940 ('generic[T]', '[int]', 'generic[int]'), 941 ('generic[T]', '[int, str]', 'TypeError'), 942 ('generic[T]', '[tuple_type[int, ...]]', 'generic[tuple_type[int, ...]]'), 943 ('generic[T]', '[*tuple_type[int]]', 'generic[int]'), 944 ('generic[T]', '[*tuple_type[()]]', 'TypeError'), 945 ('generic[T]', '[*tuple_type[int, str]]', 'TypeError'), 946 ('generic[T]', '[*tuple_type[int, ...]]', 'TypeError'), 947 ('generic[T]', '[*Ts]', 'TypeError'), 948 ('generic[T]', '[T, *Ts]', 'TypeError'), 949 ('generic[T]', '[*Ts, T]', 'TypeError'), 950 # Raises TypeError because C is not variadic. 951 # (If C _were_ variadic, it'd be fine.) 952 ('C[T, *tuple_type[int, ...]]', '[int]', 'TypeError'), 953 # Should definitely raise TypeError: list only takes one argument. 954 ('list[T, *tuple_type[int, ...]]', '[int]', 'list[int, *tuple_type[int, ...]]'), 955 ('List[T, *tuple_type[int, ...]]', '[int]', 'TypeError'), 956 # Should raise, because more than one `TypeVarTuple` is not supported. 957 ('generic[*Ts, *Ts2]', '[int]', 'TypeError'), 958 ] 959 960 for alias_template, args_template, expected_template in tests: 961 rendered_templates = template_replace( 962 templates=[alias_template, args_template, expected_template], 963 replacements={'generic': generics, 'tuple_type': tuple_types} 964 ) 965 for alias_str, args_str, expected_str in rendered_templates: 966 with self.subTest(alias=alias_str, args=args_str, expected=expected_str): 967 if expected_str == 'TypeError': 968 with self.assertRaises(TypeError): 969 eval(alias_str + args_str) 970 else: 971 self.assertEqual( 972 eval(alias_str + args_str), 973 eval(expected_str) 974 ) 975 976 977 def test_two_parameters(self): 978 T1 = TypeVar('T1') 979 T2 = TypeVar('T2') 980 Ts = TypeVarTuple('Ts') 981 982 class C(Generic[T1, T2]): pass 983 984 generics = ['C', 'dict', 'Dict'] 985 tuple_types = ['tuple', 'Tuple'] 986 987 tests = [ 988 # Alias # Args # Expected result 989 ('generic[T1, T2]', '[()]', 'TypeError'), 990 ('generic[T1, T2]', '[int]', 'TypeError'), 991 ('generic[T1, T2]', '[int, str]', 'generic[int, str]'), 992 ('generic[T1, T2]', '[int, str, bool]', 'TypeError'), 993 ('generic[T1, T2]', '[*tuple_type[int]]', 'TypeError'), 994 ('generic[T1, T2]', '[*tuple_type[int, str]]', 'generic[int, str]'), 995 ('generic[T1, T2]', '[*tuple_type[int, str, bool]]', 'TypeError'), 996 997 ('generic[T1, T2]', '[int, *tuple_type[str]]', 'generic[int, str]'), 998 ('generic[T1, T2]', '[*tuple_type[int], str]', 'generic[int, str]'), 999 ('generic[T1, T2]', '[*tuple_type[int], *tuple_type[str]]', 'generic[int, str]'), 1000 ('generic[T1, T2]', '[*tuple_type[int, str], *tuple_type[()]]', 'generic[int, str]'), 1001 ('generic[T1, T2]', '[*tuple_type[()], *tuple_type[int, str]]', 'generic[int, str]'), 1002 ('generic[T1, T2]', '[*tuple_type[int], *tuple_type[()]]', 'TypeError'), 1003 ('generic[T1, T2]', '[*tuple_type[()], *tuple_type[int]]', 'TypeError'), 1004 ('generic[T1, T2]', '[*tuple_type[int, str], *tuple_type[float]]', 'TypeError'), 1005 ('generic[T1, T2]', '[*tuple_type[int], *tuple_type[str, float]]', 'TypeError'), 1006 ('generic[T1, T2]', '[*tuple_type[int, str], *tuple_type[float, bool]]', 'TypeError'), 1007 1008 ('generic[T1, T2]', '[tuple_type[int, ...]]', 'TypeError'), 1009 ('generic[T1, T2]', '[tuple_type[int, ...], tuple_type[str, ...]]', 'generic[tuple_type[int, ...], tuple_type[str, ...]]'), 1010 ('generic[T1, T2]', '[*tuple_type[int, ...]]', 'TypeError'), 1011 ('generic[T1, T2]', '[int, *tuple_type[str, ...]]', 'TypeError'), 1012 ('generic[T1, T2]', '[*tuple_type[int, ...], str]', 'TypeError'), 1013 ('generic[T1, T2]', '[*tuple_type[int, ...], *tuple_type[str, ...]]', 'TypeError'), 1014 ('generic[T1, T2]', '[*Ts]', 'TypeError'), 1015 ('generic[T1, T2]', '[T, *Ts]', 'TypeError'), 1016 ('generic[T1, T2]', '[*Ts, T]', 'TypeError'), 1017 # This one isn't technically valid - none of the things that 1018 # `generic` can be (defined in `generics` above) are variadic, so we 1019 # shouldn't really be able to do `generic[T1, *tuple_type[int, ...]]`. 1020 # So even if type checkers shouldn't allow it, we allow it at 1021 # runtime, in accordance with a general philosophy of "Keep the 1022 # runtime lenient so people can experiment with typing constructs". 1023 ('generic[T1, *tuple_type[int, ...]]', '[str]', 'generic[str, *tuple_type[int, ...]]'), 1024 ] 1025 1026 for alias_template, args_template, expected_template in tests: 1027 rendered_templates = template_replace( 1028 templates=[alias_template, args_template, expected_template], 1029 replacements={'generic': generics, 'tuple_type': tuple_types} 1030 ) 1031 for alias_str, args_str, expected_str in rendered_templates: 1032 with self.subTest(alias=alias_str, args=args_str, expected=expected_str): 1033 if expected_str == 'TypeError': 1034 with self.assertRaises(TypeError): 1035 eval(alias_str + args_str) 1036 else: 1037 self.assertEqual( 1038 eval(alias_str + args_str), 1039 eval(expected_str) 1040 ) 1041 1042 def test_three_parameters(self): 1043 T1 = TypeVar('T1') 1044 T2 = TypeVar('T2') 1045 T3 = TypeVar('T3') 1046 1047 class C(Generic[T1, T2, T3]): pass 1048 1049 generics = ['C'] 1050 tuple_types = ['tuple', 'Tuple'] 1051 1052 tests = [ 1053 # Alias # Args # Expected result 1054 ('generic[T1, bool, T2]', '[int, str]', 'generic[int, bool, str]'), 1055 ('generic[T1, bool, T2]', '[*tuple_type[int, str]]', 'generic[int, bool, str]'), 1056 ] 1057 1058 for alias_template, args_template, expected_template in tests: 1059 rendered_templates = template_replace( 1060 templates=[alias_template, args_template, expected_template], 1061 replacements={'generic': generics, 'tuple_type': tuple_types} 1062 ) 1063 for alias_str, args_str, expected_str in rendered_templates: 1064 with self.subTest(alias=alias_str, args=args_str, expected=expected_str): 1065 if expected_str == 'TypeError': 1066 with self.assertRaises(TypeError): 1067 eval(alias_str + args_str) 1068 else: 1069 self.assertEqual( 1070 eval(alias_str + args_str), 1071 eval(expected_str) 1072 ) 1073 1074 def test_variadic_parameters(self): 1075 T1 = TypeVar('T1') 1076 T2 = TypeVar('T2') 1077 Ts = TypeVarTuple('Ts') 1078 1079 class C(Generic[*Ts]): pass 1080 1081 generics = ['C', 'tuple', 'Tuple'] 1082 tuple_types = ['tuple', 'Tuple'] 1083 1084 tests = [ 1085 # Alias # Args # Expected result 1086 ('generic[*Ts]', '[()]', 'generic[()]'), 1087 ('generic[*Ts]', '[int]', 'generic[int]'), 1088 ('generic[*Ts]', '[int, str]', 'generic[int, str]'), 1089 ('generic[*Ts]', '[*tuple_type[int]]', 'generic[int]'), 1090 ('generic[*Ts]', '[*tuple_type[*Ts]]', 'generic[*Ts]'), 1091 ('generic[*Ts]', '[*tuple_type[int, str]]', 'generic[int, str]'), 1092 ('generic[*Ts]', '[str, *tuple_type[int, ...], bool]', 'generic[str, *tuple_type[int, ...], bool]'), 1093 ('generic[*Ts]', '[tuple_type[int, ...]]', 'generic[tuple_type[int, ...]]'), 1094 ('generic[*Ts]', '[tuple_type[int, ...], tuple_type[str, ...]]', 'generic[tuple_type[int, ...], tuple_type[str, ...]]'), 1095 ('generic[*Ts]', '[*tuple_type[int, ...]]', 'generic[*tuple_type[int, ...]]'), 1096 ('generic[*Ts]', '[*tuple_type[int, ...], *tuple_type[str, ...]]', 'TypeError'), 1097 1098 ('generic[*Ts]', '[*Ts]', 'generic[*Ts]'), 1099 ('generic[*Ts]', '[T, *Ts]', 'generic[T, *Ts]'), 1100 ('generic[*Ts]', '[*Ts, T]', 'generic[*Ts, T]'), 1101 ('generic[T, *Ts]', '[()]', 'TypeError'), 1102 ('generic[T, *Ts]', '[int]', 'generic[int]'), 1103 ('generic[T, *Ts]', '[int, str]', 'generic[int, str]'), 1104 ('generic[T, *Ts]', '[int, str, bool]', 'generic[int, str, bool]'), 1105 ('generic[list[T], *Ts]', '[()]', 'TypeError'), 1106 ('generic[list[T], *Ts]', '[int]', 'generic[list[int]]'), 1107 ('generic[list[T], *Ts]', '[int, str]', 'generic[list[int], str]'), 1108 ('generic[list[T], *Ts]', '[int, str, bool]', 'generic[list[int], str, bool]'), 1109 1110 ('generic[*Ts, T]', '[()]', 'TypeError'), 1111 ('generic[*Ts, T]', '[int]', 'generic[int]'), 1112 ('generic[*Ts, T]', '[int, str]', 'generic[int, str]'), 1113 ('generic[*Ts, T]', '[int, str, bool]', 'generic[int, str, bool]'), 1114 ('generic[*Ts, list[T]]', '[()]', 'TypeError'), 1115 ('generic[*Ts, list[T]]', '[int]', 'generic[list[int]]'), 1116 ('generic[*Ts, list[T]]', '[int, str]', 'generic[int, list[str]]'), 1117 ('generic[*Ts, list[T]]', '[int, str, bool]', 'generic[int, str, list[bool]]'), 1118 1119 ('generic[T1, T2, *Ts]', '[()]', 'TypeError'), 1120 ('generic[T1, T2, *Ts]', '[int]', 'TypeError'), 1121 ('generic[T1, T2, *Ts]', '[int, str]', 'generic[int, str]'), 1122 ('generic[T1, T2, *Ts]', '[int, str, bool]', 'generic[int, str, bool]'), 1123 ('generic[T1, T2, *Ts]', '[int, str, bool, bytes]', 'generic[int, str, bool, bytes]'), 1124 1125 ('generic[*Ts, T1, T2]', '[()]', 'TypeError'), 1126 ('generic[*Ts, T1, T2]', '[int]', 'TypeError'), 1127 ('generic[*Ts, T1, T2]', '[int, str]', 'generic[int, str]'), 1128 ('generic[*Ts, T1, T2]', '[int, str, bool]', 'generic[int, str, bool]'), 1129 ('generic[*Ts, T1, T2]', '[int, str, bool, bytes]', 'generic[int, str, bool, bytes]'), 1130 1131 ('generic[T1, *Ts, T2]', '[()]', 'TypeError'), 1132 ('generic[T1, *Ts, T2]', '[int]', 'TypeError'), 1133 ('generic[T1, *Ts, T2]', '[int, str]', 'generic[int, str]'), 1134 ('generic[T1, *Ts, T2]', '[int, str, bool]', 'generic[int, str, bool]'), 1135 ('generic[T1, *Ts, T2]', '[int, str, bool, bytes]', 'generic[int, str, bool, bytes]'), 1136 1137 ('generic[T, *Ts]', '[*tuple_type[int, ...]]', 'generic[int, *tuple_type[int, ...]]'), 1138 ('generic[T, *Ts]', '[str, *tuple_type[int, ...]]', 'generic[str, *tuple_type[int, ...]]'), 1139 ('generic[T, *Ts]', '[*tuple_type[int, ...], str]', 'generic[int, *tuple_type[int, ...], str]'), 1140 ('generic[*Ts, T]', '[*tuple_type[int, ...]]', 'generic[*tuple_type[int, ...], int]'), 1141 ('generic[*Ts, T]', '[str, *tuple_type[int, ...]]', 'generic[str, *tuple_type[int, ...], int]'), 1142 ('generic[*Ts, T]', '[*tuple_type[int, ...], str]', 'generic[*tuple_type[int, ...], str]'), 1143 ('generic[T1, *Ts, T2]', '[*tuple_type[int, ...]]', 'generic[int, *tuple_type[int, ...], int]'), 1144 ('generic[T, str, *Ts]', '[*tuple_type[int, ...]]', 'generic[int, str, *tuple_type[int, ...]]'), 1145 ('generic[*Ts, str, T]', '[*tuple_type[int, ...]]', 'generic[*tuple_type[int, ...], str, int]'), 1146 ('generic[list[T], *Ts]', '[*tuple_type[int, ...]]', 'generic[list[int], *tuple_type[int, ...]]'), 1147 ('generic[*Ts, list[T]]', '[*tuple_type[int, ...]]', 'generic[*tuple_type[int, ...], list[int]]'), 1148 1149 ('generic[T, *tuple_type[int, ...]]', '[str]', 'generic[str, *tuple_type[int, ...]]'), 1150 ('generic[T1, T2, *tuple_type[int, ...]]', '[str, bool]', 'generic[str, bool, *tuple_type[int, ...]]'), 1151 ('generic[T1, *tuple_type[int, ...], T2]', '[str, bool]', 'generic[str, *tuple_type[int, ...], bool]'), 1152 ('generic[T1, *tuple_type[int, ...], T2]', '[str, bool, float]', 'TypeError'), 1153 1154 ('generic[T1, *tuple_type[T2, ...]]', '[int, str]', 'generic[int, *tuple_type[str, ...]]'), 1155 ('generic[*tuple_type[T1, ...], T2]', '[int, str]', 'generic[*tuple_type[int, ...], str]'), 1156 ('generic[T1, *tuple_type[generic[*Ts], ...]]', '[int, str, bool]', 'generic[int, *tuple_type[generic[str, bool], ...]]'), 1157 ('generic[*tuple_type[generic[*Ts], ...], T1]', '[int, str, bool]', 'generic[*tuple_type[generic[int, str], ...], bool]'), 1158 ] 1159 1160 for alias_template, args_template, expected_template in tests: 1161 rendered_templates = template_replace( 1162 templates=[alias_template, args_template, expected_template], 1163 replacements={'generic': generics, 'tuple_type': tuple_types} 1164 ) 1165 for alias_str, args_str, expected_str in rendered_templates: 1166 with self.subTest(alias=alias_str, args=args_str, expected=expected_str): 1167 if expected_str == 'TypeError': 1168 with self.assertRaises(TypeError): 1169 eval(alias_str + args_str) 1170 else: 1171 self.assertEqual( 1172 eval(alias_str + args_str), 1173 eval(expected_str) 1174 ) 1175 1176 1177 1178class UnpackTests(BaseTestCase): 1179 1180 def test_accepts_single_type(self): 1181 (*tuple[int],) 1182 Unpack[Tuple[int]] 1183 1184 def test_dir(self): 1185 dir_items = set(dir(Unpack[Tuple[int]])) 1186 for required_item in [ 1187 '__args__', '__parameters__', '__origin__', 1188 ]: 1189 with self.subTest(required_item=required_item): 1190 self.assertIn(required_item, dir_items) 1191 1192 def test_rejects_multiple_types(self): 1193 with self.assertRaises(TypeError): 1194 Unpack[Tuple[int], Tuple[str]] 1195 # We can't do the equivalent for `*` here - 1196 # *(Tuple[int], Tuple[str]) is just plain tuple unpacking, 1197 # which is valid. 1198 1199 def test_rejects_multiple_parameterization(self): 1200 with self.assertRaises(TypeError): 1201 (*tuple[int],)[0][tuple[int]] 1202 with self.assertRaises(TypeError): 1203 Unpack[Tuple[int]][Tuple[int]] 1204 1205 def test_cannot_be_called(self): 1206 with self.assertRaises(TypeError): 1207 Unpack() 1208 1209 def test_usage_with_kwargs(self): 1210 Movie = TypedDict('Movie', {'name': str, 'year': int}) 1211 def foo(**kwargs: Unpack[Movie]): ... 1212 self.assertEqual(repr(foo.__annotations__['kwargs']), 1213 f"typing.Unpack[{__name__}.Movie]") 1214 1215 def test_builtin_tuple(self): 1216 Ts = TypeVarTuple("Ts") 1217 1218 class Old(Generic[*Ts]): ... 1219 class New[*Ts]: ... 1220 1221 PartOld = Old[int, *Ts] 1222 self.assertEqual(PartOld[str].__args__, (int, str)) 1223 self.assertEqual(PartOld[*tuple[str]].__args__, (int, str)) 1224 self.assertEqual(PartOld[*Tuple[str]].__args__, (int, str)) 1225 self.assertEqual(PartOld[Unpack[tuple[str]]].__args__, (int, str)) 1226 self.assertEqual(PartOld[Unpack[Tuple[str]]].__args__, (int, str)) 1227 1228 PartNew = New[int, *Ts] 1229 self.assertEqual(PartNew[str].__args__, (int, str)) 1230 self.assertEqual(PartNew[*tuple[str]].__args__, (int, str)) 1231 self.assertEqual(PartNew[*Tuple[str]].__args__, (int, str)) 1232 self.assertEqual(PartNew[Unpack[tuple[str]]].__args__, (int, str)) 1233 self.assertEqual(PartNew[Unpack[Tuple[str]]].__args__, (int, str)) 1234 1235 def test_unpack_wrong_type(self): 1236 Ts = TypeVarTuple("Ts") 1237 class Gen[*Ts]: ... 1238 PartGen = Gen[int, *Ts] 1239 1240 bad_unpack_param = re.escape("Unpack[...] must be used with a tuple type") 1241 with self.assertRaisesRegex(TypeError, bad_unpack_param): 1242 PartGen[Unpack[list[int]]] 1243 with self.assertRaisesRegex(TypeError, bad_unpack_param): 1244 PartGen[Unpack[List[int]]] 1245 1246 1247class TypeVarTupleTests(BaseTestCase): 1248 1249 def assertEndsWith(self, string, tail): 1250 if not string.endswith(tail): 1251 self.fail(f"String {string!r} does not end with {tail!r}") 1252 1253 def test_name(self): 1254 Ts = TypeVarTuple('Ts') 1255 self.assertEqual(Ts.__name__, 'Ts') 1256 Ts2 = TypeVarTuple('Ts2') 1257 self.assertEqual(Ts2.__name__, 'Ts2') 1258 1259 def test_module(self): 1260 Ts = TypeVarTuple('Ts') 1261 self.assertEqual(Ts.__module__, __name__) 1262 1263 def test_exec(self): 1264 ns = {} 1265 exec('from typing import TypeVarTuple; Ts = TypeVarTuple("Ts")', ns) 1266 Ts = ns['Ts'] 1267 self.assertEqual(Ts.__name__, 'Ts') 1268 self.assertIs(Ts.__module__, None) 1269 1270 def test_instance_is_equal_to_itself(self): 1271 Ts = TypeVarTuple('Ts') 1272 self.assertEqual(Ts, Ts) 1273 1274 def test_different_instances_are_different(self): 1275 self.assertNotEqual(TypeVarTuple('Ts'), TypeVarTuple('Ts')) 1276 1277 def test_instance_isinstance_of_typevartuple(self): 1278 Ts = TypeVarTuple('Ts') 1279 self.assertIsInstance(Ts, TypeVarTuple) 1280 1281 def test_cannot_call_instance(self): 1282 Ts = TypeVarTuple('Ts') 1283 with self.assertRaises(TypeError): 1284 Ts() 1285 1286 def test_unpacked_typevartuple_is_equal_to_itself(self): 1287 Ts = TypeVarTuple('Ts') 1288 self.assertEqual((*Ts,)[0], (*Ts,)[0]) 1289 self.assertEqual(Unpack[Ts], Unpack[Ts]) 1290 1291 def test_parameterised_tuple_is_equal_to_itself(self): 1292 Ts = TypeVarTuple('Ts') 1293 self.assertEqual(tuple[*Ts], tuple[*Ts]) 1294 self.assertEqual(Tuple[Unpack[Ts]], Tuple[Unpack[Ts]]) 1295 1296 def tests_tuple_arg_ordering_matters(self): 1297 Ts1 = TypeVarTuple('Ts1') 1298 Ts2 = TypeVarTuple('Ts2') 1299 self.assertNotEqual( 1300 tuple[*Ts1, *Ts2], 1301 tuple[*Ts2, *Ts1], 1302 ) 1303 self.assertNotEqual( 1304 Tuple[Unpack[Ts1], Unpack[Ts2]], 1305 Tuple[Unpack[Ts2], Unpack[Ts1]], 1306 ) 1307 1308 def test_tuple_args_and_parameters_are_correct(self): 1309 Ts = TypeVarTuple('Ts') 1310 t1 = tuple[*Ts] 1311 self.assertEqual(t1.__args__, (*Ts,)) 1312 self.assertEqual(t1.__parameters__, (Ts,)) 1313 t2 = Tuple[Unpack[Ts]] 1314 self.assertEqual(t2.__args__, (Unpack[Ts],)) 1315 self.assertEqual(t2.__parameters__, (Ts,)) 1316 1317 def test_var_substitution(self): 1318 Ts = TypeVarTuple('Ts') 1319 T = TypeVar('T') 1320 T2 = TypeVar('T2') 1321 class G1(Generic[*Ts]): pass 1322 class G2(Generic[Unpack[Ts]]): pass 1323 1324 for A in G1, G2, Tuple, tuple: 1325 B = A[*Ts] 1326 self.assertEqual(B[()], A[()]) 1327 self.assertEqual(B[float], A[float]) 1328 self.assertEqual(B[float, str], A[float, str]) 1329 1330 C = A[Unpack[Ts]] 1331 self.assertEqual(C[()], A[()]) 1332 self.assertEqual(C[float], A[float]) 1333 self.assertEqual(C[float, str], A[float, str]) 1334 1335 D = list[A[*Ts]] 1336 self.assertEqual(D[()], list[A[()]]) 1337 self.assertEqual(D[float], list[A[float]]) 1338 self.assertEqual(D[float, str], list[A[float, str]]) 1339 1340 E = List[A[Unpack[Ts]]] 1341 self.assertEqual(E[()], List[A[()]]) 1342 self.assertEqual(E[float], List[A[float]]) 1343 self.assertEqual(E[float, str], List[A[float, str]]) 1344 1345 F = A[T, *Ts, T2] 1346 with self.assertRaises(TypeError): 1347 F[()] 1348 with self.assertRaises(TypeError): 1349 F[float] 1350 self.assertEqual(F[float, str], A[float, str]) 1351 self.assertEqual(F[float, str, int], A[float, str, int]) 1352 self.assertEqual(F[float, str, int, bytes], A[float, str, int, bytes]) 1353 1354 G = A[T, Unpack[Ts], T2] 1355 with self.assertRaises(TypeError): 1356 G[()] 1357 with self.assertRaises(TypeError): 1358 G[float] 1359 self.assertEqual(G[float, str], A[float, str]) 1360 self.assertEqual(G[float, str, int], A[float, str, int]) 1361 self.assertEqual(G[float, str, int, bytes], A[float, str, int, bytes]) 1362 1363 H = tuple[list[T], A[*Ts], list[T2]] 1364 with self.assertRaises(TypeError): 1365 H[()] 1366 with self.assertRaises(TypeError): 1367 H[float] 1368 if A != Tuple: 1369 self.assertEqual(H[float, str], 1370 tuple[list[float], A[()], list[str]]) 1371 self.assertEqual(H[float, str, int], 1372 tuple[list[float], A[str], list[int]]) 1373 self.assertEqual(H[float, str, int, bytes], 1374 tuple[list[float], A[str, int], list[bytes]]) 1375 1376 I = Tuple[List[T], A[Unpack[Ts]], List[T2]] 1377 with self.assertRaises(TypeError): 1378 I[()] 1379 with self.assertRaises(TypeError): 1380 I[float] 1381 if A != Tuple: 1382 self.assertEqual(I[float, str], 1383 Tuple[List[float], A[()], List[str]]) 1384 self.assertEqual(I[float, str, int], 1385 Tuple[List[float], A[str], List[int]]) 1386 self.assertEqual(I[float, str, int, bytes], 1387 Tuple[List[float], A[str, int], List[bytes]]) 1388 1389 def test_bad_var_substitution(self): 1390 Ts = TypeVarTuple('Ts') 1391 T = TypeVar('T') 1392 T2 = TypeVar('T2') 1393 class G1(Generic[*Ts]): pass 1394 class G2(Generic[Unpack[Ts]]): pass 1395 1396 for A in G1, G2, Tuple, tuple: 1397 B = A[Ts] 1398 with self.assertRaises(TypeError): 1399 B[int, str] 1400 1401 C = A[T, T2] 1402 with self.assertRaises(TypeError): 1403 C[*Ts] 1404 with self.assertRaises(TypeError): 1405 C[Unpack[Ts]] 1406 1407 B = A[T, *Ts, str, T2] 1408 with self.assertRaises(TypeError): 1409 B[int, *Ts] 1410 with self.assertRaises(TypeError): 1411 B[int, *Ts, *Ts] 1412 1413 C = A[T, Unpack[Ts], str, T2] 1414 with self.assertRaises(TypeError): 1415 C[int, Unpack[Ts]] 1416 with self.assertRaises(TypeError): 1417 C[int, Unpack[Ts], Unpack[Ts]] 1418 1419 def test_repr_is_correct(self): 1420 Ts = TypeVarTuple('Ts') 1421 1422 class G1(Generic[*Ts]): pass 1423 class G2(Generic[Unpack[Ts]]): pass 1424 1425 self.assertEqual(repr(Ts), 'Ts') 1426 1427 self.assertEqual(repr((*Ts,)[0]), 'typing.Unpack[Ts]') 1428 self.assertEqual(repr(Unpack[Ts]), 'typing.Unpack[Ts]') 1429 1430 self.assertEqual(repr(tuple[*Ts]), 'tuple[typing.Unpack[Ts]]') 1431 self.assertEqual(repr(Tuple[Unpack[Ts]]), 'typing.Tuple[typing.Unpack[Ts]]') 1432 1433 self.assertEqual(repr(*tuple[*Ts]), '*tuple[typing.Unpack[Ts]]') 1434 self.assertEqual(repr(Unpack[Tuple[Unpack[Ts]]]), 'typing.Unpack[typing.Tuple[typing.Unpack[Ts]]]') 1435 1436 def test_variadic_class_repr_is_correct(self): 1437 Ts = TypeVarTuple('Ts') 1438 class A(Generic[*Ts]): pass 1439 class B(Generic[Unpack[Ts]]): pass 1440 1441 self.assertEndsWith(repr(A[()]), 'A[()]') 1442 self.assertEndsWith(repr(B[()]), 'B[()]') 1443 self.assertEndsWith(repr(A[float]), 'A[float]') 1444 self.assertEndsWith(repr(B[float]), 'B[float]') 1445 self.assertEndsWith(repr(A[float, str]), 'A[float, str]') 1446 self.assertEndsWith(repr(B[float, str]), 'B[float, str]') 1447 1448 self.assertEndsWith(repr(A[*tuple[int, ...]]), 1449 'A[*tuple[int, ...]]') 1450 self.assertEndsWith(repr(B[Unpack[Tuple[int, ...]]]), 1451 'B[typing.Unpack[typing.Tuple[int, ...]]]') 1452 1453 self.assertEndsWith(repr(A[float, *tuple[int, ...]]), 1454 'A[float, *tuple[int, ...]]') 1455 self.assertEndsWith(repr(A[float, Unpack[Tuple[int, ...]]]), 1456 'A[float, typing.Unpack[typing.Tuple[int, ...]]]') 1457 1458 self.assertEndsWith(repr(A[*tuple[int, ...], str]), 1459 'A[*tuple[int, ...], str]') 1460 self.assertEndsWith(repr(B[Unpack[Tuple[int, ...]], str]), 1461 'B[typing.Unpack[typing.Tuple[int, ...]], str]') 1462 1463 self.assertEndsWith(repr(A[float, *tuple[int, ...], str]), 1464 'A[float, *tuple[int, ...], str]') 1465 self.assertEndsWith(repr(B[float, Unpack[Tuple[int, ...]], str]), 1466 'B[float, typing.Unpack[typing.Tuple[int, ...]], str]') 1467 1468 def test_variadic_class_alias_repr_is_correct(self): 1469 Ts = TypeVarTuple('Ts') 1470 class A(Generic[Unpack[Ts]]): pass 1471 1472 B = A[*Ts] 1473 self.assertEndsWith(repr(B), 'A[typing.Unpack[Ts]]') 1474 self.assertEndsWith(repr(B[()]), 'A[()]') 1475 self.assertEndsWith(repr(B[float]), 'A[float]') 1476 self.assertEndsWith(repr(B[float, str]), 'A[float, str]') 1477 1478 C = A[Unpack[Ts]] 1479 self.assertEndsWith(repr(C), 'A[typing.Unpack[Ts]]') 1480 self.assertEndsWith(repr(C[()]), 'A[()]') 1481 self.assertEndsWith(repr(C[float]), 'A[float]') 1482 self.assertEndsWith(repr(C[float, str]), 'A[float, str]') 1483 1484 D = A[*Ts, int] 1485 self.assertEndsWith(repr(D), 'A[typing.Unpack[Ts], int]') 1486 self.assertEndsWith(repr(D[()]), 'A[int]') 1487 self.assertEndsWith(repr(D[float]), 'A[float, int]') 1488 self.assertEndsWith(repr(D[float, str]), 'A[float, str, int]') 1489 1490 E = A[Unpack[Ts], int] 1491 self.assertEndsWith(repr(E), 'A[typing.Unpack[Ts], int]') 1492 self.assertEndsWith(repr(E[()]), 'A[int]') 1493 self.assertEndsWith(repr(E[float]), 'A[float, int]') 1494 self.assertEndsWith(repr(E[float, str]), 'A[float, str, int]') 1495 1496 F = A[int, *Ts] 1497 self.assertEndsWith(repr(F), 'A[int, typing.Unpack[Ts]]') 1498 self.assertEndsWith(repr(F[()]), 'A[int]') 1499 self.assertEndsWith(repr(F[float]), 'A[int, float]') 1500 self.assertEndsWith(repr(F[float, str]), 'A[int, float, str]') 1501 1502 G = A[int, Unpack[Ts]] 1503 self.assertEndsWith(repr(G), 'A[int, typing.Unpack[Ts]]') 1504 self.assertEndsWith(repr(G[()]), 'A[int]') 1505 self.assertEndsWith(repr(G[float]), 'A[int, float]') 1506 self.assertEndsWith(repr(G[float, str]), 'A[int, float, str]') 1507 1508 H = A[int, *Ts, str] 1509 self.assertEndsWith(repr(H), 'A[int, typing.Unpack[Ts], str]') 1510 self.assertEndsWith(repr(H[()]), 'A[int, str]') 1511 self.assertEndsWith(repr(H[float]), 'A[int, float, str]') 1512 self.assertEndsWith(repr(H[float, str]), 'A[int, float, str, str]') 1513 1514 I = A[int, Unpack[Ts], str] 1515 self.assertEndsWith(repr(I), 'A[int, typing.Unpack[Ts], str]') 1516 self.assertEndsWith(repr(I[()]), 'A[int, str]') 1517 self.assertEndsWith(repr(I[float]), 'A[int, float, str]') 1518 self.assertEndsWith(repr(I[float, str]), 'A[int, float, str, str]') 1519 1520 J = A[*Ts, *tuple[str, ...]] 1521 self.assertEndsWith(repr(J), 'A[typing.Unpack[Ts], *tuple[str, ...]]') 1522 self.assertEndsWith(repr(J[()]), 'A[*tuple[str, ...]]') 1523 self.assertEndsWith(repr(J[float]), 'A[float, *tuple[str, ...]]') 1524 self.assertEndsWith(repr(J[float, str]), 'A[float, str, *tuple[str, ...]]') 1525 1526 K = A[Unpack[Ts], Unpack[Tuple[str, ...]]] 1527 self.assertEndsWith(repr(K), 'A[typing.Unpack[Ts], typing.Unpack[typing.Tuple[str, ...]]]') 1528 self.assertEndsWith(repr(K[()]), 'A[typing.Unpack[typing.Tuple[str, ...]]]') 1529 self.assertEndsWith(repr(K[float]), 'A[float, typing.Unpack[typing.Tuple[str, ...]]]') 1530 self.assertEndsWith(repr(K[float, str]), 'A[float, str, typing.Unpack[typing.Tuple[str, ...]]]') 1531 1532 def test_cannot_subclass(self): 1533 with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'TypeVarTuple'): 1534 class C(TypeVarTuple): pass 1535 Ts = TypeVarTuple('Ts') 1536 with self.assertRaisesRegex(TypeError, 1537 CANNOT_SUBCLASS_INSTANCE % 'TypeVarTuple'): 1538 class D(Ts): pass 1539 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 1540 class E(type(Unpack)): pass 1541 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 1542 class F(type(*Ts)): pass 1543 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 1544 class G(type(Unpack[Ts])): pass 1545 with self.assertRaisesRegex(TypeError, 1546 r'Cannot subclass typing\.Unpack'): 1547 class H(Unpack): pass 1548 with self.assertRaisesRegex(TypeError, r'Cannot subclass typing.Unpack\[Ts\]'): 1549 class I(*Ts): pass 1550 with self.assertRaisesRegex(TypeError, r'Cannot subclass typing.Unpack\[Ts\]'): 1551 class J(Unpack[Ts]): pass 1552 1553 def test_variadic_class_args_are_correct(self): 1554 T = TypeVar('T') 1555 Ts = TypeVarTuple('Ts') 1556 class A(Generic[*Ts]): pass 1557 class B(Generic[Unpack[Ts]]): pass 1558 1559 C = A[()] 1560 D = B[()] 1561 self.assertEqual(C.__args__, ()) 1562 self.assertEqual(D.__args__, ()) 1563 1564 E = A[int] 1565 F = B[int] 1566 self.assertEqual(E.__args__, (int,)) 1567 self.assertEqual(F.__args__, (int,)) 1568 1569 G = A[int, str] 1570 H = B[int, str] 1571 self.assertEqual(G.__args__, (int, str)) 1572 self.assertEqual(H.__args__, (int, str)) 1573 1574 I = A[T] 1575 J = B[T] 1576 self.assertEqual(I.__args__, (T,)) 1577 self.assertEqual(J.__args__, (T,)) 1578 1579 K = A[*Ts] 1580 L = B[Unpack[Ts]] 1581 self.assertEqual(K.__args__, (*Ts,)) 1582 self.assertEqual(L.__args__, (Unpack[Ts],)) 1583 1584 M = A[T, *Ts] 1585 N = B[T, Unpack[Ts]] 1586 self.assertEqual(M.__args__, (T, *Ts)) 1587 self.assertEqual(N.__args__, (T, Unpack[Ts])) 1588 1589 O = A[*Ts, T] 1590 P = B[Unpack[Ts], T] 1591 self.assertEqual(O.__args__, (*Ts, T)) 1592 self.assertEqual(P.__args__, (Unpack[Ts], T)) 1593 1594 def test_variadic_class_origin_is_correct(self): 1595 Ts = TypeVarTuple('Ts') 1596 1597 class C(Generic[*Ts]): pass 1598 self.assertIs(C[int].__origin__, C) 1599 self.assertIs(C[T].__origin__, C) 1600 self.assertIs(C[Unpack[Ts]].__origin__, C) 1601 1602 class D(Generic[Unpack[Ts]]): pass 1603 self.assertIs(D[int].__origin__, D) 1604 self.assertIs(D[T].__origin__, D) 1605 self.assertIs(D[Unpack[Ts]].__origin__, D) 1606 1607 def test_get_type_hints_on_unpack_args(self): 1608 Ts = TypeVarTuple('Ts') 1609 1610 def func1(*args: *Ts): pass 1611 self.assertEqual(gth(func1), {'args': Unpack[Ts]}) 1612 1613 def func2(*args: *tuple[int, str]): pass 1614 self.assertEqual(gth(func2), {'args': Unpack[tuple[int, str]]}) 1615 1616 class CustomVariadic(Generic[*Ts]): pass 1617 1618 def func3(*args: *CustomVariadic[int, str]): pass 1619 self.assertEqual(gth(func3), {'args': Unpack[CustomVariadic[int, str]]}) 1620 1621 def test_get_type_hints_on_unpack_args_string(self): 1622 Ts = TypeVarTuple('Ts') 1623 1624 def func1(*args: '*Ts'): pass 1625 self.assertEqual(gth(func1, localns={'Ts': Ts}), 1626 {'args': Unpack[Ts]}) 1627 1628 def func2(*args: '*tuple[int, str]'): pass 1629 self.assertEqual(gth(func2), {'args': Unpack[tuple[int, str]]}) 1630 1631 class CustomVariadic(Generic[*Ts]): pass 1632 1633 def func3(*args: '*CustomVariadic[int, str]'): pass 1634 self.assertEqual(gth(func3, localns={'CustomVariadic': CustomVariadic}), 1635 {'args': Unpack[CustomVariadic[int, str]]}) 1636 1637 def test_tuple_args_are_correct(self): 1638 Ts = TypeVarTuple('Ts') 1639 1640 self.assertEqual(tuple[*Ts].__args__, (*Ts,)) 1641 self.assertEqual(Tuple[Unpack[Ts]].__args__, (Unpack[Ts],)) 1642 1643 self.assertEqual(tuple[*Ts, int].__args__, (*Ts, int)) 1644 self.assertEqual(Tuple[Unpack[Ts], int].__args__, (Unpack[Ts], int)) 1645 1646 self.assertEqual(tuple[int, *Ts].__args__, (int, *Ts)) 1647 self.assertEqual(Tuple[int, Unpack[Ts]].__args__, (int, Unpack[Ts])) 1648 1649 self.assertEqual(tuple[int, *Ts, str].__args__, 1650 (int, *Ts, str)) 1651 self.assertEqual(Tuple[int, Unpack[Ts], str].__args__, 1652 (int, Unpack[Ts], str)) 1653 1654 self.assertEqual(tuple[*Ts, int].__args__, (*Ts, int)) 1655 self.assertEqual(Tuple[Unpack[Ts]].__args__, (Unpack[Ts],)) 1656 1657 def test_callable_args_are_correct(self): 1658 Ts = TypeVarTuple('Ts') 1659 Ts1 = TypeVarTuple('Ts1') 1660 Ts2 = TypeVarTuple('Ts2') 1661 1662 # TypeVarTuple in the arguments 1663 1664 a = Callable[[*Ts], None] 1665 b = Callable[[Unpack[Ts]], None] 1666 self.assertEqual(a.__args__, (*Ts, type(None))) 1667 self.assertEqual(b.__args__, (Unpack[Ts], type(None))) 1668 1669 c = Callable[[int, *Ts], None] 1670 d = Callable[[int, Unpack[Ts]], None] 1671 self.assertEqual(c.__args__, (int, *Ts, type(None))) 1672 self.assertEqual(d.__args__, (int, Unpack[Ts], type(None))) 1673 1674 e = Callable[[*Ts, int], None] 1675 f = Callable[[Unpack[Ts], int], None] 1676 self.assertEqual(e.__args__, (*Ts, int, type(None))) 1677 self.assertEqual(f.__args__, (Unpack[Ts], int, type(None))) 1678 1679 g = Callable[[str, *Ts, int], None] 1680 h = Callable[[str, Unpack[Ts], int], None] 1681 self.assertEqual(g.__args__, (str, *Ts, int, type(None))) 1682 self.assertEqual(h.__args__, (str, Unpack[Ts], int, type(None))) 1683 1684 # TypeVarTuple as the return 1685 1686 i = Callable[[None], *Ts] 1687 j = Callable[[None], Unpack[Ts]] 1688 self.assertEqual(i.__args__, (type(None), *Ts)) 1689 self.assertEqual(j.__args__, (type(None), Unpack[Ts])) 1690 1691 k = Callable[[None], tuple[int, *Ts]] 1692 l = Callable[[None], Tuple[int, Unpack[Ts]]] 1693 self.assertEqual(k.__args__, (type(None), tuple[int, *Ts])) 1694 self.assertEqual(l.__args__, (type(None), Tuple[int, Unpack[Ts]])) 1695 1696 m = Callable[[None], tuple[*Ts, int]] 1697 n = Callable[[None], Tuple[Unpack[Ts], int]] 1698 self.assertEqual(m.__args__, (type(None), tuple[*Ts, int])) 1699 self.assertEqual(n.__args__, (type(None), Tuple[Unpack[Ts], int])) 1700 1701 o = Callable[[None], tuple[str, *Ts, int]] 1702 p = Callable[[None], Tuple[str, Unpack[Ts], int]] 1703 self.assertEqual(o.__args__, (type(None), tuple[str, *Ts, int])) 1704 self.assertEqual(p.__args__, (type(None), Tuple[str, Unpack[Ts], int])) 1705 1706 # TypeVarTuple in both 1707 1708 q = Callable[[*Ts], *Ts] 1709 r = Callable[[Unpack[Ts]], Unpack[Ts]] 1710 self.assertEqual(q.__args__, (*Ts, *Ts)) 1711 self.assertEqual(r.__args__, (Unpack[Ts], Unpack[Ts])) 1712 1713 s = Callable[[*Ts1], *Ts2] 1714 u = Callable[[Unpack[Ts1]], Unpack[Ts2]] 1715 self.assertEqual(s.__args__, (*Ts1, *Ts2)) 1716 self.assertEqual(u.__args__, (Unpack[Ts1], Unpack[Ts2])) 1717 1718 def test_variadic_class_with_duplicate_typevartuples_fails(self): 1719 Ts1 = TypeVarTuple('Ts1') 1720 Ts2 = TypeVarTuple('Ts2') 1721 1722 with self.assertRaises(TypeError): 1723 class C(Generic[*Ts1, *Ts1]): pass 1724 with self.assertRaises(TypeError): 1725 class D(Generic[Unpack[Ts1], Unpack[Ts1]]): pass 1726 1727 with self.assertRaises(TypeError): 1728 class E(Generic[*Ts1, *Ts2, *Ts1]): pass 1729 with self.assertRaises(TypeError): 1730 class F(Generic[Unpack[Ts1], Unpack[Ts2], Unpack[Ts1]]): pass 1731 1732 def test_type_concatenation_in_variadic_class_argument_list_succeeds(self): 1733 Ts = TypeVarTuple('Ts') 1734 class C(Generic[Unpack[Ts]]): pass 1735 1736 C[int, *Ts] 1737 C[int, Unpack[Ts]] 1738 1739 C[*Ts, int] 1740 C[Unpack[Ts], int] 1741 1742 C[int, *Ts, str] 1743 C[int, Unpack[Ts], str] 1744 1745 C[int, bool, *Ts, float, str] 1746 C[int, bool, Unpack[Ts], float, str] 1747 1748 def test_type_concatenation_in_tuple_argument_list_succeeds(self): 1749 Ts = TypeVarTuple('Ts') 1750 1751 tuple[int, *Ts] 1752 tuple[*Ts, int] 1753 tuple[int, *Ts, str] 1754 tuple[int, bool, *Ts, float, str] 1755 1756 Tuple[int, Unpack[Ts]] 1757 Tuple[Unpack[Ts], int] 1758 Tuple[int, Unpack[Ts], str] 1759 Tuple[int, bool, Unpack[Ts], float, str] 1760 1761 def test_variadic_class_definition_using_packed_typevartuple_fails(self): 1762 Ts = TypeVarTuple('Ts') 1763 with self.assertRaises(TypeError): 1764 class C(Generic[Ts]): pass 1765 1766 def test_variadic_class_definition_using_concrete_types_fails(self): 1767 Ts = TypeVarTuple('Ts') 1768 with self.assertRaises(TypeError): 1769 class F(Generic[*Ts, int]): pass 1770 with self.assertRaises(TypeError): 1771 class E(Generic[Unpack[Ts], int]): pass 1772 1773 def test_variadic_class_with_2_typevars_accepts_2_or_more_args(self): 1774 Ts = TypeVarTuple('Ts') 1775 T1 = TypeVar('T1') 1776 T2 = TypeVar('T2') 1777 1778 class A(Generic[T1, T2, *Ts]): pass 1779 A[int, str] 1780 A[int, str, float] 1781 A[int, str, float, bool] 1782 1783 class B(Generic[T1, T2, Unpack[Ts]]): pass 1784 B[int, str] 1785 B[int, str, float] 1786 B[int, str, float, bool] 1787 1788 class C(Generic[T1, *Ts, T2]): pass 1789 C[int, str] 1790 C[int, str, float] 1791 C[int, str, float, bool] 1792 1793 class D(Generic[T1, Unpack[Ts], T2]): pass 1794 D[int, str] 1795 D[int, str, float] 1796 D[int, str, float, bool] 1797 1798 class E(Generic[*Ts, T1, T2]): pass 1799 E[int, str] 1800 E[int, str, float] 1801 E[int, str, float, bool] 1802 1803 class F(Generic[Unpack[Ts], T1, T2]): pass 1804 F[int, str] 1805 F[int, str, float] 1806 F[int, str, float, bool] 1807 1808 def test_variadic_args_annotations_are_correct(self): 1809 Ts = TypeVarTuple('Ts') 1810 1811 def f(*args: Unpack[Ts]): pass 1812 def g(*args: *Ts): pass 1813 self.assertEqual(f.__annotations__, {'args': Unpack[Ts]}) 1814 self.assertEqual(g.__annotations__, {'args': (*Ts,)[0]}) 1815 1816 def test_variadic_args_with_ellipsis_annotations_are_correct(self): 1817 def a(*args: *tuple[int, ...]): pass 1818 self.assertEqual(a.__annotations__, 1819 {'args': (*tuple[int, ...],)[0]}) 1820 1821 def b(*args: Unpack[Tuple[int, ...]]): pass 1822 self.assertEqual(b.__annotations__, 1823 {'args': Unpack[Tuple[int, ...]]}) 1824 1825 def test_concatenation_in_variadic_args_annotations_are_correct(self): 1826 Ts = TypeVarTuple('Ts') 1827 1828 # Unpacking using `*`, native `tuple` type 1829 1830 def a(*args: *tuple[int, *Ts]): pass 1831 self.assertEqual( 1832 a.__annotations__, 1833 {'args': (*tuple[int, *Ts],)[0]}, 1834 ) 1835 1836 def b(*args: *tuple[*Ts, int]): pass 1837 self.assertEqual( 1838 b.__annotations__, 1839 {'args': (*tuple[*Ts, int],)[0]}, 1840 ) 1841 1842 def c(*args: *tuple[str, *Ts, int]): pass 1843 self.assertEqual( 1844 c.__annotations__, 1845 {'args': (*tuple[str, *Ts, int],)[0]}, 1846 ) 1847 1848 def d(*args: *tuple[int, bool, *Ts, float, str]): pass 1849 self.assertEqual( 1850 d.__annotations__, 1851 {'args': (*tuple[int, bool, *Ts, float, str],)[0]}, 1852 ) 1853 1854 # Unpacking using `Unpack`, `Tuple` type from typing.py 1855 1856 def e(*args: Unpack[Tuple[int, Unpack[Ts]]]): pass 1857 self.assertEqual( 1858 e.__annotations__, 1859 {'args': Unpack[Tuple[int, Unpack[Ts]]]}, 1860 ) 1861 1862 def f(*args: Unpack[Tuple[Unpack[Ts], int]]): pass 1863 self.assertEqual( 1864 f.__annotations__, 1865 {'args': Unpack[Tuple[Unpack[Ts], int]]}, 1866 ) 1867 1868 def g(*args: Unpack[Tuple[str, Unpack[Ts], int]]): pass 1869 self.assertEqual( 1870 g.__annotations__, 1871 {'args': Unpack[Tuple[str, Unpack[Ts], int]]}, 1872 ) 1873 1874 def h(*args: Unpack[Tuple[int, bool, Unpack[Ts], float, str]]): pass 1875 self.assertEqual( 1876 h.__annotations__, 1877 {'args': Unpack[Tuple[int, bool, Unpack[Ts], float, str]]}, 1878 ) 1879 1880 def test_variadic_class_same_args_results_in_equalty(self): 1881 Ts = TypeVarTuple('Ts') 1882 class C(Generic[*Ts]): pass 1883 class D(Generic[Unpack[Ts]]): pass 1884 1885 self.assertEqual(C[int], C[int]) 1886 self.assertEqual(D[int], D[int]) 1887 1888 Ts1 = TypeVarTuple('Ts1') 1889 Ts2 = TypeVarTuple('Ts2') 1890 1891 self.assertEqual( 1892 C[*Ts1], 1893 C[*Ts1], 1894 ) 1895 self.assertEqual( 1896 D[Unpack[Ts1]], 1897 D[Unpack[Ts1]], 1898 ) 1899 1900 self.assertEqual( 1901 C[*Ts1, *Ts2], 1902 C[*Ts1, *Ts2], 1903 ) 1904 self.assertEqual( 1905 D[Unpack[Ts1], Unpack[Ts2]], 1906 D[Unpack[Ts1], Unpack[Ts2]], 1907 ) 1908 1909 self.assertEqual( 1910 C[int, *Ts1, *Ts2], 1911 C[int, *Ts1, *Ts2], 1912 ) 1913 self.assertEqual( 1914 D[int, Unpack[Ts1], Unpack[Ts2]], 1915 D[int, Unpack[Ts1], Unpack[Ts2]], 1916 ) 1917 1918 def test_variadic_class_arg_ordering_matters(self): 1919 Ts = TypeVarTuple('Ts') 1920 class C(Generic[*Ts]): pass 1921 class D(Generic[Unpack[Ts]]): pass 1922 1923 self.assertNotEqual( 1924 C[int, str], 1925 C[str, int], 1926 ) 1927 self.assertNotEqual( 1928 D[int, str], 1929 D[str, int], 1930 ) 1931 1932 Ts1 = TypeVarTuple('Ts1') 1933 Ts2 = TypeVarTuple('Ts2') 1934 1935 self.assertNotEqual( 1936 C[*Ts1, *Ts2], 1937 C[*Ts2, *Ts1], 1938 ) 1939 self.assertNotEqual( 1940 D[Unpack[Ts1], Unpack[Ts2]], 1941 D[Unpack[Ts2], Unpack[Ts1]], 1942 ) 1943 1944 def test_variadic_class_arg_typevartuple_identity_matters(self): 1945 Ts = TypeVarTuple('Ts') 1946 Ts1 = TypeVarTuple('Ts1') 1947 Ts2 = TypeVarTuple('Ts2') 1948 1949 class C(Generic[*Ts]): pass 1950 class D(Generic[Unpack[Ts]]): pass 1951 1952 self.assertNotEqual(C[*Ts1], C[*Ts2]) 1953 self.assertNotEqual(D[Unpack[Ts1]], D[Unpack[Ts2]]) 1954 1955 1956class TypeVarTuplePicklingTests(BaseTestCase): 1957 # These are slightly awkward tests to run, because TypeVarTuples are only 1958 # picklable if defined in the global scope. We therefore need to push 1959 # various things defined in these tests into the global scope with `global` 1960 # statements at the start of each test. 1961 1962 @all_pickle_protocols 1963 def test_pickling_then_unpickling_results_in_same_identity(self, proto): 1964 global global_Ts1 # See explanation at start of class. 1965 global_Ts1 = TypeVarTuple('global_Ts1') 1966 global_Ts2 = pickle.loads(pickle.dumps(global_Ts1, proto)) 1967 self.assertIs(global_Ts1, global_Ts2) 1968 1969 @all_pickle_protocols 1970 def test_pickling_then_unpickling_unpacked_results_in_same_identity(self, proto): 1971 global global_Ts # See explanation at start of class. 1972 global_Ts = TypeVarTuple('global_Ts') 1973 1974 unpacked1 = (*global_Ts,)[0] 1975 unpacked2 = pickle.loads(pickle.dumps(unpacked1, proto)) 1976 self.assertIs(unpacked1, unpacked2) 1977 1978 unpacked3 = Unpack[global_Ts] 1979 unpacked4 = pickle.loads(pickle.dumps(unpacked3, proto)) 1980 self.assertIs(unpacked3, unpacked4) 1981 1982 @all_pickle_protocols 1983 def test_pickling_then_unpickling_tuple_with_typevartuple_equality( 1984 self, proto 1985 ): 1986 global global_T, global_Ts # See explanation at start of class. 1987 global_T = TypeVar('global_T') 1988 global_Ts = TypeVarTuple('global_Ts') 1989 1990 tuples = [ 1991 tuple[*global_Ts], 1992 Tuple[Unpack[global_Ts]], 1993 1994 tuple[T, *global_Ts], 1995 Tuple[T, Unpack[global_Ts]], 1996 1997 tuple[int, *global_Ts], 1998 Tuple[int, Unpack[global_Ts]], 1999 ] 2000 for t in tuples: 2001 t2 = pickle.loads(pickle.dumps(t, proto)) 2002 self.assertEqual(t, t2) 2003 2004 2005class UnionTests(BaseTestCase): 2006 2007 def test_basics(self): 2008 u = Union[int, float] 2009 self.assertNotEqual(u, Union) 2010 2011 def test_subclass_error(self): 2012 with self.assertRaises(TypeError): 2013 issubclass(int, Union) 2014 with self.assertRaises(TypeError): 2015 issubclass(Union, int) 2016 with self.assertRaises(TypeError): 2017 issubclass(Union[int, str], int) 2018 2019 def test_union_any(self): 2020 u = Union[Any] 2021 self.assertEqual(u, Any) 2022 u1 = Union[int, Any] 2023 u2 = Union[Any, int] 2024 u3 = Union[Any, object] 2025 self.assertEqual(u1, u2) 2026 self.assertNotEqual(u1, Any) 2027 self.assertNotEqual(u2, Any) 2028 self.assertNotEqual(u3, Any) 2029 2030 def test_union_object(self): 2031 u = Union[object] 2032 self.assertEqual(u, object) 2033 u1 = Union[int, object] 2034 u2 = Union[object, int] 2035 self.assertEqual(u1, u2) 2036 self.assertNotEqual(u1, object) 2037 self.assertNotEqual(u2, object) 2038 2039 def test_unordered(self): 2040 u1 = Union[int, float] 2041 u2 = Union[float, int] 2042 self.assertEqual(u1, u2) 2043 2044 def test_single_class_disappears(self): 2045 t = Union[Employee] 2046 self.assertIs(t, Employee) 2047 2048 def test_base_class_kept(self): 2049 u = Union[Employee, Manager] 2050 self.assertNotEqual(u, Employee) 2051 self.assertIn(Employee, u.__args__) 2052 self.assertIn(Manager, u.__args__) 2053 2054 def test_union_union(self): 2055 u = Union[int, float] 2056 v = Union[u, Employee] 2057 self.assertEqual(v, Union[int, float, Employee]) 2058 2059 def test_union_of_unhashable(self): 2060 class UnhashableMeta(type): 2061 __hash__ = None 2062 2063 class A(metaclass=UnhashableMeta): ... 2064 class B(metaclass=UnhashableMeta): ... 2065 2066 self.assertEqual(Union[A, B].__args__, (A, B)) 2067 union1 = Union[A, B] 2068 with self.assertRaises(TypeError): 2069 hash(union1) 2070 2071 union2 = Union[int, B] 2072 with self.assertRaises(TypeError): 2073 hash(union2) 2074 2075 union3 = Union[A, int] 2076 with self.assertRaises(TypeError): 2077 hash(union3) 2078 2079 def test_repr(self): 2080 self.assertEqual(repr(Union), 'typing.Union') 2081 u = Union[Employee, int] 2082 self.assertEqual(repr(u), 'typing.Union[%s.Employee, int]' % __name__) 2083 u = Union[int, Employee] 2084 self.assertEqual(repr(u), 'typing.Union[int, %s.Employee]' % __name__) 2085 T = TypeVar('T') 2086 u = Union[T, int][int] 2087 self.assertEqual(repr(u), repr(int)) 2088 u = Union[List[int], int] 2089 self.assertEqual(repr(u), 'typing.Union[typing.List[int], int]') 2090 u = Union[list[int], dict[str, float]] 2091 self.assertEqual(repr(u), 'typing.Union[list[int], dict[str, float]]') 2092 u = Union[int | float] 2093 self.assertEqual(repr(u), 'typing.Union[int, float]') 2094 2095 u = Union[None, str] 2096 self.assertEqual(repr(u), 'typing.Optional[str]') 2097 u = Union[str, None] 2098 self.assertEqual(repr(u), 'typing.Optional[str]') 2099 u = Union[None, str, int] 2100 self.assertEqual(repr(u), 'typing.Union[NoneType, str, int]') 2101 u = Optional[str] 2102 self.assertEqual(repr(u), 'typing.Optional[str]') 2103 2104 def test_dir(self): 2105 dir_items = set(dir(Union[str, int])) 2106 for required_item in [ 2107 '__args__', '__parameters__', '__origin__', 2108 ]: 2109 with self.subTest(required_item=required_item): 2110 self.assertIn(required_item, dir_items) 2111 2112 def test_cannot_subclass(self): 2113 with self.assertRaisesRegex(TypeError, 2114 r'Cannot subclass typing\.Union'): 2115 class C(Union): 2116 pass 2117 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 2118 class D(type(Union)): 2119 pass 2120 with self.assertRaisesRegex(TypeError, 2121 r'Cannot subclass typing\.Union\[int, str\]'): 2122 class E(Union[int, str]): 2123 pass 2124 2125 def test_cannot_instantiate(self): 2126 with self.assertRaises(TypeError): 2127 Union() 2128 with self.assertRaises(TypeError): 2129 type(Union)() 2130 u = Union[int, float] 2131 with self.assertRaises(TypeError): 2132 u() 2133 with self.assertRaises(TypeError): 2134 type(u)() 2135 2136 def test_union_generalization(self): 2137 self.assertFalse(Union[str, typing.Iterable[int]] == str) 2138 self.assertFalse(Union[str, typing.Iterable[int]] == typing.Iterable[int]) 2139 self.assertIn(str, Union[str, typing.Iterable[int]].__args__) 2140 self.assertIn(typing.Iterable[int], Union[str, typing.Iterable[int]].__args__) 2141 2142 def test_union_compare_other(self): 2143 self.assertNotEqual(Union, object) 2144 self.assertNotEqual(Union, Any) 2145 self.assertNotEqual(ClassVar, Union) 2146 self.assertNotEqual(Optional, Union) 2147 self.assertNotEqual([None], Optional) 2148 self.assertNotEqual(Optional, typing.Mapping) 2149 self.assertNotEqual(Optional[typing.MutableMapping], Union) 2150 2151 def test_optional(self): 2152 o = Optional[int] 2153 u = Union[int, None] 2154 self.assertEqual(o, u) 2155 2156 def test_empty(self): 2157 with self.assertRaises(TypeError): 2158 Union[()] 2159 2160 def test_no_eval_union(self): 2161 u = Union[int, str] 2162 def f(x: u): ... 2163 self.assertIs(get_type_hints(f)['x'], u) 2164 2165 def test_function_repr_union(self): 2166 def fun() -> int: ... 2167 self.assertEqual(repr(Union[fun, int]), 'typing.Union[fun, int]') 2168 2169 def test_union_str_pattern(self): 2170 # Shouldn't crash; see http://bugs.python.org/issue25390 2171 A = Union[str, Pattern] 2172 A 2173 2174 def test_etree(self): 2175 # See https://github.com/python/typing/issues/229 2176 # (Only relevant for Python 2.) 2177 from xml.etree.ElementTree import Element 2178 2179 Union[Element, str] # Shouldn't crash 2180 2181 def Elem(*args): 2182 return Element(*args) 2183 2184 Union[Elem, str] # Nor should this 2185 2186 def test_union_of_literals(self): 2187 self.assertEqual(Union[Literal[1], Literal[2]].__args__, 2188 (Literal[1], Literal[2])) 2189 self.assertEqual(Union[Literal[1], Literal[1]], 2190 Literal[1]) 2191 2192 self.assertEqual(Union[Literal[False], Literal[0]].__args__, 2193 (Literal[False], Literal[0])) 2194 self.assertEqual(Union[Literal[True], Literal[1]].__args__, 2195 (Literal[True], Literal[1])) 2196 2197 import enum 2198 class Ints(enum.IntEnum): 2199 A = 0 2200 B = 1 2201 2202 self.assertEqual(Union[Literal[Ints.A], Literal[Ints.A]], 2203 Literal[Ints.A]) 2204 self.assertEqual(Union[Literal[Ints.B], Literal[Ints.B]], 2205 Literal[Ints.B]) 2206 2207 self.assertEqual(Union[Literal[Ints.A], Literal[Ints.B]].__args__, 2208 (Literal[Ints.A], Literal[Ints.B])) 2209 2210 self.assertEqual(Union[Literal[0], Literal[Ints.A], Literal[False]].__args__, 2211 (Literal[0], Literal[Ints.A], Literal[False])) 2212 self.assertEqual(Union[Literal[1], Literal[Ints.B], Literal[True]].__args__, 2213 (Literal[1], Literal[Ints.B], Literal[True])) 2214 2215 2216class TupleTests(BaseTestCase): 2217 2218 def test_basics(self): 2219 with self.assertRaises(TypeError): 2220 issubclass(Tuple, Tuple[int, str]) 2221 with self.assertRaises(TypeError): 2222 issubclass(tuple, Tuple[int, str]) 2223 2224 class TP(tuple): ... 2225 self.assertIsSubclass(tuple, Tuple) 2226 self.assertIsSubclass(TP, Tuple) 2227 2228 def test_equality(self): 2229 self.assertEqual(Tuple[int], Tuple[int]) 2230 self.assertEqual(Tuple[int, ...], Tuple[int, ...]) 2231 self.assertNotEqual(Tuple[int], Tuple[int, int]) 2232 self.assertNotEqual(Tuple[int], Tuple[int, ...]) 2233 2234 def test_tuple_subclass(self): 2235 class MyTuple(tuple): 2236 pass 2237 self.assertIsSubclass(MyTuple, Tuple) 2238 self.assertIsSubclass(Tuple, Tuple) 2239 self.assertIsSubclass(tuple, Tuple) 2240 2241 def test_tuple_instance_type_error(self): 2242 with self.assertRaises(TypeError): 2243 isinstance((0, 0), Tuple[int, int]) 2244 self.assertIsInstance((0, 0), Tuple) 2245 2246 def test_repr(self): 2247 self.assertEqual(repr(Tuple), 'typing.Tuple') 2248 self.assertEqual(repr(Tuple[()]), 'typing.Tuple[()]') 2249 self.assertEqual(repr(Tuple[int, float]), 'typing.Tuple[int, float]') 2250 self.assertEqual(repr(Tuple[int, ...]), 'typing.Tuple[int, ...]') 2251 self.assertEqual(repr(Tuple[list[int]]), 'typing.Tuple[list[int]]') 2252 2253 def test_errors(self): 2254 with self.assertRaises(TypeError): 2255 issubclass(42, Tuple) 2256 with self.assertRaises(TypeError): 2257 issubclass(42, Tuple[int]) 2258 2259 2260class BaseCallableTests: 2261 2262 def test_self_subclass(self): 2263 Callable = self.Callable 2264 with self.assertRaises(TypeError): 2265 issubclass(types.FunctionType, Callable[[int], int]) 2266 self.assertIsSubclass(types.FunctionType, Callable) 2267 self.assertIsSubclass(Callable, Callable) 2268 2269 def test_eq_hash(self): 2270 Callable = self.Callable 2271 C = Callable[[int], int] 2272 self.assertEqual(C, Callable[[int], int]) 2273 self.assertEqual(len({C, Callable[[int], int]}), 1) 2274 self.assertNotEqual(C, Callable[[int], str]) 2275 self.assertNotEqual(C, Callable[[str], int]) 2276 self.assertNotEqual(C, Callable[[int, int], int]) 2277 self.assertNotEqual(C, Callable[[], int]) 2278 self.assertNotEqual(C, Callable[..., int]) 2279 self.assertNotEqual(C, Callable) 2280 2281 def test_dir(self): 2282 Callable = self.Callable 2283 dir_items = set(dir(Callable[..., int])) 2284 for required_item in [ 2285 '__args__', '__parameters__', '__origin__', 2286 ]: 2287 with self.subTest(required_item=required_item): 2288 self.assertIn(required_item, dir_items) 2289 2290 def test_cannot_instantiate(self): 2291 Callable = self.Callable 2292 with self.assertRaises(TypeError): 2293 Callable() 2294 with self.assertRaises(TypeError): 2295 type(Callable)() 2296 c = Callable[[int], str] 2297 with self.assertRaises(TypeError): 2298 c() 2299 with self.assertRaises(TypeError): 2300 type(c)() 2301 2302 def test_callable_wrong_forms(self): 2303 Callable = self.Callable 2304 with self.assertRaises(TypeError): 2305 Callable[int] 2306 2307 def test_callable_instance_works(self): 2308 Callable = self.Callable 2309 def f(): 2310 pass 2311 self.assertIsInstance(f, Callable) 2312 self.assertNotIsInstance(None, Callable) 2313 2314 def test_callable_instance_type_error(self): 2315 Callable = self.Callable 2316 def f(): 2317 pass 2318 with self.assertRaises(TypeError): 2319 isinstance(f, Callable[[], None]) 2320 with self.assertRaises(TypeError): 2321 isinstance(f, Callable[[], Any]) 2322 with self.assertRaises(TypeError): 2323 isinstance(None, Callable[[], None]) 2324 with self.assertRaises(TypeError): 2325 isinstance(None, Callable[[], Any]) 2326 2327 def test_repr(self): 2328 Callable = self.Callable 2329 fullname = f'{Callable.__module__}.Callable' 2330 ct0 = Callable[[], bool] 2331 self.assertEqual(repr(ct0), f'{fullname}[[], bool]') 2332 ct2 = Callable[[str, float], int] 2333 self.assertEqual(repr(ct2), f'{fullname}[[str, float], int]') 2334 ctv = Callable[..., str] 2335 self.assertEqual(repr(ctv), f'{fullname}[..., str]') 2336 ct3 = Callable[[str, float], list[int]] 2337 self.assertEqual(repr(ct3), f'{fullname}[[str, float], list[int]]') 2338 2339 def test_callable_with_ellipsis(self): 2340 Callable = self.Callable 2341 def foo(a: Callable[..., T]): 2342 pass 2343 2344 self.assertEqual(get_type_hints(foo, globals(), locals()), 2345 {'a': Callable[..., T]}) 2346 2347 def test_ellipsis_in_generic(self): 2348 Callable = self.Callable 2349 # Shouldn't crash; see https://github.com/python/typing/issues/259 2350 typing.List[Callable[..., str]] 2351 2352 def test_or_and_ror(self): 2353 Callable = self.Callable 2354 self.assertEqual(Callable | Tuple, Union[Callable, Tuple]) 2355 self.assertEqual(Tuple | Callable, Union[Tuple, Callable]) 2356 2357 def test_basic(self): 2358 Callable = self.Callable 2359 alias = Callable[[int, str], float] 2360 if Callable is collections.abc.Callable: 2361 self.assertIsInstance(alias, types.GenericAlias) 2362 self.assertIs(alias.__origin__, collections.abc.Callable) 2363 self.assertEqual(alias.__args__, (int, str, float)) 2364 self.assertEqual(alias.__parameters__, ()) 2365 2366 def test_weakref(self): 2367 Callable = self.Callable 2368 alias = Callable[[int, str], float] 2369 self.assertEqual(weakref.ref(alias)(), alias) 2370 2371 def test_pickle(self): 2372 global T_pickle, P_pickle, TS_pickle # needed for pickling 2373 Callable = self.Callable 2374 T_pickle = TypeVar('T_pickle') 2375 P_pickle = ParamSpec('P_pickle') 2376 TS_pickle = TypeVarTuple('TS_pickle') 2377 2378 samples = [ 2379 Callable[[int, str], float], 2380 Callable[P_pickle, int], 2381 Callable[P_pickle, T_pickle], 2382 Callable[Concatenate[int, P_pickle], int], 2383 Callable[Concatenate[*TS_pickle, P_pickle], int], 2384 ] 2385 for alias in samples: 2386 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 2387 with self.subTest(alias=alias, proto=proto): 2388 s = pickle.dumps(alias, proto) 2389 loaded = pickle.loads(s) 2390 self.assertEqual(alias.__origin__, loaded.__origin__) 2391 self.assertEqual(alias.__args__, loaded.__args__) 2392 self.assertEqual(alias.__parameters__, loaded.__parameters__) 2393 2394 del T_pickle, P_pickle, TS_pickle # cleaning up global state 2395 2396 def test_var_substitution(self): 2397 Callable = self.Callable 2398 fullname = f"{Callable.__module__}.Callable" 2399 C1 = Callable[[int, T], T] 2400 C2 = Callable[[KT, T], VT] 2401 C3 = Callable[..., T] 2402 self.assertEqual(C1[str], Callable[[int, str], str]) 2403 self.assertEqual(C1[None], Callable[[int, type(None)], type(None)]) 2404 self.assertEqual(C2[int, float, str], Callable[[int, float], str]) 2405 self.assertEqual(C3[int], Callable[..., int]) 2406 self.assertEqual(C3[NoReturn], Callable[..., NoReturn]) 2407 2408 # multi chaining 2409 C4 = C2[int, VT, str] 2410 self.assertEqual(repr(C4), f"{fullname}[[int, ~VT], str]") 2411 self.assertEqual(repr(C4[dict]), f"{fullname}[[int, dict], str]") 2412 self.assertEqual(C4[dict], Callable[[int, dict], str]) 2413 2414 # substitute a nested GenericAlias (both typing and the builtin 2415 # version) 2416 C5 = Callable[[typing.List[T], tuple[KT, T], VT], int] 2417 self.assertEqual(C5[int, str, float], 2418 Callable[[typing.List[int], tuple[str, int], float], int]) 2419 2420 def test_type_subst_error(self): 2421 Callable = self.Callable 2422 P = ParamSpec('P') 2423 T = TypeVar('T') 2424 2425 pat = "Expected a list of types, an ellipsis, ParamSpec, or Concatenate." 2426 2427 with self.assertRaisesRegex(TypeError, pat): 2428 Callable[P, T][0, int] 2429 2430 def test_type_erasure(self): 2431 Callable = self.Callable 2432 class C1(Callable): 2433 def __call__(self): 2434 return None 2435 a = C1[[int], T] 2436 self.assertIs(a().__class__, C1) 2437 self.assertEqual(a().__orig_class__, C1[[int], T]) 2438 2439 def test_paramspec(self): 2440 Callable = self.Callable 2441 fullname = f"{Callable.__module__}.Callable" 2442 P = ParamSpec('P') 2443 P2 = ParamSpec('P2') 2444 C1 = Callable[P, T] 2445 # substitution 2446 self.assertEqual(C1[[int], str], Callable[[int], str]) 2447 self.assertEqual(C1[[int, str], str], Callable[[int, str], str]) 2448 self.assertEqual(C1[[], str], Callable[[], str]) 2449 self.assertEqual(C1[..., str], Callable[..., str]) 2450 self.assertEqual(C1[P2, str], Callable[P2, str]) 2451 self.assertEqual(C1[Concatenate[int, P2], str], 2452 Callable[Concatenate[int, P2], str]) 2453 self.assertEqual(repr(C1), f"{fullname}[~P, ~T]") 2454 self.assertEqual(repr(C1[[int, str], str]), f"{fullname}[[int, str], str]") 2455 with self.assertRaises(TypeError): 2456 C1[int, str] 2457 2458 C2 = Callable[P, int] 2459 self.assertEqual(C2[[int]], Callable[[int], int]) 2460 self.assertEqual(C2[[int, str]], Callable[[int, str], int]) 2461 self.assertEqual(C2[[]], Callable[[], int]) 2462 self.assertEqual(C2[...], Callable[..., int]) 2463 self.assertEqual(C2[P2], Callable[P2, int]) 2464 self.assertEqual(C2[Concatenate[int, P2]], 2465 Callable[Concatenate[int, P2], int]) 2466 # special case in PEP 612 where 2467 # X[int, str, float] == X[[int, str, float]] 2468 self.assertEqual(C2[int], Callable[[int], int]) 2469 self.assertEqual(C2[int, str], Callable[[int, str], int]) 2470 self.assertEqual(repr(C2), f"{fullname}[~P, int]") 2471 self.assertEqual(repr(C2[int, str]), f"{fullname}[[int, str], int]") 2472 2473 def test_concatenate(self): 2474 Callable = self.Callable 2475 fullname = f"{Callable.__module__}.Callable" 2476 T = TypeVar('T') 2477 P = ParamSpec('P') 2478 P2 = ParamSpec('P2') 2479 C = Callable[Concatenate[int, P], T] 2480 self.assertEqual(repr(C), 2481 f"{fullname}[typing.Concatenate[int, ~P], ~T]") 2482 self.assertEqual(C[P2, int], Callable[Concatenate[int, P2], int]) 2483 self.assertEqual(C[[str, float], int], Callable[[int, str, float], int]) 2484 self.assertEqual(C[[], int], Callable[[int], int]) 2485 self.assertEqual(C[Concatenate[str, P2], int], 2486 Callable[Concatenate[int, str, P2], int]) 2487 self.assertEqual(C[..., int], Callable[Concatenate[int, ...], int]) 2488 2489 C = Callable[Concatenate[int, P], int] 2490 self.assertEqual(repr(C), 2491 f"{fullname}[typing.Concatenate[int, ~P], int]") 2492 self.assertEqual(C[P2], Callable[Concatenate[int, P2], int]) 2493 self.assertEqual(C[[str, float]], Callable[[int, str, float], int]) 2494 self.assertEqual(C[str, float], Callable[[int, str, float], int]) 2495 self.assertEqual(C[[]], Callable[[int], int]) 2496 self.assertEqual(C[Concatenate[str, P2]], 2497 Callable[Concatenate[int, str, P2], int]) 2498 self.assertEqual(C[...], Callable[Concatenate[int, ...], int]) 2499 2500 def test_nested_paramspec(self): 2501 # Since Callable has some special treatment, we want to be sure 2502 # that substituion works correctly, see gh-103054 2503 Callable = self.Callable 2504 P = ParamSpec('P') 2505 P2 = ParamSpec('P2') 2506 T = TypeVar('T') 2507 T2 = TypeVar('T2') 2508 Ts = TypeVarTuple('Ts') 2509 class My(Generic[P, T]): 2510 pass 2511 2512 self.assertEqual(My.__parameters__, (P, T)) 2513 2514 C1 = My[[int, T2], Callable[P2, T2]] 2515 self.assertEqual(C1.__args__, ((int, T2), Callable[P2, T2])) 2516 self.assertEqual(C1.__parameters__, (T2, P2)) 2517 self.assertEqual(C1[str, [list[int], bytes]], 2518 My[[int, str], Callable[[list[int], bytes], str]]) 2519 2520 C2 = My[[Callable[[T2], int], list[T2]], str] 2521 self.assertEqual(C2.__args__, ((Callable[[T2], int], list[T2]), str)) 2522 self.assertEqual(C2.__parameters__, (T2,)) 2523 self.assertEqual(C2[list[str]], 2524 My[[Callable[[list[str]], int], list[list[str]]], str]) 2525 2526 C3 = My[[Callable[P2, T2], T2], T2] 2527 self.assertEqual(C3.__args__, ((Callable[P2, T2], T2), T2)) 2528 self.assertEqual(C3.__parameters__, (P2, T2)) 2529 self.assertEqual(C3[[], int], 2530 My[[Callable[[], int], int], int]) 2531 self.assertEqual(C3[[str, bool], int], 2532 My[[Callable[[str, bool], int], int], int]) 2533 self.assertEqual(C3[[str, bool], T][int], 2534 My[[Callable[[str, bool], int], int], int]) 2535 2536 C4 = My[[Callable[[int, *Ts, str], T2], T2], T2] 2537 self.assertEqual(C4.__args__, ((Callable[[int, *Ts, str], T2], T2), T2)) 2538 self.assertEqual(C4.__parameters__, (Ts, T2)) 2539 self.assertEqual(C4[bool, bytes, float], 2540 My[[Callable[[int, bool, bytes, str], float], float], float]) 2541 2542 def test_errors(self): 2543 Callable = self.Callable 2544 alias = Callable[[int, str], float] 2545 with self.assertRaisesRegex(TypeError, "is not a generic class"): 2546 alias[int] 2547 P = ParamSpec('P') 2548 C1 = Callable[P, T] 2549 with self.assertRaisesRegex(TypeError, "many arguments for"): 2550 C1[int, str, str] 2551 with self.assertRaisesRegex(TypeError, "few arguments for"): 2552 C1[int] 2553 2554class TypingCallableTests(BaseCallableTests, BaseTestCase): 2555 Callable = typing.Callable 2556 2557 def test_consistency(self): 2558 # bpo-42195 2559 # Testing collections.abc.Callable's consistency with typing.Callable 2560 c1 = typing.Callable[[int, str], dict] 2561 c2 = collections.abc.Callable[[int, str], dict] 2562 self.assertEqual(c1.__args__, c2.__args__) 2563 self.assertEqual(hash(c1.__args__), hash(c2.__args__)) 2564 2565 2566class CollectionsCallableTests(BaseCallableTests, BaseTestCase): 2567 Callable = collections.abc.Callable 2568 2569 2570class LiteralTests(BaseTestCase): 2571 def test_basics(self): 2572 # All of these are allowed. 2573 Literal[1] 2574 Literal[1, 2, 3] 2575 Literal["x", "y", "z"] 2576 Literal[None] 2577 Literal[True] 2578 Literal[1, "2", False] 2579 Literal[Literal[1, 2], Literal[4, 5]] 2580 Literal[b"foo", u"bar"] 2581 2582 def test_enum(self): 2583 import enum 2584 class My(enum.Enum): 2585 A = 'A' 2586 2587 self.assertEqual(Literal[My.A].__args__, (My.A,)) 2588 2589 def test_illegal_parameters_do_not_raise_runtime_errors(self): 2590 # Type checkers should reject these types, but we do not 2591 # raise errors at runtime to maintain maximum flexibility. 2592 Literal[int] 2593 Literal[3j + 2, ..., ()] 2594 Literal[{"foo": 3, "bar": 4}] 2595 Literal[T] 2596 2597 def test_literals_inside_other_types(self): 2598 List[Literal[1, 2, 3]] 2599 List[Literal[("foo", "bar", "baz")]] 2600 2601 def test_repr(self): 2602 self.assertEqual(repr(Literal[1]), "typing.Literal[1]") 2603 self.assertEqual(repr(Literal[1, True, "foo"]), "typing.Literal[1, True, 'foo']") 2604 self.assertEqual(repr(Literal[int]), "typing.Literal[int]") 2605 self.assertEqual(repr(Literal), "typing.Literal") 2606 self.assertEqual(repr(Literal[None]), "typing.Literal[None]") 2607 self.assertEqual(repr(Literal[1, 2, 3, 3]), "typing.Literal[1, 2, 3]") 2608 2609 def test_dir(self): 2610 dir_items = set(dir(Literal[1, 2, 3])) 2611 for required_item in [ 2612 '__args__', '__parameters__', '__origin__', 2613 ]: 2614 with self.subTest(required_item=required_item): 2615 self.assertIn(required_item, dir_items) 2616 2617 def test_cannot_init(self): 2618 with self.assertRaises(TypeError): 2619 Literal() 2620 with self.assertRaises(TypeError): 2621 Literal[1]() 2622 with self.assertRaises(TypeError): 2623 type(Literal)() 2624 with self.assertRaises(TypeError): 2625 type(Literal[1])() 2626 2627 def test_no_isinstance_or_issubclass(self): 2628 with self.assertRaises(TypeError): 2629 isinstance(1, Literal[1]) 2630 with self.assertRaises(TypeError): 2631 isinstance(int, Literal[1]) 2632 with self.assertRaises(TypeError): 2633 issubclass(1, Literal[1]) 2634 with self.assertRaises(TypeError): 2635 issubclass(int, Literal[1]) 2636 2637 def test_no_subclassing(self): 2638 with self.assertRaises(TypeError): 2639 class Foo(Literal[1]): pass 2640 with self.assertRaises(TypeError): 2641 class Bar(Literal): pass 2642 2643 def test_no_multiple_subscripts(self): 2644 with self.assertRaises(TypeError): 2645 Literal[1][1] 2646 2647 def test_equal(self): 2648 self.assertNotEqual(Literal[0], Literal[False]) 2649 self.assertNotEqual(Literal[True], Literal[1]) 2650 self.assertNotEqual(Literal[1], Literal[2]) 2651 self.assertNotEqual(Literal[1, True], Literal[1]) 2652 self.assertNotEqual(Literal[1, True], Literal[1, 1]) 2653 self.assertNotEqual(Literal[1, 2], Literal[True, 2]) 2654 self.assertEqual(Literal[1], Literal[1]) 2655 self.assertEqual(Literal[1, 2], Literal[2, 1]) 2656 self.assertEqual(Literal[1, 2, 3], Literal[1, 2, 3, 3]) 2657 2658 def test_hash(self): 2659 self.assertEqual(hash(Literal[1]), hash(Literal[1])) 2660 self.assertEqual(hash(Literal[1, 2]), hash(Literal[2, 1])) 2661 self.assertEqual(hash(Literal[1, 2, 3]), hash(Literal[1, 2, 3, 3])) 2662 2663 def test_args(self): 2664 self.assertEqual(Literal[1, 2, 3].__args__, (1, 2, 3)) 2665 self.assertEqual(Literal[1, 2, 3, 3].__args__, (1, 2, 3)) 2666 self.assertEqual(Literal[1, Literal[2], Literal[3, 4]].__args__, (1, 2, 3, 4)) 2667 # Mutable arguments will not be deduplicated 2668 self.assertEqual(Literal[[], []].__args__, ([], [])) 2669 2670 def test_flatten(self): 2671 l1 = Literal[Literal[1], Literal[2], Literal[3]] 2672 l2 = Literal[Literal[1, 2], 3] 2673 l3 = Literal[Literal[1, 2, 3]] 2674 for l in l1, l2, l3: 2675 self.assertEqual(l, Literal[1, 2, 3]) 2676 self.assertEqual(l.__args__, (1, 2, 3)) 2677 2678 def test_does_not_flatten_enum(self): 2679 import enum 2680 class Ints(enum.IntEnum): 2681 A = 1 2682 B = 2 2683 2684 l = Literal[ 2685 Literal[Ints.A], 2686 Literal[Ints.B], 2687 Literal[1], 2688 Literal[2], 2689 ] 2690 self.assertEqual(l.__args__, (Ints.A, Ints.B, 1, 2)) 2691 2692 2693XK = TypeVar('XK', str, bytes) 2694XV = TypeVar('XV') 2695 2696 2697class SimpleMapping(Generic[XK, XV]): 2698 2699 def __getitem__(self, key: XK) -> XV: 2700 ... 2701 2702 def __setitem__(self, key: XK, value: XV): 2703 ... 2704 2705 def get(self, key: XK, default: XV = None) -> XV: 2706 ... 2707 2708 2709class MySimpleMapping(SimpleMapping[XK, XV]): 2710 2711 def __init__(self): 2712 self.store = {} 2713 2714 def __getitem__(self, key: str): 2715 return self.store[key] 2716 2717 def __setitem__(self, key: str, value): 2718 self.store[key] = value 2719 2720 def get(self, key: str, default=None): 2721 try: 2722 return self.store[key] 2723 except KeyError: 2724 return default 2725 2726 2727class Coordinate(Protocol): 2728 x: int 2729 y: int 2730 2731@runtime_checkable 2732class Point(Coordinate, Protocol): 2733 label: str 2734 2735class MyPoint: 2736 x: int 2737 y: int 2738 label: str 2739 2740class XAxis(Protocol): 2741 x: int 2742 2743class YAxis(Protocol): 2744 y: int 2745 2746@runtime_checkable 2747class Position(XAxis, YAxis, Protocol): 2748 pass 2749 2750@runtime_checkable 2751class Proto(Protocol): 2752 attr: int 2753 def meth(self, arg: str) -> int: 2754 ... 2755 2756class Concrete(Proto): 2757 pass 2758 2759class Other: 2760 attr: int = 1 2761 def meth(self, arg: str) -> int: 2762 if arg == 'this': 2763 return 1 2764 return 0 2765 2766class NT(NamedTuple): 2767 x: int 2768 y: int 2769 2770@runtime_checkable 2771class HasCallProtocol(Protocol): 2772 __call__: typing.Callable 2773 2774 2775class ProtocolTests(BaseTestCase): 2776 def test_basic_protocol(self): 2777 @runtime_checkable 2778 class P(Protocol): 2779 def meth(self): 2780 pass 2781 2782 class C: pass 2783 2784 class D: 2785 def meth(self): 2786 pass 2787 2788 def f(): 2789 pass 2790 2791 self.assertIsSubclass(D, P) 2792 self.assertIsInstance(D(), P) 2793 self.assertNotIsSubclass(C, P) 2794 self.assertNotIsInstance(C(), P) 2795 self.assertNotIsSubclass(types.FunctionType, P) 2796 self.assertNotIsInstance(f, P) 2797 2798 def test_runtime_checkable_generic_non_protocol(self): 2799 # Make sure this doesn't raise AttributeError 2800 with self.assertRaisesRegex( 2801 TypeError, 2802 "@runtime_checkable can be only applied to protocol classes", 2803 ): 2804 @runtime_checkable 2805 class Foo[T]: ... 2806 2807 def test_runtime_checkable_generic(self): 2808 @runtime_checkable 2809 class Foo[T](Protocol): 2810 def meth(self) -> T: ... 2811 2812 class Impl: 2813 def meth(self) -> int: ... 2814 2815 self.assertIsSubclass(Impl, Foo) 2816 2817 class NotImpl: 2818 def method(self) -> int: ... 2819 2820 self.assertNotIsSubclass(NotImpl, Foo) 2821 2822 def test_pep695_generics_can_be_runtime_checkable(self): 2823 @runtime_checkable 2824 class HasX(Protocol): 2825 x: int 2826 2827 class Bar[T]: 2828 x: T 2829 def __init__(self, x): 2830 self.x = x 2831 2832 class Capybara[T]: 2833 y: str 2834 def __init__(self, y): 2835 self.y = y 2836 2837 self.assertIsInstance(Bar(1), HasX) 2838 self.assertNotIsInstance(Capybara('a'), HasX) 2839 2840 def test_everything_implements_empty_protocol(self): 2841 @runtime_checkable 2842 class Empty(Protocol): 2843 pass 2844 2845 class C: 2846 pass 2847 2848 def f(): 2849 pass 2850 2851 for thing in (object, type, tuple, C, types.FunctionType): 2852 self.assertIsSubclass(thing, Empty) 2853 for thing in (object(), 1, (), typing, f): 2854 self.assertIsInstance(thing, Empty) 2855 2856 def test_function_implements_protocol(self): 2857 def f(): 2858 pass 2859 2860 self.assertIsInstance(f, HasCallProtocol) 2861 2862 def test_no_inheritance_from_nominal(self): 2863 class C: pass 2864 2865 class BP(Protocol): pass 2866 2867 with self.assertRaises(TypeError): 2868 class P(C, Protocol): 2869 pass 2870 with self.assertRaises(TypeError): 2871 class Q(Protocol, C): 2872 pass 2873 with self.assertRaises(TypeError): 2874 class R(BP, C, Protocol): 2875 pass 2876 2877 class D(BP, C): pass 2878 2879 class E(C, BP): pass 2880 2881 self.assertNotIsInstance(D(), E) 2882 self.assertNotIsInstance(E(), D) 2883 2884 def test_no_instantiation(self): 2885 class P(Protocol): pass 2886 2887 with self.assertRaises(TypeError): 2888 P() 2889 2890 class C(P): pass 2891 2892 self.assertIsInstance(C(), C) 2893 with self.assertRaises(TypeError): 2894 C(42) 2895 2896 T = TypeVar('T') 2897 2898 class PG(Protocol[T]): pass 2899 2900 with self.assertRaises(TypeError): 2901 PG() 2902 with self.assertRaises(TypeError): 2903 PG[int]() 2904 with self.assertRaises(TypeError): 2905 PG[T]() 2906 2907 class CG(PG[T]): pass 2908 2909 self.assertIsInstance(CG[int](), CG) 2910 with self.assertRaises(TypeError): 2911 CG[int](42) 2912 2913 def test_protocol_defining_init_does_not_get_overridden(self): 2914 # check that P.__init__ doesn't get clobbered 2915 # see https://bugs.python.org/issue44807 2916 2917 class P(Protocol): 2918 x: int 2919 def __init__(self, x: int) -> None: 2920 self.x = x 2921 class C: pass 2922 2923 c = C() 2924 P.__init__(c, 1) 2925 self.assertEqual(c.x, 1) 2926 2927 def test_concrete_class_inheriting_init_from_protocol(self): 2928 class P(Protocol): 2929 x: int 2930 def __init__(self, x: int) -> None: 2931 self.x = x 2932 2933 class C(P): pass 2934 2935 c = C(1) 2936 self.assertIsInstance(c, C) 2937 self.assertEqual(c.x, 1) 2938 2939 def test_cannot_instantiate_abstract(self): 2940 @runtime_checkable 2941 class P(Protocol): 2942 @abc.abstractmethod 2943 def ameth(self) -> int: 2944 raise NotImplementedError 2945 2946 class B(P): 2947 pass 2948 2949 class C(B): 2950 def ameth(self) -> int: 2951 return 26 2952 2953 with self.assertRaises(TypeError): 2954 B() 2955 self.assertIsInstance(C(), P) 2956 2957 def test_subprotocols_extending(self): 2958 class P1(Protocol): 2959 def meth1(self): 2960 pass 2961 2962 @runtime_checkable 2963 class P2(P1, Protocol): 2964 def meth2(self): 2965 pass 2966 2967 class C: 2968 def meth1(self): 2969 pass 2970 2971 def meth2(self): 2972 pass 2973 2974 class C1: 2975 def meth1(self): 2976 pass 2977 2978 class C2: 2979 def meth2(self): 2980 pass 2981 2982 self.assertNotIsInstance(C1(), P2) 2983 self.assertNotIsInstance(C2(), P2) 2984 self.assertNotIsSubclass(C1, P2) 2985 self.assertNotIsSubclass(C2, P2) 2986 self.assertIsInstance(C(), P2) 2987 self.assertIsSubclass(C, P2) 2988 2989 def test_subprotocols_merging(self): 2990 class P1(Protocol): 2991 def meth1(self): 2992 pass 2993 2994 class P2(Protocol): 2995 def meth2(self): 2996 pass 2997 2998 @runtime_checkable 2999 class P(P1, P2, Protocol): 3000 pass 3001 3002 class C: 3003 def meth1(self): 3004 pass 3005 3006 def meth2(self): 3007 pass 3008 3009 class C1: 3010 def meth1(self): 3011 pass 3012 3013 class C2: 3014 def meth2(self): 3015 pass 3016 3017 self.assertNotIsInstance(C1(), P) 3018 self.assertNotIsInstance(C2(), P) 3019 self.assertNotIsSubclass(C1, P) 3020 self.assertNotIsSubclass(C2, P) 3021 self.assertIsInstance(C(), P) 3022 self.assertIsSubclass(C, P) 3023 3024 def test_protocols_issubclass(self): 3025 T = TypeVar('T') 3026 3027 @runtime_checkable 3028 class P(Protocol): 3029 def x(self): ... 3030 3031 @runtime_checkable 3032 class PG(Protocol[T]): 3033 def x(self): ... 3034 3035 class BadP(Protocol): 3036 def x(self): ... 3037 3038 class BadPG(Protocol[T]): 3039 def x(self): ... 3040 3041 class C: 3042 def x(self): ... 3043 3044 self.assertIsSubclass(C, P) 3045 self.assertIsSubclass(C, PG) 3046 self.assertIsSubclass(BadP, PG) 3047 3048 no_subscripted_generics = ( 3049 "Subscripted generics cannot be used with class and instance checks" 3050 ) 3051 3052 with self.assertRaisesRegex(TypeError, no_subscripted_generics): 3053 issubclass(C, PG[T]) 3054 with self.assertRaisesRegex(TypeError, no_subscripted_generics): 3055 issubclass(C, PG[C]) 3056 3057 only_runtime_checkable_protocols = ( 3058 "Instance and class checks can only be used with " 3059 "@runtime_checkable protocols" 3060 ) 3061 3062 with self.assertRaisesRegex(TypeError, only_runtime_checkable_protocols): 3063 issubclass(C, BadP) 3064 with self.assertRaisesRegex(TypeError, only_runtime_checkable_protocols): 3065 issubclass(C, BadPG) 3066 3067 with self.assertRaisesRegex(TypeError, no_subscripted_generics): 3068 issubclass(P, PG[T]) 3069 with self.assertRaisesRegex(TypeError, no_subscripted_generics): 3070 issubclass(PG, PG[int]) 3071 3072 only_classes_allowed = r"issubclass\(\) arg 1 must be a class" 3073 3074 with self.assertRaisesRegex(TypeError, only_classes_allowed): 3075 issubclass(1, P) 3076 with self.assertRaisesRegex(TypeError, only_classes_allowed): 3077 issubclass(1, PG) 3078 with self.assertRaisesRegex(TypeError, only_classes_allowed): 3079 issubclass(1, BadP) 3080 with self.assertRaisesRegex(TypeError, only_classes_allowed): 3081 issubclass(1, BadPG) 3082 3083 def test_implicit_issubclass_between_two_protocols(self): 3084 @runtime_checkable 3085 class CallableMembersProto(Protocol): 3086 def meth(self): ... 3087 3088 # All the below protocols should be considered "subclasses" 3089 # of CallableMembersProto at runtime, 3090 # even though none of them explicitly subclass CallableMembersProto 3091 3092 class IdenticalProto(Protocol): 3093 def meth(self): ... 3094 3095 class SupersetProto(Protocol): 3096 def meth(self): ... 3097 def meth2(self): ... 3098 3099 class NonCallableMembersProto(Protocol): 3100 meth: Callable[[], None] 3101 3102 class NonCallableMembersSupersetProto(Protocol): 3103 meth: Callable[[], None] 3104 meth2: Callable[[str, int], bool] 3105 3106 class MixedMembersProto1(Protocol): 3107 meth: Callable[[], None] 3108 def meth2(self): ... 3109 3110 class MixedMembersProto2(Protocol): 3111 def meth(self): ... 3112 meth2: Callable[[str, int], bool] 3113 3114 for proto in ( 3115 IdenticalProto, SupersetProto, NonCallableMembersProto, 3116 NonCallableMembersSupersetProto, MixedMembersProto1, MixedMembersProto2 3117 ): 3118 with self.subTest(proto=proto.__name__): 3119 self.assertIsSubclass(proto, CallableMembersProto) 3120 3121 # These two shouldn't be considered subclasses of CallableMembersProto, however, 3122 # since they don't have the `meth` protocol member 3123 3124 class EmptyProtocol(Protocol): ... 3125 class UnrelatedProtocol(Protocol): 3126 def wut(self): ... 3127 3128 self.assertNotIsSubclass(EmptyProtocol, CallableMembersProto) 3129 self.assertNotIsSubclass(UnrelatedProtocol, CallableMembersProto) 3130 3131 # These aren't protocols at all (despite having annotations), 3132 # so they should only be considered subclasses of CallableMembersProto 3133 # if they *actually have an attribute* matching the `meth` member 3134 # (just having an annotation is insufficient) 3135 3136 class AnnotatedButNotAProtocol: 3137 meth: Callable[[], None] 3138 3139 class NotAProtocolButAnImplicitSubclass: 3140 def meth(self): pass 3141 3142 class NotAProtocolButAnImplicitSubclass2: 3143 meth: Callable[[], None] 3144 def meth(self): pass 3145 3146 class NotAProtocolButAnImplicitSubclass3: 3147 meth: Callable[[], None] 3148 meth2: Callable[[int, str], bool] 3149 def meth(self): pass 3150 def meth2(self, x, y): return True 3151 3152 self.assertNotIsSubclass(AnnotatedButNotAProtocol, CallableMembersProto) 3153 self.assertIsSubclass(NotAProtocolButAnImplicitSubclass, CallableMembersProto) 3154 self.assertIsSubclass(NotAProtocolButAnImplicitSubclass2, CallableMembersProto) 3155 self.assertIsSubclass(NotAProtocolButAnImplicitSubclass3, CallableMembersProto) 3156 3157 def test_isinstance_checks_not_at_whim_of_gc(self): 3158 self.addCleanup(gc.enable) 3159 gc.disable() 3160 3161 with self.assertRaisesRegex( 3162 TypeError, 3163 "Protocols can only inherit from other protocols" 3164 ): 3165 class Foo(collections.abc.Mapping, Protocol): 3166 pass 3167 3168 self.assertNotIsInstance([], collections.abc.Mapping) 3169 3170 def test_issubclass_and_isinstance_on_Protocol_itself(self): 3171 class C: 3172 def x(self): pass 3173 3174 self.assertNotIsSubclass(object, Protocol) 3175 self.assertNotIsInstance(object(), Protocol) 3176 3177 self.assertNotIsSubclass(str, Protocol) 3178 self.assertNotIsInstance('foo', Protocol) 3179 3180 self.assertNotIsSubclass(C, Protocol) 3181 self.assertNotIsInstance(C(), Protocol) 3182 3183 only_classes_allowed = r"issubclass\(\) arg 1 must be a class" 3184 3185 with self.assertRaisesRegex(TypeError, only_classes_allowed): 3186 issubclass(1, Protocol) 3187 with self.assertRaisesRegex(TypeError, only_classes_allowed): 3188 issubclass('foo', Protocol) 3189 with self.assertRaisesRegex(TypeError, only_classes_allowed): 3190 issubclass(C(), Protocol) 3191 3192 T = TypeVar('T') 3193 3194 @runtime_checkable 3195 class EmptyProtocol(Protocol): pass 3196 3197 @runtime_checkable 3198 class SupportsStartsWith(Protocol): 3199 def startswith(self, x: str) -> bool: ... 3200 3201 @runtime_checkable 3202 class SupportsX(Protocol[T]): 3203 def x(self): ... 3204 3205 for proto in EmptyProtocol, SupportsStartsWith, SupportsX: 3206 with self.subTest(proto=proto.__name__): 3207 self.assertIsSubclass(proto, Protocol) 3208 3209 # gh-105237 / PR #105239: 3210 # check that the presence of Protocol subclasses 3211 # where `issubclass(X, <subclass>)` evaluates to True 3212 # doesn't influence the result of `issubclass(X, Protocol)` 3213 3214 self.assertIsSubclass(object, EmptyProtocol) 3215 self.assertIsInstance(object(), EmptyProtocol) 3216 self.assertNotIsSubclass(object, Protocol) 3217 self.assertNotIsInstance(object(), Protocol) 3218 3219 self.assertIsSubclass(str, SupportsStartsWith) 3220 self.assertIsInstance('foo', SupportsStartsWith) 3221 self.assertNotIsSubclass(str, Protocol) 3222 self.assertNotIsInstance('foo', Protocol) 3223 3224 self.assertIsSubclass(C, SupportsX) 3225 self.assertIsInstance(C(), SupportsX) 3226 self.assertNotIsSubclass(C, Protocol) 3227 self.assertNotIsInstance(C(), Protocol) 3228 3229 def test_protocols_issubclass_non_callable(self): 3230 class C: 3231 x = 1 3232 3233 @runtime_checkable 3234 class PNonCall(Protocol): 3235 x = 1 3236 3237 non_callable_members_illegal = ( 3238 "Protocols with non-method members don't support issubclass()" 3239 ) 3240 3241 with self.assertRaisesRegex(TypeError, non_callable_members_illegal): 3242 issubclass(C, PNonCall) 3243 3244 self.assertIsInstance(C(), PNonCall) 3245 PNonCall.register(C) 3246 3247 with self.assertRaisesRegex(TypeError, non_callable_members_illegal): 3248 issubclass(C, PNonCall) 3249 3250 self.assertIsInstance(C(), PNonCall) 3251 3252 # check that non-protocol subclasses are not affected 3253 class D(PNonCall): ... 3254 3255 self.assertNotIsSubclass(C, D) 3256 self.assertNotIsInstance(C(), D) 3257 D.register(C) 3258 self.assertIsSubclass(C, D) 3259 self.assertIsInstance(C(), D) 3260 3261 with self.assertRaisesRegex(TypeError, non_callable_members_illegal): 3262 issubclass(D, PNonCall) 3263 3264 def test_no_weird_caching_with_issubclass_after_isinstance(self): 3265 @runtime_checkable 3266 class Spam(Protocol): 3267 x: int 3268 3269 class Eggs: 3270 def __init__(self) -> None: 3271 self.x = 42 3272 3273 self.assertIsInstance(Eggs(), Spam) 3274 3275 # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, 3276 # TypeError wouldn't be raised here, 3277 # as the cached result of the isinstance() check immediately above 3278 # would mean the issubclass() call would short-circuit 3279 # before we got to the "raise TypeError" line 3280 with self.assertRaisesRegex( 3281 TypeError, 3282 "Protocols with non-method members don't support issubclass()" 3283 ): 3284 issubclass(Eggs, Spam) 3285 3286 def test_no_weird_caching_with_issubclass_after_isinstance_2(self): 3287 @runtime_checkable 3288 class Spam(Protocol): 3289 x: int 3290 3291 class Eggs: ... 3292 3293 self.assertNotIsInstance(Eggs(), Spam) 3294 3295 # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, 3296 # TypeError wouldn't be raised here, 3297 # as the cached result of the isinstance() check immediately above 3298 # would mean the issubclass() call would short-circuit 3299 # before we got to the "raise TypeError" line 3300 with self.assertRaisesRegex( 3301 TypeError, 3302 "Protocols with non-method members don't support issubclass()" 3303 ): 3304 issubclass(Eggs, Spam) 3305 3306 def test_no_weird_caching_with_issubclass_after_isinstance_3(self): 3307 @runtime_checkable 3308 class Spam(Protocol): 3309 x: int 3310 3311 class Eggs: 3312 def __getattr__(self, attr): 3313 if attr == "x": 3314 return 42 3315 raise AttributeError(attr) 3316 3317 self.assertNotIsInstance(Eggs(), Spam) 3318 3319 # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, 3320 # TypeError wouldn't be raised here, 3321 # as the cached result of the isinstance() check immediately above 3322 # would mean the issubclass() call would short-circuit 3323 # before we got to the "raise TypeError" line 3324 with self.assertRaisesRegex( 3325 TypeError, 3326 "Protocols with non-method members don't support issubclass()" 3327 ): 3328 issubclass(Eggs, Spam) 3329 3330 def test_no_weird_caching_with_issubclass_after_isinstance_pep695(self): 3331 @runtime_checkable 3332 class Spam[T](Protocol): 3333 x: T 3334 3335 class Eggs[T]: 3336 def __init__(self, x: T) -> None: 3337 self.x = x 3338 3339 self.assertIsInstance(Eggs(42), Spam) 3340 3341 # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, 3342 # TypeError wouldn't be raised here, 3343 # as the cached result of the isinstance() check immediately above 3344 # would mean the issubclass() call would short-circuit 3345 # before we got to the "raise TypeError" line 3346 with self.assertRaisesRegex( 3347 TypeError, 3348 "Protocols with non-method members don't support issubclass()" 3349 ): 3350 issubclass(Eggs, Spam) 3351 3352 def test_protocols_isinstance(self): 3353 T = TypeVar('T') 3354 3355 @runtime_checkable 3356 class P(Protocol): 3357 def meth(x): ... 3358 3359 @runtime_checkable 3360 class PG(Protocol[T]): 3361 def meth(x): ... 3362 3363 @runtime_checkable 3364 class WeirdProto(Protocol): 3365 meth = str.maketrans 3366 3367 @runtime_checkable 3368 class WeirdProto2(Protocol): 3369 meth = lambda *args, **kwargs: None 3370 3371 class CustomCallable: 3372 def __call__(self, *args, **kwargs): 3373 pass 3374 3375 @runtime_checkable 3376 class WeirderProto(Protocol): 3377 meth = CustomCallable() 3378 3379 class BadP(Protocol): 3380 def meth(x): ... 3381 3382 class BadPG(Protocol[T]): 3383 def meth(x): ... 3384 3385 class C: 3386 def meth(x): ... 3387 3388 class C2: 3389 def __init__(self): 3390 self.meth = lambda: None 3391 3392 for klass in C, C2: 3393 for proto in P, PG, WeirdProto, WeirdProto2, WeirderProto: 3394 with self.subTest(klass=klass.__name__, proto=proto.__name__): 3395 self.assertIsInstance(klass(), proto) 3396 3397 no_subscripted_generics = "Subscripted generics cannot be used with class and instance checks" 3398 3399 with self.assertRaisesRegex(TypeError, no_subscripted_generics): 3400 isinstance(C(), PG[T]) 3401 with self.assertRaisesRegex(TypeError, no_subscripted_generics): 3402 isinstance(C(), PG[C]) 3403 3404 only_runtime_checkable_msg = ( 3405 "Instance and class checks can only be used " 3406 "with @runtime_checkable protocols" 3407 ) 3408 3409 with self.assertRaisesRegex(TypeError, only_runtime_checkable_msg): 3410 isinstance(C(), BadP) 3411 with self.assertRaisesRegex(TypeError, only_runtime_checkable_msg): 3412 isinstance(C(), BadPG) 3413 3414 def test_protocols_isinstance_properties_and_descriptors(self): 3415 class C: 3416 @property 3417 def attr(self): 3418 return 42 3419 3420 class CustomDescriptor: 3421 def __get__(self, obj, objtype=None): 3422 return 42 3423 3424 class D: 3425 attr = CustomDescriptor() 3426 3427 # Check that properties set on superclasses 3428 # are still found by the isinstance() logic 3429 class E(C): ... 3430 class F(D): ... 3431 3432 class Empty: ... 3433 3434 T = TypeVar('T') 3435 3436 @runtime_checkable 3437 class P(Protocol): 3438 @property 3439 def attr(self): ... 3440 3441 @runtime_checkable 3442 class P1(Protocol): 3443 attr: int 3444 3445 @runtime_checkable 3446 class PG(Protocol[T]): 3447 @property 3448 def attr(self): ... 3449 3450 @runtime_checkable 3451 class PG1(Protocol[T]): 3452 attr: T 3453 3454 @runtime_checkable 3455 class MethodP(Protocol): 3456 def attr(self): ... 3457 3458 @runtime_checkable 3459 class MethodPG(Protocol[T]): 3460 def attr(self) -> T: ... 3461 3462 for protocol_class in P, P1, PG, PG1, MethodP, MethodPG: 3463 for klass in C, D, E, F: 3464 with self.subTest( 3465 klass=klass.__name__, 3466 protocol_class=protocol_class.__name__ 3467 ): 3468 self.assertIsInstance(klass(), protocol_class) 3469 3470 with self.subTest(klass="Empty", protocol_class=protocol_class.__name__): 3471 self.assertNotIsInstance(Empty(), protocol_class) 3472 3473 class BadP(Protocol): 3474 @property 3475 def attr(self): ... 3476 3477 class BadP1(Protocol): 3478 attr: int 3479 3480 class BadPG(Protocol[T]): 3481 @property 3482 def attr(self): ... 3483 3484 class BadPG1(Protocol[T]): 3485 attr: T 3486 3487 cases = ( 3488 PG[T], PG[C], PG1[T], PG1[C], MethodPG[T], 3489 MethodPG[C], BadP, BadP1, BadPG, BadPG1 3490 ) 3491 3492 for obj in cases: 3493 for klass in C, D, E, F, Empty: 3494 with self.subTest(klass=klass.__name__, obj=obj): 3495 with self.assertRaises(TypeError): 3496 isinstance(klass(), obj) 3497 3498 def test_protocols_isinstance_not_fooled_by_custom_dir(self): 3499 @runtime_checkable 3500 class HasX(Protocol): 3501 x: int 3502 3503 class CustomDirWithX: 3504 x = 10 3505 def __dir__(self): 3506 return [] 3507 3508 class CustomDirWithoutX: 3509 def __dir__(self): 3510 return ["x"] 3511 3512 self.assertIsInstance(CustomDirWithX(), HasX) 3513 self.assertNotIsInstance(CustomDirWithoutX(), HasX) 3514 3515 def test_protocols_isinstance_attribute_access_with_side_effects(self): 3516 class C: 3517 @property 3518 def attr(self): 3519 raise AttributeError('no') 3520 3521 class CustomDescriptor: 3522 def __get__(self, obj, objtype=None): 3523 raise RuntimeError("NO") 3524 3525 class D: 3526 attr = CustomDescriptor() 3527 3528 # Check that properties set on superclasses 3529 # are still found by the isinstance() logic 3530 class E(C): ... 3531 class F(D): ... 3532 3533 class WhyWouldYouDoThis: 3534 def __getattr__(self, name): 3535 raise RuntimeError("wut") 3536 3537 T = TypeVar('T') 3538 3539 @runtime_checkable 3540 class P(Protocol): 3541 @property 3542 def attr(self): ... 3543 3544 @runtime_checkable 3545 class P1(Protocol): 3546 attr: int 3547 3548 @runtime_checkable 3549 class PG(Protocol[T]): 3550 @property 3551 def attr(self): ... 3552 3553 @runtime_checkable 3554 class PG1(Protocol[T]): 3555 attr: T 3556 3557 @runtime_checkable 3558 class MethodP(Protocol): 3559 def attr(self): ... 3560 3561 @runtime_checkable 3562 class MethodPG(Protocol[T]): 3563 def attr(self) -> T: ... 3564 3565 for protocol_class in P, P1, PG, PG1, MethodP, MethodPG: 3566 for klass in C, D, E, F: 3567 with self.subTest( 3568 klass=klass.__name__, 3569 protocol_class=protocol_class.__name__ 3570 ): 3571 self.assertIsInstance(klass(), protocol_class) 3572 3573 with self.subTest( 3574 klass="WhyWouldYouDoThis", 3575 protocol_class=protocol_class.__name__ 3576 ): 3577 self.assertNotIsInstance(WhyWouldYouDoThis(), protocol_class) 3578 3579 def test_protocols_isinstance___slots__(self): 3580 # As per the consensus in https://github.com/python/typing/issues/1367, 3581 # this is desirable behaviour 3582 @runtime_checkable 3583 class HasX(Protocol): 3584 x: int 3585 3586 class HasNothingButSlots: 3587 __slots__ = ("x",) 3588 3589 self.assertIsInstance(HasNothingButSlots(), HasX) 3590 3591 def test_protocols_isinstance_py36(self): 3592 class APoint: 3593 def __init__(self, x, y, label): 3594 self.x = x 3595 self.y = y 3596 self.label = label 3597 3598 class BPoint: 3599 label = 'B' 3600 3601 def __init__(self, x, y): 3602 self.x = x 3603 self.y = y 3604 3605 class C: 3606 def __init__(self, attr): 3607 self.attr = attr 3608 3609 def meth(self, arg): 3610 return 0 3611 3612 class Bad: pass 3613 3614 self.assertIsInstance(APoint(1, 2, 'A'), Point) 3615 self.assertIsInstance(BPoint(1, 2), Point) 3616 self.assertNotIsInstance(MyPoint(), Point) 3617 self.assertIsInstance(BPoint(1, 2), Position) 3618 self.assertIsInstance(Other(), Proto) 3619 self.assertIsInstance(Concrete(), Proto) 3620 self.assertIsInstance(C(42), Proto) 3621 self.assertNotIsInstance(Bad(), Proto) 3622 self.assertNotIsInstance(Bad(), Point) 3623 self.assertNotIsInstance(Bad(), Position) 3624 self.assertNotIsInstance(Bad(), Concrete) 3625 self.assertNotIsInstance(Other(), Concrete) 3626 self.assertIsInstance(NT(1, 2), Position) 3627 3628 def test_protocols_isinstance_init(self): 3629 T = TypeVar('T') 3630 3631 @runtime_checkable 3632 class P(Protocol): 3633 x = 1 3634 3635 @runtime_checkable 3636 class PG(Protocol[T]): 3637 x = 1 3638 3639 class C: 3640 def __init__(self, x): 3641 self.x = x 3642 3643 self.assertIsInstance(C(1), P) 3644 self.assertIsInstance(C(1), PG) 3645 3646 def test_protocols_isinstance_monkeypatching(self): 3647 @runtime_checkable 3648 class HasX(Protocol): 3649 x: int 3650 3651 class Foo: ... 3652 3653 f = Foo() 3654 self.assertNotIsInstance(f, HasX) 3655 f.x = 42 3656 self.assertIsInstance(f, HasX) 3657 del f.x 3658 self.assertNotIsInstance(f, HasX) 3659 3660 def test_protocol_checks_after_subscript(self): 3661 class P(Protocol[T]): pass 3662 class C(P[T]): pass 3663 class Other1: pass 3664 class Other2: pass 3665 CA = C[Any] 3666 3667 self.assertNotIsInstance(Other1(), C) 3668 self.assertNotIsSubclass(Other2, C) 3669 3670 class D1(C[Any]): pass 3671 class D2(C[Any]): pass 3672 CI = C[int] 3673 3674 self.assertIsInstance(D1(), C) 3675 self.assertIsSubclass(D2, C) 3676 3677 def test_protocols_support_register(self): 3678 @runtime_checkable 3679 class P(Protocol): 3680 x = 1 3681 3682 class PM(Protocol): 3683 def meth(self): pass 3684 3685 class D(PM): pass 3686 3687 class C: pass 3688 3689 D.register(C) 3690 P.register(C) 3691 self.assertIsInstance(C(), P) 3692 self.assertIsInstance(C(), D) 3693 3694 def test_none_on_non_callable_doesnt_block_implementation(self): 3695 @runtime_checkable 3696 class P(Protocol): 3697 x = 1 3698 3699 class A: 3700 x = 1 3701 3702 class B(A): 3703 x = None 3704 3705 class C: 3706 def __init__(self): 3707 self.x = None 3708 3709 self.assertIsInstance(B(), P) 3710 self.assertIsInstance(C(), P) 3711 3712 def test_none_on_callable_blocks_implementation(self): 3713 @runtime_checkable 3714 class P(Protocol): 3715 def x(self): ... 3716 3717 class A: 3718 def x(self): ... 3719 3720 class B(A): 3721 x = None 3722 3723 class C: 3724 def __init__(self): 3725 self.x = None 3726 3727 self.assertNotIsInstance(B(), P) 3728 self.assertNotIsInstance(C(), P) 3729 3730 def test_non_protocol_subclasses(self): 3731 class P(Protocol): 3732 x = 1 3733 3734 @runtime_checkable 3735 class PR(Protocol): 3736 def meth(self): pass 3737 3738 class NonP(P): 3739 x = 1 3740 3741 class NonPR(PR): pass 3742 3743 class C(metaclass=abc.ABCMeta): 3744 x = 1 3745 3746 class D(metaclass=abc.ABCMeta): 3747 def meth(self): pass 3748 3749 self.assertNotIsInstance(C(), NonP) 3750 self.assertNotIsInstance(D(), NonPR) 3751 self.assertNotIsSubclass(C, NonP) 3752 self.assertNotIsSubclass(D, NonPR) 3753 self.assertIsInstance(NonPR(), PR) 3754 self.assertIsSubclass(NonPR, PR) 3755 3756 self.assertNotIn("__protocol_attrs__", vars(NonP)) 3757 self.assertNotIn("__protocol_attrs__", vars(NonPR)) 3758 self.assertNotIn("__non_callable_proto_members__", vars(NonP)) 3759 self.assertNotIn("__non_callable_proto_members__", vars(NonPR)) 3760 3761 self.assertEqual(get_protocol_members(P), {"x"}) 3762 self.assertEqual(get_protocol_members(PR), {"meth"}) 3763 3764 # the returned object should be immutable, 3765 # and should be a different object to the original attribute 3766 # to prevent users from (accidentally or deliberately) 3767 # mutating the attribute on the original class 3768 self.assertIsInstance(get_protocol_members(P), frozenset) 3769 self.assertIsNot(get_protocol_members(P), P.__protocol_attrs__) 3770 self.assertIsInstance(get_protocol_members(PR), frozenset) 3771 self.assertIsNot(get_protocol_members(PR), P.__protocol_attrs__) 3772 3773 acceptable_extra_attrs = { 3774 '_is_protocol', '_is_runtime_protocol', '__parameters__', 3775 '__init__', '__annotations__', '__subclasshook__', 3776 } 3777 self.assertLessEqual(vars(NonP).keys(), vars(C).keys() | acceptable_extra_attrs) 3778 self.assertLessEqual( 3779 vars(NonPR).keys(), vars(D).keys() | acceptable_extra_attrs 3780 ) 3781 3782 def test_custom_subclasshook(self): 3783 class P(Protocol): 3784 x = 1 3785 3786 class OKClass: pass 3787 3788 class BadClass: 3789 x = 1 3790 3791 class C(P): 3792 @classmethod 3793 def __subclasshook__(cls, other): 3794 return other.__name__.startswith("OK") 3795 3796 self.assertIsInstance(OKClass(), C) 3797 self.assertNotIsInstance(BadClass(), C) 3798 self.assertIsSubclass(OKClass, C) 3799 self.assertNotIsSubclass(BadClass, C) 3800 3801 def test_custom_subclasshook_2(self): 3802 @runtime_checkable 3803 class HasX(Protocol): 3804 # The presence of a non-callable member 3805 # would mean issubclass() checks would fail with TypeError 3806 # if it weren't for the custom `__subclasshook__` method 3807 x = 1 3808 3809 @classmethod 3810 def __subclasshook__(cls, other): 3811 return hasattr(other, 'x') 3812 3813 class Empty: pass 3814 3815 class ImplementsHasX: 3816 x = 1 3817 3818 self.assertIsInstance(ImplementsHasX(), HasX) 3819 self.assertNotIsInstance(Empty(), HasX) 3820 self.assertIsSubclass(ImplementsHasX, HasX) 3821 self.assertNotIsSubclass(Empty, HasX) 3822 3823 # isinstance() and issubclass() checks against this still raise TypeError, 3824 # despite the presence of the custom __subclasshook__ method, 3825 # as it's not decorated with @runtime_checkable 3826 class NotRuntimeCheckable(Protocol): 3827 @classmethod 3828 def __subclasshook__(cls, other): 3829 return hasattr(other, 'x') 3830 3831 must_be_runtime_checkable = ( 3832 "Instance and class checks can only be used " 3833 "with @runtime_checkable protocols" 3834 ) 3835 3836 with self.assertRaisesRegex(TypeError, must_be_runtime_checkable): 3837 issubclass(object, NotRuntimeCheckable) 3838 with self.assertRaisesRegex(TypeError, must_be_runtime_checkable): 3839 isinstance(object(), NotRuntimeCheckable) 3840 3841 def test_issubclass_fails_correctly(self): 3842 @runtime_checkable 3843 class NonCallableMembers(Protocol): 3844 x = 1 3845 3846 class NotRuntimeCheckable(Protocol): 3847 def callable_member(self) -> int: ... 3848 3849 @runtime_checkable 3850 class RuntimeCheckable(Protocol): 3851 def callable_member(self) -> int: ... 3852 3853 class C: pass 3854 3855 # These three all exercise different code paths, 3856 # but should result in the same error message: 3857 for protocol in NonCallableMembers, NotRuntimeCheckable, RuntimeCheckable: 3858 with self.subTest(proto_name=protocol.__name__): 3859 with self.assertRaisesRegex( 3860 TypeError, r"issubclass\(\) arg 1 must be a class" 3861 ): 3862 issubclass(C(), protocol) 3863 3864 def test_defining_generic_protocols(self): 3865 T = TypeVar('T') 3866 S = TypeVar('S') 3867 3868 @runtime_checkable 3869 class PR(Protocol[T, S]): 3870 def meth(self): pass 3871 3872 class P(PR[int, T], Protocol[T]): 3873 y = 1 3874 3875 with self.assertRaises(TypeError): 3876 PR[int] 3877 with self.assertRaises(TypeError): 3878 P[int, str] 3879 3880 class C(PR[int, T]): pass 3881 3882 self.assertIsInstance(C[str](), C) 3883 3884 def test_defining_generic_protocols_old_style(self): 3885 T = TypeVar('T') 3886 S = TypeVar('S') 3887 3888 @runtime_checkable 3889 class PR(Protocol, Generic[T, S]): 3890 def meth(self): pass 3891 3892 class P(PR[int, str], Protocol): 3893 y = 1 3894 3895 with self.assertRaises(TypeError): 3896 issubclass(PR[int, str], PR) 3897 self.assertIsSubclass(P, PR) 3898 with self.assertRaises(TypeError): 3899 PR[int] 3900 3901 class P1(Protocol, Generic[T]): 3902 def bar(self, x: T) -> str: ... 3903 3904 class P2(Generic[T], Protocol): 3905 def bar(self, x: T) -> str: ... 3906 3907 @runtime_checkable 3908 class PSub(P1[str], Protocol): 3909 x = 1 3910 3911 class Test: 3912 x = 1 3913 3914 def bar(self, x: str) -> str: 3915 return x 3916 3917 self.assertIsInstance(Test(), PSub) 3918 3919 def test_pep695_generic_protocol_callable_members(self): 3920 @runtime_checkable 3921 class Foo[T](Protocol): 3922 def meth(self, x: T) -> None: ... 3923 3924 class Bar[T]: 3925 def meth(self, x: T) -> None: ... 3926 3927 self.assertIsInstance(Bar(), Foo) 3928 self.assertIsSubclass(Bar, Foo) 3929 3930 @runtime_checkable 3931 class SupportsTrunc[T](Protocol): 3932 def __trunc__(self) -> T: ... 3933 3934 self.assertIsInstance(0.0, SupportsTrunc) 3935 self.assertIsSubclass(float, SupportsTrunc) 3936 3937 def test_init_called(self): 3938 T = TypeVar('T') 3939 3940 class P(Protocol[T]): pass 3941 3942 class C(P[T]): 3943 def __init__(self): 3944 self.test = 'OK' 3945 3946 self.assertEqual(C[int]().test, 'OK') 3947 3948 class B: 3949 def __init__(self): 3950 self.test = 'OK' 3951 3952 class D1(B, P[T]): 3953 pass 3954 3955 self.assertEqual(D1[int]().test, 'OK') 3956 3957 class D2(P[T], B): 3958 pass 3959 3960 self.assertEqual(D2[int]().test, 'OK') 3961 3962 def test_new_called(self): 3963 T = TypeVar('T') 3964 3965 class P(Protocol[T]): pass 3966 3967 class C(P[T]): 3968 def __new__(cls, *args): 3969 self = super().__new__(cls, *args) 3970 self.test = 'OK' 3971 return self 3972 3973 self.assertEqual(C[int]().test, 'OK') 3974 with self.assertRaises(TypeError): 3975 C[int](42) 3976 with self.assertRaises(TypeError): 3977 C[int](a=42) 3978 3979 def test_protocols_bad_subscripts(self): 3980 T = TypeVar('T') 3981 S = TypeVar('S') 3982 with self.assertRaises(TypeError): 3983 class P(Protocol[T, T]): pass 3984 with self.assertRaises(TypeError): 3985 class Q(Protocol[int]): pass 3986 with self.assertRaises(TypeError): 3987 class R(Protocol[T], Protocol[S]): pass 3988 with self.assertRaises(TypeError): 3989 class S(typing.Mapping[T, S], Protocol[T]): pass 3990 3991 def test_generic_protocols_repr(self): 3992 T = TypeVar('T') 3993 S = TypeVar('S') 3994 3995 class P(Protocol[T, S]): pass 3996 3997 self.assertTrue(repr(P[T, S]).endswith('P[~T, ~S]')) 3998 self.assertTrue(repr(P[int, str]).endswith('P[int, str]')) 3999 4000 def test_generic_protocols_eq(self): 4001 T = TypeVar('T') 4002 S = TypeVar('S') 4003 4004 class P(Protocol[T, S]): pass 4005 4006 self.assertEqual(P, P) 4007 self.assertEqual(P[int, T], P[int, T]) 4008 self.assertEqual(P[T, T][Tuple[T, S]][int, str], 4009 P[Tuple[int, str], Tuple[int, str]]) 4010 4011 def test_generic_protocols_special_from_generic(self): 4012 T = TypeVar('T') 4013 4014 class P(Protocol[T]): pass 4015 4016 self.assertEqual(P.__parameters__, (T,)) 4017 self.assertEqual(P[int].__parameters__, ()) 4018 self.assertEqual(P[int].__args__, (int,)) 4019 self.assertIs(P[int].__origin__, P) 4020 4021 def test_generic_protocols_special_from_protocol(self): 4022 @runtime_checkable 4023 class PR(Protocol): 4024 x = 1 4025 4026 class P(Protocol): 4027 def meth(self): 4028 pass 4029 4030 T = TypeVar('T') 4031 4032 class PG(Protocol[T]): 4033 x = 1 4034 4035 def meth(self): 4036 pass 4037 4038 self.assertTrue(P._is_protocol) 4039 self.assertTrue(PR._is_protocol) 4040 self.assertTrue(PG._is_protocol) 4041 self.assertFalse(P._is_runtime_protocol) 4042 self.assertTrue(PR._is_runtime_protocol) 4043 self.assertTrue(PG[int]._is_protocol) 4044 self.assertEqual(typing._get_protocol_attrs(P), {'meth'}) 4045 self.assertEqual(typing._get_protocol_attrs(PR), {'x'}) 4046 self.assertEqual(frozenset(typing._get_protocol_attrs(PG)), 4047 frozenset({'x', 'meth'})) 4048 4049 def test_no_runtime_deco_on_nominal(self): 4050 with self.assertRaises(TypeError): 4051 @runtime_checkable 4052 class C: pass 4053 4054 class Proto(Protocol): 4055 x = 1 4056 4057 with self.assertRaises(TypeError): 4058 @runtime_checkable 4059 class Concrete(Proto): 4060 pass 4061 4062 def test_none_treated_correctly(self): 4063 @runtime_checkable 4064 class P(Protocol): 4065 x = None # type: int 4066 4067 class B(object): pass 4068 4069 self.assertNotIsInstance(B(), P) 4070 4071 class C: 4072 x = 1 4073 4074 class D: 4075 x = None 4076 4077 self.assertIsInstance(C(), P) 4078 self.assertIsInstance(D(), P) 4079 4080 class CI: 4081 def __init__(self): 4082 self.x = 1 4083 4084 class DI: 4085 def __init__(self): 4086 self.x = None 4087 4088 self.assertIsInstance(CI(), P) 4089 self.assertIsInstance(DI(), P) 4090 4091 def test_protocols_in_unions(self): 4092 class P(Protocol): 4093 x = None # type: int 4094 4095 Alias = typing.Union[typing.Iterable, P] 4096 Alias2 = typing.Union[P, typing.Iterable] 4097 self.assertEqual(Alias, Alias2) 4098 4099 def test_protocols_pickleable(self): 4100 global P, CP # pickle wants to reference the class by name 4101 T = TypeVar('T') 4102 4103 @runtime_checkable 4104 class P(Protocol[T]): 4105 x = 1 4106 4107 class CP(P[int]): 4108 pass 4109 4110 c = CP() 4111 c.foo = 42 4112 c.bar = 'abc' 4113 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 4114 z = pickle.dumps(c, proto) 4115 x = pickle.loads(z) 4116 self.assertEqual(x.foo, 42) 4117 self.assertEqual(x.bar, 'abc') 4118 self.assertEqual(x.x, 1) 4119 self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) 4120 s = pickle.dumps(P, proto) 4121 D = pickle.loads(s) 4122 4123 class E: 4124 x = 1 4125 4126 self.assertIsInstance(E(), D) 4127 4128 def test_runtime_checkable_with_match_args(self): 4129 @runtime_checkable 4130 class P_regular(Protocol): 4131 x: int 4132 y: int 4133 4134 @runtime_checkable 4135 class P_match(Protocol): 4136 __match_args__ = ('x', 'y') 4137 x: int 4138 y: int 4139 4140 class Regular: 4141 def __init__(self, x: int, y: int): 4142 self.x = x 4143 self.y = y 4144 4145 class WithMatch: 4146 __match_args__ = ('x', 'y', 'z') 4147 def __init__(self, x: int, y: int, z: int): 4148 self.x = x 4149 self.y = y 4150 self.z = z 4151 4152 class Nope: ... 4153 4154 self.assertIsInstance(Regular(1, 2), P_regular) 4155 self.assertIsInstance(Regular(1, 2), P_match) 4156 self.assertIsInstance(WithMatch(1, 2, 3), P_regular) 4157 self.assertIsInstance(WithMatch(1, 2, 3), P_match) 4158 self.assertNotIsInstance(Nope(), P_regular) 4159 self.assertNotIsInstance(Nope(), P_match) 4160 4161 def test_supports_int(self): 4162 self.assertIsSubclass(int, typing.SupportsInt) 4163 self.assertNotIsSubclass(str, typing.SupportsInt) 4164 4165 def test_supports_float(self): 4166 self.assertIsSubclass(float, typing.SupportsFloat) 4167 self.assertNotIsSubclass(str, typing.SupportsFloat) 4168 4169 def test_supports_complex(self): 4170 4171 class C: 4172 def __complex__(self): 4173 return 0j 4174 4175 self.assertIsSubclass(complex, typing.SupportsComplex) 4176 self.assertIsSubclass(C, typing.SupportsComplex) 4177 self.assertNotIsSubclass(str, typing.SupportsComplex) 4178 4179 def test_supports_bytes(self): 4180 4181 class B: 4182 def __bytes__(self): 4183 return b'' 4184 4185 self.assertIsSubclass(bytes, typing.SupportsBytes) 4186 self.assertIsSubclass(B, typing.SupportsBytes) 4187 self.assertNotIsSubclass(str, typing.SupportsBytes) 4188 4189 def test_supports_abs(self): 4190 self.assertIsSubclass(float, typing.SupportsAbs) 4191 self.assertIsSubclass(int, typing.SupportsAbs) 4192 self.assertNotIsSubclass(str, typing.SupportsAbs) 4193 4194 def test_supports_round(self): 4195 issubclass(float, typing.SupportsRound) 4196 self.assertIsSubclass(float, typing.SupportsRound) 4197 self.assertIsSubclass(int, typing.SupportsRound) 4198 self.assertNotIsSubclass(str, typing.SupportsRound) 4199 4200 def test_reversible(self): 4201 self.assertIsSubclass(list, typing.Reversible) 4202 self.assertNotIsSubclass(int, typing.Reversible) 4203 4204 def test_supports_index(self): 4205 self.assertIsSubclass(int, typing.SupportsIndex) 4206 self.assertNotIsSubclass(str, typing.SupportsIndex) 4207 4208 def test_bundled_protocol_instance_works(self): 4209 self.assertIsInstance(0, typing.SupportsAbs) 4210 class C1(typing.SupportsInt): 4211 def __int__(self) -> int: 4212 return 42 4213 class C2(C1): 4214 pass 4215 c = C2() 4216 self.assertIsInstance(c, C1) 4217 4218 def test_collections_protocols_allowed(self): 4219 @runtime_checkable 4220 class Custom(collections.abc.Iterable, Protocol): 4221 def close(self): ... 4222 4223 class A: pass 4224 class B: 4225 def __iter__(self): 4226 return [] 4227 def close(self): 4228 return 0 4229 4230 self.assertIsSubclass(B, Custom) 4231 self.assertNotIsSubclass(A, Custom) 4232 4233 @runtime_checkable 4234 class ReleasableBuffer(collections.abc.Buffer, Protocol): 4235 def __release_buffer__(self, mv: memoryview) -> None: ... 4236 4237 class C: pass 4238 class D: 4239 def __buffer__(self, flags: int) -> memoryview: 4240 return memoryview(b'') 4241 def __release_buffer__(self, mv: memoryview) -> None: 4242 pass 4243 4244 self.assertIsSubclass(D, ReleasableBuffer) 4245 self.assertIsInstance(D(), ReleasableBuffer) 4246 self.assertNotIsSubclass(C, ReleasableBuffer) 4247 self.assertNotIsInstance(C(), ReleasableBuffer) 4248 4249 def test_builtin_protocol_allowlist(self): 4250 with self.assertRaises(TypeError): 4251 class CustomProtocol(TestCase, Protocol): 4252 pass 4253 4254 class CustomContextManager(typing.ContextManager, Protocol): 4255 pass 4256 4257 class CustomAsyncIterator(typing.AsyncIterator, Protocol): 4258 pass 4259 4260 def test_non_runtime_protocol_isinstance_check(self): 4261 class P(Protocol): 4262 x: int 4263 4264 with self.assertRaisesRegex(TypeError, "@runtime_checkable"): 4265 isinstance(1, P) 4266 4267 def test_super_call_init(self): 4268 class P(Protocol): 4269 x: int 4270 4271 class Foo(P): 4272 def __init__(self): 4273 super().__init__() 4274 4275 Foo() # Previously triggered RecursionError 4276 4277 def test_get_protocol_members(self): 4278 with self.assertRaisesRegex(TypeError, "not a Protocol"): 4279 get_protocol_members(object) 4280 with self.assertRaisesRegex(TypeError, "not a Protocol"): 4281 get_protocol_members(object()) 4282 with self.assertRaisesRegex(TypeError, "not a Protocol"): 4283 get_protocol_members(Protocol) 4284 with self.assertRaisesRegex(TypeError, "not a Protocol"): 4285 get_protocol_members(Generic) 4286 4287 class P(Protocol): 4288 a: int 4289 def b(self) -> str: ... 4290 @property 4291 def c(self) -> int: ... 4292 4293 self.assertEqual(get_protocol_members(P), {'a', 'b', 'c'}) 4294 self.assertIsInstance(get_protocol_members(P), frozenset) 4295 self.assertIsNot(get_protocol_members(P), P.__protocol_attrs__) 4296 4297 class Concrete: 4298 a: int 4299 def b(self) -> str: return "capybara" 4300 @property 4301 def c(self) -> int: return 5 4302 4303 with self.assertRaisesRegex(TypeError, "not a Protocol"): 4304 get_protocol_members(Concrete) 4305 with self.assertRaisesRegex(TypeError, "not a Protocol"): 4306 get_protocol_members(Concrete()) 4307 4308 class ConcreteInherit(P): 4309 a: int = 42 4310 def b(self) -> str: return "capybara" 4311 @property 4312 def c(self) -> int: return 5 4313 4314 with self.assertRaisesRegex(TypeError, "not a Protocol"): 4315 get_protocol_members(ConcreteInherit) 4316 with self.assertRaisesRegex(TypeError, "not a Protocol"): 4317 get_protocol_members(ConcreteInherit()) 4318 4319 def test_is_protocol(self): 4320 self.assertTrue(is_protocol(Proto)) 4321 self.assertTrue(is_protocol(Point)) 4322 self.assertFalse(is_protocol(Concrete)) 4323 self.assertFalse(is_protocol(Concrete())) 4324 self.assertFalse(is_protocol(Generic)) 4325 self.assertFalse(is_protocol(object)) 4326 4327 # Protocol is not itself a protocol 4328 self.assertFalse(is_protocol(Protocol)) 4329 4330 def test_interaction_with_isinstance_checks_on_superclasses_with_ABCMeta(self): 4331 # Ensure the cache is empty, or this test won't work correctly 4332 collections.abc.Sized._abc_registry_clear() 4333 4334 class Foo(collections.abc.Sized, Protocol): pass 4335 4336 # gh-105144: this previously raised TypeError 4337 # if a Protocol subclass of Sized had been created 4338 # before any isinstance() checks against Sized 4339 self.assertNotIsInstance(1, collections.abc.Sized) 4340 4341 def test_interaction_with_isinstance_checks_on_superclasses_with_ABCMeta_2(self): 4342 # Ensure the cache is empty, or this test won't work correctly 4343 collections.abc.Sized._abc_registry_clear() 4344 4345 class Foo(typing.Sized, Protocol): pass 4346 4347 # gh-105144: this previously raised TypeError 4348 # if a Protocol subclass of Sized had been created 4349 # before any isinstance() checks against Sized 4350 self.assertNotIsInstance(1, typing.Sized) 4351 4352 def test_empty_protocol_decorated_with_final(self): 4353 @final 4354 @runtime_checkable 4355 class EmptyProtocol(Protocol): ... 4356 4357 self.assertIsSubclass(object, EmptyProtocol) 4358 self.assertIsInstance(object(), EmptyProtocol) 4359 4360 def test_protocol_decorated_with_final_callable_members(self): 4361 @final 4362 @runtime_checkable 4363 class ProtocolWithMethod(Protocol): 4364 def startswith(self, string: str) -> bool: ... 4365 4366 self.assertIsSubclass(str, ProtocolWithMethod) 4367 self.assertNotIsSubclass(int, ProtocolWithMethod) 4368 self.assertIsInstance('foo', ProtocolWithMethod) 4369 self.assertNotIsInstance(42, ProtocolWithMethod) 4370 4371 def test_protocol_decorated_with_final_noncallable_members(self): 4372 @final 4373 @runtime_checkable 4374 class ProtocolWithNonCallableMember(Protocol): 4375 x: int 4376 4377 class Foo: 4378 x = 42 4379 4380 only_callable_members_please = ( 4381 r"Protocols with non-method members don't support issubclass()" 4382 ) 4383 4384 with self.assertRaisesRegex(TypeError, only_callable_members_please): 4385 issubclass(Foo, ProtocolWithNonCallableMember) 4386 4387 with self.assertRaisesRegex(TypeError, only_callable_members_please): 4388 issubclass(int, ProtocolWithNonCallableMember) 4389 4390 self.assertIsInstance(Foo(), ProtocolWithNonCallableMember) 4391 self.assertNotIsInstance(42, ProtocolWithNonCallableMember) 4392 4393 def test_protocol_decorated_with_final_mixed_members(self): 4394 @final 4395 @runtime_checkable 4396 class ProtocolWithMixedMembers(Protocol): 4397 x: int 4398 def method(self) -> None: ... 4399 4400 class Foo: 4401 x = 42 4402 def method(self) -> None: ... 4403 4404 only_callable_members_please = ( 4405 r"Protocols with non-method members don't support issubclass()" 4406 ) 4407 4408 with self.assertRaisesRegex(TypeError, only_callable_members_please): 4409 issubclass(Foo, ProtocolWithMixedMembers) 4410 4411 with self.assertRaisesRegex(TypeError, only_callable_members_please): 4412 issubclass(int, ProtocolWithMixedMembers) 4413 4414 self.assertIsInstance(Foo(), ProtocolWithMixedMembers) 4415 self.assertNotIsInstance(42, ProtocolWithMixedMembers) 4416 4417 def test_protocol_issubclass_error_message(self): 4418 @runtime_checkable 4419 class Vec2D(Protocol): 4420 x: float 4421 y: float 4422 4423 def square_norm(self) -> float: 4424 return self.x ** 2 + self.y ** 2 4425 4426 self.assertEqual(Vec2D.__protocol_attrs__, {'x', 'y', 'square_norm'}) 4427 expected_error_message = ( 4428 "Protocols with non-method members don't support issubclass()." 4429 " Non-method members: 'x', 'y'." 4430 ) 4431 with self.assertRaisesRegex(TypeError, re.escape(expected_error_message)): 4432 issubclass(int, Vec2D) 4433 4434 def test_nonruntime_protocol_interaction_with_evil_classproperty(self): 4435 class classproperty: 4436 def __get__(self, instance, type): 4437 raise RuntimeError("NO") 4438 4439 class Commentable(Protocol): 4440 evil = classproperty() 4441 4442 # recognised as a protocol attr, 4443 # but not actually accessed by the protocol metaclass 4444 # (which would raise RuntimeError) for non-runtime protocols. 4445 # See gh-113320 4446 self.assertEqual(get_protocol_members(Commentable), {"evil"}) 4447 4448 def test_runtime_protocol_interaction_with_evil_classproperty(self): 4449 class CustomError(Exception): pass 4450 4451 class classproperty: 4452 def __get__(self, instance, type): 4453 raise CustomError 4454 4455 with self.assertRaises(TypeError) as cm: 4456 @runtime_checkable 4457 class Commentable(Protocol): 4458 evil = classproperty() 4459 4460 exc = cm.exception 4461 self.assertEqual( 4462 exc.args[0], 4463 "Failed to determine whether protocol member 'evil' is a method member" 4464 ) 4465 self.assertIs(type(exc.__cause__), CustomError) 4466 4467 4468class GenericTests(BaseTestCase): 4469 4470 def test_basics(self): 4471 X = SimpleMapping[str, Any] 4472 self.assertEqual(X.__parameters__, ()) 4473 with self.assertRaises(TypeError): 4474 X[str] 4475 with self.assertRaises(TypeError): 4476 X[str, str] 4477 Y = SimpleMapping[XK, str] 4478 self.assertEqual(Y.__parameters__, (XK,)) 4479 Y[str] 4480 with self.assertRaises(TypeError): 4481 Y[str, str] 4482 SM1 = SimpleMapping[str, int] 4483 with self.assertRaises(TypeError): 4484 issubclass(SM1, SimpleMapping) 4485 self.assertIsInstance(SM1(), SimpleMapping) 4486 T = TypeVar("T") 4487 self.assertEqual(List[list[T] | float].__parameters__, (T,)) 4488 4489 def test_generic_errors(self): 4490 T = TypeVar('T') 4491 S = TypeVar('S') 4492 with self.assertRaises(TypeError): 4493 Generic[T][T] 4494 with self.assertRaises(TypeError): 4495 Generic[T][S] 4496 with self.assertRaises(TypeError): 4497 class C(Generic[T], Generic[T]): ... 4498 with self.assertRaises(TypeError): 4499 isinstance([], List[int]) 4500 with self.assertRaises(TypeError): 4501 issubclass(list, List[int]) 4502 with self.assertRaises(TypeError): 4503 class NewGeneric(Generic): ... 4504 with self.assertRaises(TypeError): 4505 class MyGeneric(Generic[T], Generic[S]): ... 4506 with self.assertRaises(TypeError): 4507 class MyGeneric2(List[T], Generic[S]): ... 4508 with self.assertRaises(TypeError): 4509 Generic[()] 4510 class D(Generic[T]): pass 4511 with self.assertRaises(TypeError): 4512 D[()] 4513 4514 def test_generic_subclass_checks(self): 4515 for typ in [list[int], List[int], 4516 tuple[int, str], Tuple[int, str], 4517 typing.Callable[..., None], 4518 collections.abc.Callable[..., None]]: 4519 with self.subTest(typ=typ): 4520 self.assertRaises(TypeError, issubclass, typ, object) 4521 self.assertRaises(TypeError, issubclass, typ, type) 4522 self.assertRaises(TypeError, issubclass, typ, typ) 4523 self.assertRaises(TypeError, issubclass, object, typ) 4524 4525 # isinstance is fine: 4526 self.assertTrue(isinstance(typ, object)) 4527 # but, not when the right arg is also a generic: 4528 self.assertRaises(TypeError, isinstance, typ, typ) 4529 4530 def test_init(self): 4531 T = TypeVar('T') 4532 S = TypeVar('S') 4533 with self.assertRaises(TypeError): 4534 Generic[T, T] 4535 with self.assertRaises(TypeError): 4536 Generic[T, S, T] 4537 4538 def test_init_subclass(self): 4539 class X(typing.Generic[T]): 4540 def __init_subclass__(cls, **kwargs): 4541 super().__init_subclass__(**kwargs) 4542 cls.attr = 42 4543 class Y(X): 4544 pass 4545 self.assertEqual(Y.attr, 42) 4546 with self.assertRaises(AttributeError): 4547 X.attr 4548 X.attr = 1 4549 Y.attr = 2 4550 class Z(Y): 4551 pass 4552 class W(X[int]): 4553 pass 4554 self.assertEqual(Y.attr, 2) 4555 self.assertEqual(Z.attr, 42) 4556 self.assertEqual(W.attr, 42) 4557 4558 def test_repr(self): 4559 self.assertEqual(repr(SimpleMapping), 4560 f"<class '{__name__}.SimpleMapping'>") 4561 self.assertEqual(repr(MySimpleMapping), 4562 f"<class '{__name__}.MySimpleMapping'>") 4563 4564 def test_chain_repr(self): 4565 T = TypeVar('T') 4566 S = TypeVar('S') 4567 4568 class C(Generic[T]): 4569 pass 4570 4571 X = C[Tuple[S, T]] 4572 self.assertEqual(X, C[Tuple[S, T]]) 4573 self.assertNotEqual(X, C[Tuple[T, S]]) 4574 4575 Y = X[T, int] 4576 self.assertEqual(Y, X[T, int]) 4577 self.assertNotEqual(Y, X[S, int]) 4578 self.assertNotEqual(Y, X[T, str]) 4579 4580 Z = Y[str] 4581 self.assertEqual(Z, Y[str]) 4582 self.assertNotEqual(Z, Y[int]) 4583 self.assertNotEqual(Z, Y[T]) 4584 4585 self.assertTrue(str(Z).endswith( 4586 '.C[typing.Tuple[str, int]]')) 4587 4588 def test_new_repr(self): 4589 T = TypeVar('T') 4590 U = TypeVar('U', covariant=True) 4591 S = TypeVar('S') 4592 4593 self.assertEqual(repr(List), 'typing.List') 4594 self.assertEqual(repr(List[T]), 'typing.List[~T]') 4595 self.assertEqual(repr(List[U]), 'typing.List[+U]') 4596 self.assertEqual(repr(List[S][T][int]), 'typing.List[int]') 4597 self.assertEqual(repr(List[int]), 'typing.List[int]') 4598 4599 def test_new_repr_complex(self): 4600 T = TypeVar('T') 4601 TS = TypeVar('TS') 4602 4603 self.assertEqual(repr(typing.Mapping[T, TS][TS, T]), 'typing.Mapping[~TS, ~T]') 4604 self.assertEqual(repr(List[Tuple[T, TS]][int, T]), 4605 'typing.List[typing.Tuple[int, ~T]]') 4606 self.assertEqual( 4607 repr(List[Tuple[T, T]][List[int]]), 4608 'typing.List[typing.Tuple[typing.List[int], typing.List[int]]]' 4609 ) 4610 4611 def test_new_repr_bare(self): 4612 T = TypeVar('T') 4613 self.assertEqual(repr(Generic[T]), 'typing.Generic[~T]') 4614 self.assertEqual(repr(typing.Protocol[T]), 'typing.Protocol[~T]') 4615 class C(typing.Dict[Any, Any]): ... 4616 # this line should just work 4617 repr(C.__mro__) 4618 4619 def test_dict(self): 4620 T = TypeVar('T') 4621 4622 class B(Generic[T]): 4623 pass 4624 4625 b = B() 4626 b.foo = 42 4627 self.assertEqual(b.__dict__, {'foo': 42}) 4628 4629 class C(B[int]): 4630 pass 4631 4632 c = C() 4633 c.bar = 'abc' 4634 self.assertEqual(c.__dict__, {'bar': 'abc'}) 4635 4636 def test_setattr_exceptions(self): 4637 class Immutable[T]: 4638 def __setattr__(self, key, value): 4639 raise RuntimeError("immutable") 4640 4641 # gh-115165: This used to cause RuntimeError to be raised 4642 # when we tried to set `__orig_class__` on the `Immutable` instance 4643 # returned by the `Immutable[int]()` call 4644 self.assertIsInstance(Immutable[int](), Immutable) 4645 4646 def test_subscripted_generics_as_proxies(self): 4647 T = TypeVar('T') 4648 class C(Generic[T]): 4649 x = 'def' 4650 self.assertEqual(C[int].x, 'def') 4651 self.assertEqual(C[C[int]].x, 'def') 4652 C[C[int]].x = 'changed' 4653 self.assertEqual(C.x, 'changed') 4654 self.assertEqual(C[str].x, 'changed') 4655 C[List[str]].z = 'new' 4656 self.assertEqual(C.z, 'new') 4657 self.assertEqual(C[Tuple[int]].z, 'new') 4658 4659 self.assertEqual(C().x, 'changed') 4660 self.assertEqual(C[Tuple[str]]().z, 'new') 4661 4662 class D(C[T]): 4663 pass 4664 self.assertEqual(D[int].x, 'changed') 4665 self.assertEqual(D.z, 'new') 4666 D.z = 'from derived z' 4667 D[int].x = 'from derived x' 4668 self.assertEqual(C.x, 'changed') 4669 self.assertEqual(C[int].z, 'new') 4670 self.assertEqual(D.x, 'from derived x') 4671 self.assertEqual(D[str].z, 'from derived z') 4672 4673 def test_abc_registry_kept(self): 4674 T = TypeVar('T') 4675 class C(collections.abc.Mapping, Generic[T]): ... 4676 C.register(int) 4677 self.assertIsInstance(1, C) 4678 C[int] 4679 self.assertIsInstance(1, C) 4680 C._abc_registry_clear() 4681 C._abc_caches_clear() # To keep refleak hunting mode clean 4682 4683 def test_false_subclasses(self): 4684 class MyMapping(MutableMapping[str, str]): pass 4685 self.assertNotIsInstance({}, MyMapping) 4686 self.assertNotIsSubclass(dict, MyMapping) 4687 4688 def test_abc_bases(self): 4689 class MM(MutableMapping[str, str]): 4690 def __getitem__(self, k): 4691 return None 4692 def __setitem__(self, k, v): 4693 pass 4694 def __delitem__(self, k): 4695 pass 4696 def __iter__(self): 4697 return iter(()) 4698 def __len__(self): 4699 return 0 4700 # this should just work 4701 MM().update() 4702 self.assertIsInstance(MM(), collections.abc.MutableMapping) 4703 self.assertIsInstance(MM(), MutableMapping) 4704 self.assertNotIsInstance(MM(), List) 4705 self.assertNotIsInstance({}, MM) 4706 4707 def test_multiple_bases(self): 4708 class MM1(MutableMapping[str, str], collections.abc.MutableMapping): 4709 pass 4710 class MM2(collections.abc.MutableMapping, MutableMapping[str, str]): 4711 pass 4712 self.assertEqual(MM2.__bases__, (collections.abc.MutableMapping, Generic)) 4713 4714 def test_orig_bases(self): 4715 T = TypeVar('T') 4716 class C(typing.Dict[str, T]): ... 4717 self.assertEqual(C.__orig_bases__, (typing.Dict[str, T],)) 4718 4719 def test_naive_runtime_checks(self): 4720 def naive_dict_check(obj, tp): 4721 # Check if a dictionary conforms to Dict type 4722 if len(tp.__parameters__) > 0: 4723 raise NotImplementedError 4724 if tp.__args__: 4725 KT, VT = tp.__args__ 4726 return all( 4727 isinstance(k, KT) and isinstance(v, VT) 4728 for k, v in obj.items() 4729 ) 4730 self.assertTrue(naive_dict_check({'x': 1}, typing.Dict[str, int])) 4731 self.assertFalse(naive_dict_check({1: 'x'}, typing.Dict[str, int])) 4732 with self.assertRaises(NotImplementedError): 4733 naive_dict_check({1: 'x'}, typing.Dict[str, T]) 4734 4735 def naive_generic_check(obj, tp): 4736 # Check if an instance conforms to the generic class 4737 if not hasattr(obj, '__orig_class__'): 4738 raise NotImplementedError 4739 return obj.__orig_class__ == tp 4740 class Node(Generic[T]): ... 4741 self.assertTrue(naive_generic_check(Node[int](), Node[int])) 4742 self.assertFalse(naive_generic_check(Node[str](), Node[int])) 4743 self.assertFalse(naive_generic_check(Node[str](), List)) 4744 with self.assertRaises(NotImplementedError): 4745 naive_generic_check([1, 2, 3], Node[int]) 4746 4747 def naive_list_base_check(obj, tp): 4748 # Check if list conforms to a List subclass 4749 return all(isinstance(x, tp.__orig_bases__[0].__args__[0]) 4750 for x in obj) 4751 class C(List[int]): ... 4752 self.assertTrue(naive_list_base_check([1, 2, 3], C)) 4753 self.assertFalse(naive_list_base_check(['a', 'b'], C)) 4754 4755 def test_multi_subscr_base(self): 4756 T = TypeVar('T') 4757 U = TypeVar('U') 4758 V = TypeVar('V') 4759 class C(List[T][U][V]): ... 4760 class D(C, List[T][U][V]): ... 4761 self.assertEqual(C.__parameters__, (V,)) 4762 self.assertEqual(D.__parameters__, (V,)) 4763 self.assertEqual(C[int].__parameters__, ()) 4764 self.assertEqual(D[int].__parameters__, ()) 4765 self.assertEqual(C[int].__args__, (int,)) 4766 self.assertEqual(D[int].__args__, (int,)) 4767 self.assertEqual(C.__bases__, (list, Generic)) 4768 self.assertEqual(D.__bases__, (C, list, Generic)) 4769 self.assertEqual(C.__orig_bases__, (List[T][U][V],)) 4770 self.assertEqual(D.__orig_bases__, (C, List[T][U][V])) 4771 4772 def test_subscript_meta(self): 4773 T = TypeVar('T') 4774 class Meta(type): ... 4775 self.assertEqual(Type[Meta], Type[Meta]) 4776 self.assertEqual(Union[T, int][Meta], Union[Meta, int]) 4777 self.assertEqual(Callable[..., Meta].__args__, (Ellipsis, Meta)) 4778 4779 def test_generic_hashes(self): 4780 class A(Generic[T]): 4781 ... 4782 4783 class B(Generic[T]): 4784 class A(Generic[T]): 4785 ... 4786 4787 self.assertEqual(A, A) 4788 self.assertEqual(mod_generics_cache.A[str], mod_generics_cache.A[str]) 4789 self.assertEqual(B.A, B.A) 4790 self.assertEqual(mod_generics_cache.B.A[B.A[str]], 4791 mod_generics_cache.B.A[B.A[str]]) 4792 4793 self.assertNotEqual(A, B.A) 4794 self.assertNotEqual(A, mod_generics_cache.A) 4795 self.assertNotEqual(A, mod_generics_cache.B.A) 4796 self.assertNotEqual(B.A, mod_generics_cache.A) 4797 self.assertNotEqual(B.A, mod_generics_cache.B.A) 4798 4799 self.assertNotEqual(A[str], B.A[str]) 4800 self.assertNotEqual(A[List[Any]], B.A[List[Any]]) 4801 self.assertNotEqual(A[str], mod_generics_cache.A[str]) 4802 self.assertNotEqual(A[str], mod_generics_cache.B.A[str]) 4803 self.assertNotEqual(B.A[int], mod_generics_cache.A[int]) 4804 self.assertNotEqual(B.A[List[Any]], mod_generics_cache.B.A[List[Any]]) 4805 4806 self.assertNotEqual(Tuple[A[str]], Tuple[B.A[str]]) 4807 self.assertNotEqual(Tuple[A[List[Any]]], Tuple[B.A[List[Any]]]) 4808 self.assertNotEqual(Union[str, A[str]], Union[str, mod_generics_cache.A[str]]) 4809 self.assertNotEqual(Union[A[str], A[str]], 4810 Union[A[str], mod_generics_cache.A[str]]) 4811 self.assertNotEqual(typing.FrozenSet[A[str]], 4812 typing.FrozenSet[mod_generics_cache.B.A[str]]) 4813 4814 self.assertTrue(repr(Tuple[A[str]]).endswith('<locals>.A[str]]')) 4815 self.assertTrue(repr(Tuple[B.A[str]]).endswith('<locals>.B.A[str]]')) 4816 self.assertTrue(repr(Tuple[mod_generics_cache.A[str]]) 4817 .endswith('mod_generics_cache.A[str]]')) 4818 self.assertTrue(repr(Tuple[mod_generics_cache.B.A[str]]) 4819 .endswith('mod_generics_cache.B.A[str]]')) 4820 4821 def test_extended_generic_rules_eq(self): 4822 T = TypeVar('T') 4823 U = TypeVar('U') 4824 self.assertEqual(Tuple[T, T][int], Tuple[int, int]) 4825 self.assertEqual(typing.Iterable[Tuple[T, T]][T], typing.Iterable[Tuple[T, T]]) 4826 with self.assertRaises(TypeError): 4827 Tuple[T, int][()] 4828 4829 self.assertEqual(Union[T, int][int], int) 4830 self.assertEqual(Union[T, U][int, Union[int, str]], Union[int, str]) 4831 class Base: ... 4832 class Derived(Base): ... 4833 self.assertEqual(Union[T, Base][Union[Base, Derived]], Union[Base, Derived]) 4834 self.assertEqual(Callable[[T], T][KT], Callable[[KT], KT]) 4835 self.assertEqual(Callable[..., List[T]][int], Callable[..., List[int]]) 4836 4837 def test_extended_generic_rules_repr(self): 4838 T = TypeVar('T') 4839 self.assertEqual(repr(Union[Tuple, Callable]).replace('typing.', ''), 4840 'Union[Tuple, Callable]') 4841 self.assertEqual(repr(Union[Tuple, Tuple[int]]).replace('typing.', ''), 4842 'Union[Tuple, Tuple[int]]') 4843 self.assertEqual(repr(Callable[..., Optional[T]][int]).replace('typing.', ''), 4844 'Callable[..., Optional[int]]') 4845 self.assertEqual(repr(Callable[[], List[T]][int]).replace('typing.', ''), 4846 'Callable[[], List[int]]') 4847 4848 def test_generic_forward_ref(self): 4849 def foobar(x: List[List['CC']]): ... 4850 def foobar2(x: list[list[ForwardRef('CC')]]): ... 4851 def foobar3(x: list[ForwardRef('CC | int')] | int): ... 4852 class CC: ... 4853 self.assertEqual( 4854 get_type_hints(foobar, globals(), locals()), 4855 {'x': List[List[CC]]} 4856 ) 4857 self.assertEqual( 4858 get_type_hints(foobar2, globals(), locals()), 4859 {'x': list[list[CC]]} 4860 ) 4861 self.assertEqual( 4862 get_type_hints(foobar3, globals(), locals()), 4863 {'x': list[CC | int] | int} 4864 ) 4865 4866 T = TypeVar('T') 4867 AT = Tuple[T, ...] 4868 def barfoo(x: AT): ... 4869 self.assertIs(get_type_hints(barfoo, globals(), locals())['x'], AT) 4870 CT = Callable[..., List[T]] 4871 def barfoo2(x: CT): ... 4872 self.assertIs(get_type_hints(barfoo2, globals(), locals())['x'], CT) 4873 4874 def test_generic_pep585_forward_ref(self): 4875 # See https://bugs.python.org/issue41370 4876 4877 class C1: 4878 a: list['C1'] 4879 self.assertEqual( 4880 get_type_hints(C1, globals(), locals()), 4881 {'a': list[C1]} 4882 ) 4883 4884 class C2: 4885 a: dict['C1', list[List[list['C2']]]] 4886 self.assertEqual( 4887 get_type_hints(C2, globals(), locals()), 4888 {'a': dict[C1, list[List[list[C2]]]]} 4889 ) 4890 4891 # Test stringified annotations 4892 scope = {} 4893 exec(textwrap.dedent(''' 4894 from __future__ import annotations 4895 class C3: 4896 a: List[list["C2"]] 4897 '''), scope) 4898 C3 = scope['C3'] 4899 self.assertEqual(C3.__annotations__['a'], "List[list['C2']]") 4900 self.assertEqual( 4901 get_type_hints(C3, globals(), locals()), 4902 {'a': List[list[C2]]} 4903 ) 4904 4905 # Test recursive types 4906 X = list["X"] 4907 def f(x: X): ... 4908 self.assertEqual( 4909 get_type_hints(f, globals(), locals()), 4910 {'x': list[list[ForwardRef('X')]]} 4911 ) 4912 4913 def test_pep695_generic_class_with_future_annotations(self): 4914 original_globals = dict(ann_module695.__dict__) 4915 4916 hints_for_A = get_type_hints(ann_module695.A) 4917 A_type_params = ann_module695.A.__type_params__ 4918 self.assertIs(hints_for_A["x"], A_type_params[0]) 4919 self.assertEqual(hints_for_A["y"].__args__[0], Unpack[A_type_params[1]]) 4920 self.assertIs(hints_for_A["z"].__args__[0], A_type_params[2]) 4921 4922 # should not have changed as a result of the get_type_hints() calls! 4923 self.assertEqual(ann_module695.__dict__, original_globals) 4924 4925 def test_pep695_generic_class_with_future_annotations_and_local_shadowing(self): 4926 hints_for_B = get_type_hints(ann_module695.B) 4927 self.assertEqual(hints_for_B, {"x": int, "y": str, "z": bytes}) 4928 4929 def test_pep695_generic_class_with_future_annotations_name_clash_with_global_vars(self): 4930 hints_for_C = get_type_hints(ann_module695.C) 4931 self.assertEqual( 4932 set(hints_for_C.values()), 4933 set(ann_module695.C.__type_params__) 4934 ) 4935 4936 def test_pep_695_generic_function_with_future_annotations(self): 4937 hints_for_generic_function = get_type_hints(ann_module695.generic_function) 4938 func_t_params = ann_module695.generic_function.__type_params__ 4939 self.assertEqual( 4940 hints_for_generic_function.keys(), {"x", "y", "z", "zz", "return"} 4941 ) 4942 self.assertIs(hints_for_generic_function["x"], func_t_params[0]) 4943 self.assertEqual(hints_for_generic_function["y"], Unpack[func_t_params[1]]) 4944 self.assertIs(hints_for_generic_function["z"].__origin__, func_t_params[2]) 4945 self.assertIs(hints_for_generic_function["zz"].__origin__, func_t_params[2]) 4946 4947 def test_pep_695_generic_function_with_future_annotations_name_clash_with_global_vars(self): 4948 self.assertEqual( 4949 set(get_type_hints(ann_module695.generic_function_2).values()), 4950 set(ann_module695.generic_function_2.__type_params__) 4951 ) 4952 4953 def test_pep_695_generic_method_with_future_annotations(self): 4954 hints_for_generic_method = get_type_hints(ann_module695.D.generic_method) 4955 params = { 4956 param.__name__: param 4957 for param in ann_module695.D.generic_method.__type_params__ 4958 } 4959 self.assertEqual( 4960 hints_for_generic_method, 4961 {"x": params["Foo"], "y": params["Bar"], "return": types.NoneType} 4962 ) 4963 4964 def test_pep_695_generic_method_with_future_annotations_name_clash_with_global_vars(self): 4965 self.assertEqual( 4966 set(get_type_hints(ann_module695.D.generic_method_2).values()), 4967 set(ann_module695.D.generic_method_2.__type_params__) 4968 ) 4969 4970 def test_pep_695_generics_with_future_annotations_nested_in_function(self): 4971 results = ann_module695.nested() 4972 4973 self.assertEqual( 4974 set(results.hints_for_E.values()), 4975 set(results.E.__type_params__) 4976 ) 4977 self.assertEqual( 4978 set(results.hints_for_E_meth.values()), 4979 set(results.E.generic_method.__type_params__) 4980 ) 4981 self.assertNotEqual( 4982 set(results.hints_for_E_meth.values()), 4983 set(results.E.__type_params__) 4984 ) 4985 self.assertEqual( 4986 set(results.hints_for_E_meth.values()).intersection(results.E.__type_params__), 4987 set() 4988 ) 4989 4990 self.assertEqual( 4991 set(results.hints_for_generic_func.values()), 4992 set(results.generic_func.__type_params__) 4993 ) 4994 4995 def test_extended_generic_rules_subclassing(self): 4996 class T1(Tuple[T, KT]): ... 4997 class T2(Tuple[T, ...]): ... 4998 class C1(typing.Container[T]): 4999 def __contains__(self, item): 5000 return False 5001 5002 self.assertEqual(T1.__parameters__, (T, KT)) 5003 self.assertEqual(T1[int, str].__args__, (int, str)) 5004 self.assertEqual(T1[int, T].__origin__, T1) 5005 5006 self.assertEqual(T2.__parameters__, (T,)) 5007 # These don't work because of tuple.__class_item__ 5008 ## with self.assertRaises(TypeError): 5009 ## T1[int] 5010 ## with self.assertRaises(TypeError): 5011 ## T2[int, str] 5012 5013 self.assertEqual(repr(C1[int]).split('.')[-1], 'C1[int]') 5014 self.assertEqual(C1.__parameters__, (T,)) 5015 self.assertIsInstance(C1(), collections.abc.Container) 5016 self.assertIsSubclass(C1, collections.abc.Container) 5017 self.assertIsInstance(T1(), tuple) 5018 self.assertIsSubclass(T2, tuple) 5019 with self.assertRaises(TypeError): 5020 issubclass(Tuple[int, ...], typing.Sequence) 5021 with self.assertRaises(TypeError): 5022 issubclass(Tuple[int, ...], typing.Iterable) 5023 5024 def test_fail_with_bare_union(self): 5025 with self.assertRaises(TypeError): 5026 List[Union] 5027 with self.assertRaises(TypeError): 5028 Tuple[Optional] 5029 with self.assertRaises(TypeError): 5030 List[ClassVar[int]] 5031 5032 def test_fail_with_bare_generic(self): 5033 T = TypeVar('T') 5034 with self.assertRaises(TypeError): 5035 List[Generic] 5036 with self.assertRaises(TypeError): 5037 Tuple[Generic[T]] 5038 with self.assertRaises(TypeError): 5039 List[typing.Protocol] 5040 5041 def test_type_erasure_special(self): 5042 T = TypeVar('T') 5043 # this is the only test that checks type caching 5044 self.clear_caches() 5045 class MyTup(Tuple[T, T]): ... 5046 self.assertIs(MyTup[int]().__class__, MyTup) 5047 self.assertEqual(MyTup[int]().__orig_class__, MyTup[int]) 5048 class MyDict(typing.Dict[T, T]): ... 5049 self.assertIs(MyDict[int]().__class__, MyDict) 5050 self.assertEqual(MyDict[int]().__orig_class__, MyDict[int]) 5051 class MyDef(typing.DefaultDict[str, T]): ... 5052 self.assertIs(MyDef[int]().__class__, MyDef) 5053 self.assertEqual(MyDef[int]().__orig_class__, MyDef[int]) 5054 class MyChain(typing.ChainMap[str, T]): ... 5055 self.assertIs(MyChain[int]().__class__, MyChain) 5056 self.assertEqual(MyChain[int]().__orig_class__, MyChain[int]) 5057 5058 def test_all_repr_eq_any(self): 5059 objs = (getattr(typing, el) for el in typing.__all__) 5060 for obj in objs: 5061 self.assertNotEqual(repr(obj), '') 5062 self.assertEqual(obj, obj) 5063 if (getattr(obj, '__parameters__', None) 5064 and not isinstance(obj, typing.TypeVar) 5065 and isinstance(obj.__parameters__, tuple) 5066 and len(obj.__parameters__) == 1): 5067 self.assertEqual(obj[Any].__args__, (Any,)) 5068 if isinstance(obj, type): 5069 for base in obj.__mro__: 5070 self.assertNotEqual(repr(base), '') 5071 self.assertEqual(base, base) 5072 5073 def test_pickle(self): 5074 global C # pickle wants to reference the class by name 5075 T = TypeVar('T') 5076 5077 class B(Generic[T]): 5078 pass 5079 5080 class C(B[int]): 5081 pass 5082 5083 c = C() 5084 c.foo = 42 5085 c.bar = 'abc' 5086 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 5087 z = pickle.dumps(c, proto) 5088 x = pickle.loads(z) 5089 self.assertEqual(x.foo, 42) 5090 self.assertEqual(x.bar, 'abc') 5091 self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) 5092 samples = [Any, Union, Tuple, Callable, ClassVar, 5093 Union[int, str], ClassVar[List], Tuple[int, ...], Tuple[()], 5094 Callable[[str], bytes], 5095 typing.DefaultDict, typing.FrozenSet[int]] 5096 for s in samples: 5097 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 5098 z = pickle.dumps(s, proto) 5099 x = pickle.loads(z) 5100 self.assertEqual(s, x) 5101 more_samples = [List, typing.Iterable, typing.Type, List[int], 5102 typing.Type[typing.Mapping], typing.AbstractSet[Tuple[int, str]]] 5103 for s in more_samples: 5104 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 5105 z = pickle.dumps(s, proto) 5106 x = pickle.loads(z) 5107 self.assertEqual(s, x) 5108 5109 def test_copy_and_deepcopy(self): 5110 T = TypeVar('T') 5111 class Node(Generic[T]): ... 5112 things = [Union[T, int], Tuple[T, int], Tuple[()], 5113 Callable[..., T], Callable[[int], int], 5114 Tuple[Any, Any], Node[T], Node[int], Node[Any], typing.Iterable[T], 5115 typing.Iterable[Any], typing.Iterable[int], typing.Dict[int, str], 5116 typing.Dict[T, Any], ClassVar[int], ClassVar[List[T]], Tuple['T', 'T'], 5117 Union['T', int], List['T'], typing.Mapping['T', int]] 5118 for t in things + [Any]: 5119 self.assertEqual(t, copy(t)) 5120 self.assertEqual(t, deepcopy(t)) 5121 5122 def test_immutability_by_copy_and_pickle(self): 5123 # Special forms like Union, Any, etc., generic aliases to containers like List, 5124 # Mapping, etc., and type variabcles are considered immutable by copy and pickle. 5125 global TP, TPB, TPV, PP # for pickle 5126 TP = TypeVar('TP') 5127 TPB = TypeVar('TPB', bound=int) 5128 TPV = TypeVar('TPV', bytes, str) 5129 PP = ParamSpec('PP') 5130 for X in [TP, TPB, TPV, PP, 5131 List, typing.Mapping, ClassVar, typing.Iterable, 5132 Union, Any, Tuple, Callable]: 5133 with self.subTest(thing=X): 5134 self.assertIs(copy(X), X) 5135 self.assertIs(deepcopy(X), X) 5136 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 5137 self.assertIs(pickle.loads(pickle.dumps(X, proto)), X) 5138 del TP, TPB, TPV, PP 5139 5140 # Check that local type variables are copyable. 5141 TL = TypeVar('TL') 5142 TLB = TypeVar('TLB', bound=int) 5143 TLV = TypeVar('TLV', bytes, str) 5144 PL = ParamSpec('PL') 5145 for X in [TL, TLB, TLV, PL]: 5146 with self.subTest(thing=X): 5147 self.assertIs(copy(X), X) 5148 self.assertIs(deepcopy(X), X) 5149 5150 def test_copy_generic_instances(self): 5151 T = TypeVar('T') 5152 class C(Generic[T]): 5153 def __init__(self, attr: T) -> None: 5154 self.attr = attr 5155 5156 c = C(42) 5157 self.assertEqual(copy(c).attr, 42) 5158 self.assertEqual(deepcopy(c).attr, 42) 5159 self.assertIsNot(copy(c), c) 5160 self.assertIsNot(deepcopy(c), c) 5161 c.attr = 1 5162 self.assertEqual(copy(c).attr, 1) 5163 self.assertEqual(deepcopy(c).attr, 1) 5164 ci = C[int](42) 5165 self.assertEqual(copy(ci).attr, 42) 5166 self.assertEqual(deepcopy(ci).attr, 42) 5167 self.assertIsNot(copy(ci), ci) 5168 self.assertIsNot(deepcopy(ci), ci) 5169 ci.attr = 1 5170 self.assertEqual(copy(ci).attr, 1) 5171 self.assertEqual(deepcopy(ci).attr, 1) 5172 self.assertEqual(ci.__orig_class__, C[int]) 5173 5174 def test_weakref_all(self): 5175 T = TypeVar('T') 5176 things = [Any, Union[T, int], Callable[..., T], Tuple[Any, Any], 5177 Optional[List[int]], typing.Mapping[int, str], 5178 typing.Match[bytes], typing.Iterable['whatever']] 5179 for t in things: 5180 self.assertEqual(weakref.ref(t)(), t) 5181 5182 def test_parameterized_slots(self): 5183 T = TypeVar('T') 5184 class C(Generic[T]): 5185 __slots__ = ('potato',) 5186 5187 c = C() 5188 c_int = C[int]() 5189 5190 c.potato = 0 5191 c_int.potato = 0 5192 with self.assertRaises(AttributeError): 5193 c.tomato = 0 5194 with self.assertRaises(AttributeError): 5195 c_int.tomato = 0 5196 5197 def foo(x: C['C']): ... 5198 self.assertEqual(get_type_hints(foo, globals(), locals())['x'], C[C]) 5199 self.assertEqual(copy(C[int]), deepcopy(C[int])) 5200 5201 def test_parameterized_slots_dict(self): 5202 T = TypeVar('T') 5203 class D(Generic[T]): 5204 __slots__ = {'banana': 42} 5205 5206 d = D() 5207 d_int = D[int]() 5208 5209 d.banana = 'yes' 5210 d_int.banana = 'yes' 5211 with self.assertRaises(AttributeError): 5212 d.foobar = 'no' 5213 with self.assertRaises(AttributeError): 5214 d_int.foobar = 'no' 5215 5216 def test_errors(self): 5217 with self.assertRaises(TypeError): 5218 B = SimpleMapping[XK, Any] 5219 5220 class C(Generic[B]): 5221 pass 5222 5223 def test_repr_2(self): 5224 class C(Generic[T]): 5225 pass 5226 5227 self.assertEqual(C.__module__, __name__) 5228 self.assertEqual(C.__qualname__, 5229 'GenericTests.test_repr_2.<locals>.C') 5230 X = C[int] 5231 self.assertEqual(X.__module__, __name__) 5232 self.assertEqual(repr(X).split('.')[-1], 'C[int]') 5233 5234 class Y(C[int]): 5235 pass 5236 5237 self.assertEqual(Y.__module__, __name__) 5238 self.assertEqual(Y.__qualname__, 5239 'GenericTests.test_repr_2.<locals>.Y') 5240 5241 def test_repr_3(self): 5242 T = TypeVar('T') 5243 T1 = TypeVar('T1') 5244 P = ParamSpec('P') 5245 P2 = ParamSpec('P2') 5246 Ts = TypeVarTuple('Ts') 5247 5248 class MyCallable(Generic[P, T]): 5249 pass 5250 5251 class DoubleSpec(Generic[P, P2, T]): 5252 pass 5253 5254 class TsP(Generic[*Ts, P]): 5255 pass 5256 5257 object_to_expected_repr = { 5258 MyCallable[P, T]: "MyCallable[~P, ~T]", 5259 MyCallable[Concatenate[T1, P], T]: "MyCallable[typing.Concatenate[~T1, ~P], ~T]", 5260 MyCallable[[], bool]: "MyCallable[[], bool]", 5261 MyCallable[[int], bool]: "MyCallable[[int], bool]", 5262 MyCallable[[int, str], bool]: "MyCallable[[int, str], bool]", 5263 MyCallable[[int, list[int]], bool]: "MyCallable[[int, list[int]], bool]", 5264 MyCallable[Concatenate[*Ts, P], T]: "MyCallable[typing.Concatenate[typing.Unpack[Ts], ~P], ~T]", 5265 5266 DoubleSpec[P2, P, T]: "DoubleSpec[~P2, ~P, ~T]", 5267 DoubleSpec[[int], [str], bool]: "DoubleSpec[[int], [str], bool]", 5268 DoubleSpec[[int, int], [str, str], bool]: "DoubleSpec[[int, int], [str, str], bool]", 5269 5270 TsP[*Ts, P]: "TsP[typing.Unpack[Ts], ~P]", 5271 TsP[int, str, list[int], []]: "TsP[int, str, list[int], []]", 5272 TsP[int, [str, list[int]]]: "TsP[int, [str, list[int]]]", 5273 5274 # These lines are just too long to fit: 5275 MyCallable[Concatenate[*Ts, P], int][int, str, [bool, float]]: 5276 "MyCallable[[int, str, bool, float], int]", 5277 } 5278 5279 for obj, expected_repr in object_to_expected_repr.items(): 5280 with self.subTest(obj=obj, expected_repr=expected_repr): 5281 self.assertRegex( 5282 repr(obj), 5283 fr"^{re.escape(MyCallable.__module__)}.*\.{re.escape(expected_repr)}$", 5284 ) 5285 5286 def test_eq_1(self): 5287 self.assertEqual(Generic, Generic) 5288 self.assertEqual(Generic[T], Generic[T]) 5289 self.assertNotEqual(Generic[KT], Generic[VT]) 5290 5291 def test_eq_2(self): 5292 5293 class A(Generic[T]): 5294 pass 5295 5296 class B(Generic[T]): 5297 pass 5298 5299 self.assertEqual(A, A) 5300 self.assertNotEqual(A, B) 5301 self.assertEqual(A[T], A[T]) 5302 self.assertNotEqual(A[T], B[T]) 5303 5304 def test_multiple_inheritance(self): 5305 5306 class A(Generic[T, VT]): 5307 pass 5308 5309 class B(Generic[KT, T]): 5310 pass 5311 5312 class C(A[T, VT], Generic[VT, T, KT], B[KT, T]): 5313 pass 5314 5315 self.assertEqual(C.__parameters__, (VT, T, KT)) 5316 5317 def test_multiple_inheritance_special(self): 5318 S = TypeVar('S') 5319 class B(Generic[S]): ... 5320 class C(List[int], B): ... 5321 self.assertEqual(C.__mro__, (C, list, B, Generic, object)) 5322 5323 def test_multiple_inheritance_non_type_with___mro_entries__(self): 5324 class GoodEntries: 5325 def __mro_entries__(self, bases): 5326 return (object,) 5327 5328 class A(List[int], GoodEntries()): ... 5329 5330 self.assertEqual(A.__mro__, (A, list, Generic, object)) 5331 5332 def test_multiple_inheritance_non_type_without___mro_entries__(self): 5333 # Error should be from the type machinery, not from typing.py 5334 with self.assertRaisesRegex(TypeError, r"^bases must be types"): 5335 class A(List[int], object()): ... 5336 5337 def test_multiple_inheritance_non_type_bad___mro_entries__(self): 5338 class BadEntries: 5339 def __mro_entries__(self, bases): 5340 return None 5341 5342 # Error should be from the type machinery, not from typing.py 5343 with self.assertRaisesRegex( 5344 TypeError, 5345 r"^__mro_entries__ must return a tuple", 5346 ): 5347 class A(List[int], BadEntries()): ... 5348 5349 def test_multiple_inheritance___mro_entries___returns_non_type(self): 5350 class BadEntries: 5351 def __mro_entries__(self, bases): 5352 return (object(),) 5353 5354 # Error should be from the type machinery, not from typing.py 5355 with self.assertRaisesRegex( 5356 TypeError, 5357 r"^bases must be types", 5358 ): 5359 class A(List[int], BadEntries()): ... 5360 5361 def test_multiple_inheritance_with_genericalias(self): 5362 class A(typing.Sized, list[int]): ... 5363 5364 self.assertEqual( 5365 A.__mro__, 5366 (A, collections.abc.Sized, Generic, list, object), 5367 ) 5368 5369 def test_multiple_inheritance_with_genericalias_2(self): 5370 T = TypeVar("T") 5371 5372 class BaseSeq(typing.Sequence[T]): ... 5373 class MySeq(List[T], BaseSeq[T]): ... 5374 5375 self.assertEqual( 5376 MySeq.__mro__, 5377 ( 5378 MySeq, 5379 list, 5380 BaseSeq, 5381 collections.abc.Sequence, 5382 collections.abc.Reversible, 5383 collections.abc.Collection, 5384 collections.abc.Sized, 5385 collections.abc.Iterable, 5386 collections.abc.Container, 5387 Generic, 5388 object, 5389 ), 5390 ) 5391 5392 def test_init_subclass_super_called(self): 5393 class FinalException(Exception): 5394 pass 5395 5396 class Final: 5397 def __init_subclass__(cls, **kwargs) -> None: 5398 for base in cls.__bases__: 5399 if base is not Final and issubclass(base, Final): 5400 raise FinalException(base) 5401 super().__init_subclass__(**kwargs) 5402 class Test(Generic[T], Final): 5403 pass 5404 with self.assertRaises(FinalException): 5405 class Subclass(Test): 5406 pass 5407 with self.assertRaises(FinalException): 5408 class Subclass2(Test[int]): 5409 pass 5410 5411 def test_nested(self): 5412 5413 G = Generic 5414 5415 class Visitor(G[T]): 5416 5417 a = None 5418 5419 def set(self, a: T): 5420 self.a = a 5421 5422 def get(self): 5423 return self.a 5424 5425 def visit(self) -> T: 5426 return self.a 5427 5428 V = Visitor[typing.List[int]] 5429 5430 class IntListVisitor(V): 5431 5432 def append(self, x: int): 5433 self.a.append(x) 5434 5435 a = IntListVisitor() 5436 a.set([]) 5437 a.append(1) 5438 a.append(42) 5439 self.assertEqual(a.get(), [1, 42]) 5440 5441 def test_type_erasure(self): 5442 T = TypeVar('T') 5443 5444 class Node(Generic[T]): 5445 def __init__(self, label: T, 5446 left: 'Node[T]' = None, 5447 right: 'Node[T]' = None): 5448 self.label = label # type: T 5449 self.left = left # type: Optional[Node[T]] 5450 self.right = right # type: Optional[Node[T]] 5451 5452 def foo(x: T): 5453 a = Node(x) 5454 b = Node[T](x) 5455 c = Node[Any](x) 5456 self.assertIs(type(a), Node) 5457 self.assertIs(type(b), Node) 5458 self.assertIs(type(c), Node) 5459 self.assertEqual(a.label, x) 5460 self.assertEqual(b.label, x) 5461 self.assertEqual(c.label, x) 5462 5463 foo(42) 5464 5465 def test_implicit_any(self): 5466 T = TypeVar('T') 5467 5468 class C(Generic[T]): 5469 pass 5470 5471 class D(C): 5472 pass 5473 5474 self.assertEqual(D.__parameters__, ()) 5475 5476 with self.assertRaises(TypeError): 5477 D[int] 5478 with self.assertRaises(TypeError): 5479 D[Any] 5480 with self.assertRaises(TypeError): 5481 D[T] 5482 5483 def test_new_with_args(self): 5484 5485 class A(Generic[T]): 5486 pass 5487 5488 class B: 5489 def __new__(cls, arg): 5490 # call object 5491 obj = super().__new__(cls) 5492 obj.arg = arg 5493 return obj 5494 5495 # mro: C, A, Generic, B, object 5496 class C(A, B): 5497 pass 5498 5499 c = C('foo') 5500 self.assertEqual(c.arg, 'foo') 5501 5502 def test_new_with_args2(self): 5503 5504 class A: 5505 def __init__(self, arg): 5506 self.from_a = arg 5507 # call object 5508 super().__init__() 5509 5510 # mro: C, Generic, A, object 5511 class C(Generic[T], A): 5512 def __init__(self, arg): 5513 self.from_c = arg 5514 # call Generic 5515 super().__init__(arg) 5516 5517 c = C('foo') 5518 self.assertEqual(c.from_a, 'foo') 5519 self.assertEqual(c.from_c, 'foo') 5520 5521 def test_new_no_args(self): 5522 5523 class A(Generic[T]): 5524 pass 5525 5526 with self.assertRaises(TypeError): 5527 A('foo') 5528 5529 class B: 5530 def __new__(cls): 5531 # call object 5532 obj = super().__new__(cls) 5533 obj.from_b = 'b' 5534 return obj 5535 5536 # mro: C, A, Generic, B, object 5537 class C(A, B): 5538 def __init__(self, arg): 5539 self.arg = arg 5540 5541 def __new__(cls, arg): 5542 # call A 5543 obj = super().__new__(cls) 5544 obj.from_c = 'c' 5545 return obj 5546 5547 c = C('foo') 5548 self.assertEqual(c.arg, 'foo') 5549 self.assertEqual(c.from_b, 'b') 5550 self.assertEqual(c.from_c, 'c') 5551 5552 def test_subclass_special_form(self): 5553 for obj in ( 5554 ClassVar[int], 5555 Final[int], 5556 Union[int, float], 5557 Optional[int], 5558 Literal[1, 2], 5559 Concatenate[int, ParamSpec("P")], 5560 TypeGuard[int], 5561 TypeIs[range], 5562 ): 5563 with self.subTest(msg=obj): 5564 with self.assertRaisesRegex( 5565 TypeError, f'^{re.escape(f"Cannot subclass {obj!r}")}$' 5566 ): 5567 class Foo(obj): 5568 pass 5569 5570 def test_complex_subclasses(self): 5571 T_co = TypeVar("T_co", covariant=True) 5572 5573 class Base(Generic[T_co]): 5574 ... 5575 5576 T = TypeVar("T") 5577 5578 # see gh-94607: this fails in that bug 5579 class Sub(Base, Generic[T]): 5580 ... 5581 5582 def test_parameter_detection(self): 5583 self.assertEqual(List[T].__parameters__, (T,)) 5584 self.assertEqual(List[List[T]].__parameters__, (T,)) 5585 class A: 5586 __parameters__ = (T,) 5587 # Bare classes should be skipped 5588 for a in (List, list): 5589 for b in (A, int, TypeVar, TypeVarTuple, ParamSpec, types.GenericAlias, types.UnionType): 5590 with self.subTest(generic=a, sub=b): 5591 with self.assertRaisesRegex(TypeError, '.* is not a generic class'): 5592 a[b][str] 5593 # Duck-typing anything that looks like it has __parameters__. 5594 # These tests are optional and failure is okay. 5595 self.assertEqual(List[A()].__parameters__, (T,)) 5596 # C version of GenericAlias 5597 self.assertEqual(list[A()].__parameters__, (T,)) 5598 5599 def test_non_generic_subscript(self): 5600 T = TypeVar('T') 5601 class G(Generic[T]): 5602 pass 5603 class A: 5604 __parameters__ = (T,) 5605 5606 for s in (int, G, A, List, list, 5607 TypeVar, TypeVarTuple, ParamSpec, 5608 types.GenericAlias, types.UnionType): 5609 5610 for t in Tuple, tuple: 5611 with self.subTest(tuple=t, sub=s): 5612 self.assertEqual(t[s, T][int], t[s, int]) 5613 self.assertEqual(t[T, s][int], t[int, s]) 5614 a = t[s] 5615 with self.assertRaises(TypeError): 5616 a[int] 5617 5618 for c in Callable, collections.abc.Callable: 5619 with self.subTest(callable=c, sub=s): 5620 self.assertEqual(c[[s], T][int], c[[s], int]) 5621 self.assertEqual(c[[T], s][int], c[[int], s]) 5622 a = c[[s], s] 5623 with self.assertRaises(TypeError): 5624 a[int] 5625 5626 5627class ClassVarTests(BaseTestCase): 5628 5629 def test_basics(self): 5630 with self.assertRaises(TypeError): 5631 ClassVar[int, str] 5632 with self.assertRaises(TypeError): 5633 ClassVar[int][str] 5634 5635 def test_repr(self): 5636 self.assertEqual(repr(ClassVar), 'typing.ClassVar') 5637 cv = ClassVar[int] 5638 self.assertEqual(repr(cv), 'typing.ClassVar[int]') 5639 cv = ClassVar[Employee] 5640 self.assertEqual(repr(cv), 'typing.ClassVar[%s.Employee]' % __name__) 5641 5642 def test_cannot_subclass(self): 5643 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 5644 class C(type(ClassVar)): 5645 pass 5646 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 5647 class D(type(ClassVar[int])): 5648 pass 5649 with self.assertRaisesRegex(TypeError, 5650 r'Cannot subclass typing\.ClassVar'): 5651 class E(ClassVar): 5652 pass 5653 with self.assertRaisesRegex(TypeError, 5654 r'Cannot subclass typing\.ClassVar\[int\]'): 5655 class F(ClassVar[int]): 5656 pass 5657 5658 def test_cannot_init(self): 5659 with self.assertRaises(TypeError): 5660 ClassVar() 5661 with self.assertRaises(TypeError): 5662 type(ClassVar)() 5663 with self.assertRaises(TypeError): 5664 type(ClassVar[Optional[int]])() 5665 5666 def test_no_isinstance(self): 5667 with self.assertRaises(TypeError): 5668 isinstance(1, ClassVar[int]) 5669 with self.assertRaises(TypeError): 5670 issubclass(int, ClassVar) 5671 5672class FinalTests(BaseTestCase): 5673 5674 def test_basics(self): 5675 Final[int] # OK 5676 with self.assertRaises(TypeError): 5677 Final[int, str] 5678 with self.assertRaises(TypeError): 5679 Final[int][str] 5680 with self.assertRaises(TypeError): 5681 Optional[Final[int]] 5682 5683 def test_repr(self): 5684 self.assertEqual(repr(Final), 'typing.Final') 5685 cv = Final[int] 5686 self.assertEqual(repr(cv), 'typing.Final[int]') 5687 cv = Final[Employee] 5688 self.assertEqual(repr(cv), 'typing.Final[%s.Employee]' % __name__) 5689 cv = Final[tuple[int]] 5690 self.assertEqual(repr(cv), 'typing.Final[tuple[int]]') 5691 5692 def test_cannot_subclass(self): 5693 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 5694 class C(type(Final)): 5695 pass 5696 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 5697 class D(type(Final[int])): 5698 pass 5699 with self.assertRaisesRegex(TypeError, 5700 r'Cannot subclass typing\.Final'): 5701 class E(Final): 5702 pass 5703 with self.assertRaisesRegex(TypeError, 5704 r'Cannot subclass typing\.Final\[int\]'): 5705 class F(Final[int]): 5706 pass 5707 5708 def test_cannot_init(self): 5709 with self.assertRaises(TypeError): 5710 Final() 5711 with self.assertRaises(TypeError): 5712 type(Final)() 5713 with self.assertRaises(TypeError): 5714 type(Final[Optional[int]])() 5715 5716 def test_no_isinstance(self): 5717 with self.assertRaises(TypeError): 5718 isinstance(1, Final[int]) 5719 with self.assertRaises(TypeError): 5720 issubclass(int, Final) 5721 5722 5723class FinalDecoratorTests(BaseTestCase): 5724 def test_final_unmodified(self): 5725 def func(x): ... 5726 self.assertIs(func, final(func)) 5727 5728 def test_dunder_final(self): 5729 @final 5730 def func(): ... 5731 @final 5732 class Cls: ... 5733 self.assertIs(True, func.__final__) 5734 self.assertIs(True, Cls.__final__) 5735 5736 class Wrapper: 5737 __slots__ = ("func",) 5738 def __init__(self, func): 5739 self.func = func 5740 def __call__(self, *args, **kwargs): 5741 return self.func(*args, **kwargs) 5742 5743 # Check that no error is thrown if the attribute 5744 # is not writable. 5745 @final 5746 @Wrapper 5747 def wrapped(): ... 5748 self.assertIsInstance(wrapped, Wrapper) 5749 self.assertIs(False, hasattr(wrapped, "__final__")) 5750 5751 class Meta(type): 5752 @property 5753 def __final__(self): return "can't set me" 5754 @final 5755 class WithMeta(metaclass=Meta): ... 5756 self.assertEqual(WithMeta.__final__, "can't set me") 5757 5758 # Builtin classes throw TypeError if you try to set an 5759 # attribute. 5760 final(int) 5761 self.assertIs(False, hasattr(int, "__final__")) 5762 5763 # Make sure it works with common builtin decorators 5764 class Methods: 5765 @final 5766 @classmethod 5767 def clsmethod(cls): ... 5768 5769 @final 5770 @staticmethod 5771 def stmethod(): ... 5772 5773 # The other order doesn't work because property objects 5774 # don't allow attribute assignment. 5775 @property 5776 @final 5777 def prop(self): ... 5778 5779 @final 5780 @lru_cache() 5781 def cached(self): ... 5782 5783 # Use getattr_static because the descriptor returns the 5784 # underlying function, which doesn't have __final__. 5785 self.assertIs( 5786 True, 5787 inspect.getattr_static(Methods, "clsmethod").__final__ 5788 ) 5789 self.assertIs( 5790 True, 5791 inspect.getattr_static(Methods, "stmethod").__final__ 5792 ) 5793 self.assertIs(True, Methods.prop.fget.__final__) 5794 self.assertIs(True, Methods.cached.__final__) 5795 5796 5797class OverrideDecoratorTests(BaseTestCase): 5798 def test_override(self): 5799 class Base: 5800 def normal_method(self): ... 5801 @classmethod 5802 def class_method_good_order(cls): ... 5803 @classmethod 5804 def class_method_bad_order(cls): ... 5805 @staticmethod 5806 def static_method_good_order(): ... 5807 @staticmethod 5808 def static_method_bad_order(): ... 5809 5810 class Derived(Base): 5811 @override 5812 def normal_method(self): 5813 return 42 5814 5815 @classmethod 5816 @override 5817 def class_method_good_order(cls): 5818 return 42 5819 @override 5820 @classmethod 5821 def class_method_bad_order(cls): 5822 return 42 5823 5824 @staticmethod 5825 @override 5826 def static_method_good_order(): 5827 return 42 5828 @override 5829 @staticmethod 5830 def static_method_bad_order(): 5831 return 42 5832 5833 self.assertIsSubclass(Derived, Base) 5834 instance = Derived() 5835 self.assertEqual(instance.normal_method(), 42) 5836 self.assertIs(True, Derived.normal_method.__override__) 5837 self.assertIs(True, instance.normal_method.__override__) 5838 5839 self.assertEqual(Derived.class_method_good_order(), 42) 5840 self.assertIs(True, Derived.class_method_good_order.__override__) 5841 self.assertEqual(Derived.class_method_bad_order(), 42) 5842 self.assertIs(False, hasattr(Derived.class_method_bad_order, "__override__")) 5843 5844 self.assertEqual(Derived.static_method_good_order(), 42) 5845 self.assertIs(True, Derived.static_method_good_order.__override__) 5846 self.assertEqual(Derived.static_method_bad_order(), 42) 5847 self.assertIs(False, hasattr(Derived.static_method_bad_order, "__override__")) 5848 5849 # Base object is not changed: 5850 self.assertIs(False, hasattr(Base.normal_method, "__override__")) 5851 self.assertIs(False, hasattr(Base.class_method_good_order, "__override__")) 5852 self.assertIs(False, hasattr(Base.class_method_bad_order, "__override__")) 5853 self.assertIs(False, hasattr(Base.static_method_good_order, "__override__")) 5854 self.assertIs(False, hasattr(Base.static_method_bad_order, "__override__")) 5855 5856 def test_property(self): 5857 class Base: 5858 @property 5859 def correct(self) -> int: 5860 return 1 5861 @property 5862 def wrong(self) -> int: 5863 return 1 5864 5865 class Child(Base): 5866 @property 5867 @override 5868 def correct(self) -> int: 5869 return 2 5870 @override 5871 @property 5872 def wrong(self) -> int: 5873 return 2 5874 5875 instance = Child() 5876 self.assertEqual(instance.correct, 2) 5877 self.assertTrue(Child.correct.fget.__override__) 5878 self.assertEqual(instance.wrong, 2) 5879 self.assertFalse(hasattr(Child.wrong, "__override__")) 5880 self.assertFalse(hasattr(Child.wrong.fset, "__override__")) 5881 5882 def test_silent_failure(self): 5883 class CustomProp: 5884 __slots__ = ('fget',) 5885 def __init__(self, fget): 5886 self.fget = fget 5887 def __get__(self, obj, objtype=None): 5888 return self.fget(obj) 5889 5890 class WithOverride: 5891 @override # must not fail on object with `__slots__` 5892 @CustomProp 5893 def some(self): 5894 return 1 5895 5896 self.assertEqual(WithOverride.some, 1) 5897 self.assertFalse(hasattr(WithOverride.some, "__override__")) 5898 5899 def test_multiple_decorators(self): 5900 def with_wraps(f): # similar to `lru_cache` definition 5901 @wraps(f) 5902 def wrapper(*args, **kwargs): 5903 return f(*args, **kwargs) 5904 return wrapper 5905 5906 class WithOverride: 5907 @override 5908 @with_wraps 5909 def on_top(self, a: int) -> int: 5910 return a + 1 5911 @with_wraps 5912 @override 5913 def on_bottom(self, a: int) -> int: 5914 return a + 2 5915 5916 instance = WithOverride() 5917 self.assertEqual(instance.on_top(1), 2) 5918 self.assertTrue(instance.on_top.__override__) 5919 self.assertEqual(instance.on_bottom(1), 3) 5920 self.assertTrue(instance.on_bottom.__override__) 5921 5922 5923class CastTests(BaseTestCase): 5924 5925 def test_basics(self): 5926 self.assertEqual(cast(int, 42), 42) 5927 self.assertEqual(cast(float, 42), 42) 5928 self.assertIs(type(cast(float, 42)), int) 5929 self.assertEqual(cast(Any, 42), 42) 5930 self.assertEqual(cast(list, 42), 42) 5931 self.assertEqual(cast(Union[str, float], 42), 42) 5932 self.assertEqual(cast(AnyStr, 42), 42) 5933 self.assertEqual(cast(None, 42), 42) 5934 5935 def test_errors(self): 5936 # Bogus calls are not expected to fail. 5937 cast(42, 42) 5938 cast('hello', 42) 5939 5940 5941class AssertTypeTests(BaseTestCase): 5942 5943 def test_basics(self): 5944 arg = 42 5945 self.assertIs(assert_type(arg, int), arg) 5946 self.assertIs(assert_type(arg, str | float), arg) 5947 self.assertIs(assert_type(arg, AnyStr), arg) 5948 self.assertIs(assert_type(arg, None), arg) 5949 5950 def test_errors(self): 5951 # Bogus calls are not expected to fail. 5952 arg = 42 5953 self.assertIs(assert_type(arg, 42), arg) 5954 self.assertIs(assert_type(arg, 'hello'), arg) 5955 5956 5957# We need this to make sure that `@no_type_check` respects `__module__` attr: 5958from test.typinganndata import ann_module8 5959 5960@no_type_check 5961class NoTypeCheck_Outer: 5962 Inner = ann_module8.NoTypeCheck_Outer.Inner 5963 5964@no_type_check 5965class NoTypeCheck_WithFunction: 5966 NoTypeCheck_function = ann_module8.NoTypeCheck_function 5967 5968 5969class ForwardRefTests(BaseTestCase): 5970 5971 def test_basics(self): 5972 5973 class Node(Generic[T]): 5974 5975 def __init__(self, label: T): 5976 self.label = label 5977 self.left = self.right = None 5978 5979 def add_both(self, 5980 left: 'Optional[Node[T]]', 5981 right: 'Node[T]' = None, 5982 stuff: int = None, 5983 blah=None): 5984 self.left = left 5985 self.right = right 5986 5987 def add_left(self, node: Optional['Node[T]']): 5988 self.add_both(node, None) 5989 5990 def add_right(self, node: 'Node[T]' = None): 5991 self.add_both(None, node) 5992 5993 t = Node[int] 5994 both_hints = get_type_hints(t.add_both, globals(), locals()) 5995 self.assertEqual(both_hints['left'], Optional[Node[T]]) 5996 self.assertEqual(both_hints['right'], Node[T]) 5997 self.assertEqual(both_hints['stuff'], int) 5998 self.assertNotIn('blah', both_hints) 5999 6000 left_hints = get_type_hints(t.add_left, globals(), locals()) 6001 self.assertEqual(left_hints['node'], Optional[Node[T]]) 6002 6003 right_hints = get_type_hints(t.add_right, globals(), locals()) 6004 self.assertEqual(right_hints['node'], Node[T]) 6005 6006 def test_forwardref_instance_type_error(self): 6007 fr = typing.ForwardRef('int') 6008 with self.assertRaises(TypeError): 6009 isinstance(42, fr) 6010 6011 def test_forwardref_subclass_type_error(self): 6012 fr = typing.ForwardRef('int') 6013 with self.assertRaises(TypeError): 6014 issubclass(int, fr) 6015 6016 def test_forwardref_only_str_arg(self): 6017 with self.assertRaises(TypeError): 6018 typing.ForwardRef(1) # only `str` type is allowed 6019 6020 def test_forward_equality(self): 6021 fr = typing.ForwardRef('int') 6022 self.assertEqual(fr, typing.ForwardRef('int')) 6023 self.assertNotEqual(List['int'], List[int]) 6024 self.assertNotEqual(fr, typing.ForwardRef('int', module=__name__)) 6025 frm = typing.ForwardRef('int', module=__name__) 6026 self.assertEqual(frm, typing.ForwardRef('int', module=__name__)) 6027 self.assertNotEqual(frm, typing.ForwardRef('int', module='__other_name__')) 6028 6029 def test_forward_equality_gth(self): 6030 c1 = typing.ForwardRef('C') 6031 c1_gth = typing.ForwardRef('C') 6032 c2 = typing.ForwardRef('C') 6033 c2_gth = typing.ForwardRef('C') 6034 6035 class C: 6036 pass 6037 def foo(a: c1_gth, b: c2_gth): 6038 pass 6039 6040 self.assertEqual(get_type_hints(foo, globals(), locals()), {'a': C, 'b': C}) 6041 self.assertEqual(c1, c2) 6042 self.assertEqual(c1, c1_gth) 6043 self.assertEqual(c1_gth, c2_gth) 6044 self.assertEqual(List[c1], List[c1_gth]) 6045 self.assertNotEqual(List[c1], List[C]) 6046 self.assertNotEqual(List[c1_gth], List[C]) 6047 self.assertEqual(Union[c1, c1_gth], Union[c1]) 6048 self.assertEqual(Union[c1, c1_gth, int], Union[c1, int]) 6049 6050 def test_forward_equality_hash(self): 6051 c1 = typing.ForwardRef('int') 6052 c1_gth = typing.ForwardRef('int') 6053 c2 = typing.ForwardRef('int') 6054 c2_gth = typing.ForwardRef('int') 6055 6056 def foo(a: c1_gth, b: c2_gth): 6057 pass 6058 get_type_hints(foo, globals(), locals()) 6059 6060 self.assertEqual(hash(c1), hash(c2)) 6061 self.assertEqual(hash(c1_gth), hash(c2_gth)) 6062 self.assertEqual(hash(c1), hash(c1_gth)) 6063 6064 c3 = typing.ForwardRef('int', module=__name__) 6065 c4 = typing.ForwardRef('int', module='__other_name__') 6066 6067 self.assertNotEqual(hash(c3), hash(c1)) 6068 self.assertNotEqual(hash(c3), hash(c1_gth)) 6069 self.assertNotEqual(hash(c3), hash(c4)) 6070 self.assertEqual(hash(c3), hash(typing.ForwardRef('int', module=__name__))) 6071 6072 def test_forward_equality_namespace(self): 6073 class A: 6074 pass 6075 def namespace1(): 6076 a = typing.ForwardRef('A') 6077 def fun(x: a): 6078 pass 6079 get_type_hints(fun, globals(), locals()) 6080 return a 6081 6082 def namespace2(): 6083 a = typing.ForwardRef('A') 6084 6085 class A: 6086 pass 6087 def fun(x: a): 6088 pass 6089 6090 get_type_hints(fun, globals(), locals()) 6091 return a 6092 6093 self.assertEqual(namespace1(), namespace1()) 6094 self.assertNotEqual(namespace1(), namespace2()) 6095 6096 def test_forward_repr(self): 6097 self.assertEqual(repr(List['int']), "typing.List[ForwardRef('int')]") 6098 self.assertEqual(repr(List[ForwardRef('int', module='mod')]), 6099 "typing.List[ForwardRef('int', module='mod')]") 6100 6101 def test_union_forward(self): 6102 6103 def foo(a: Union['T']): 6104 pass 6105 6106 self.assertEqual(get_type_hints(foo, globals(), locals()), 6107 {'a': Union[T]}) 6108 6109 def foo(a: tuple[ForwardRef('T')] | int): 6110 pass 6111 6112 self.assertEqual(get_type_hints(foo, globals(), locals()), 6113 {'a': tuple[T] | int}) 6114 6115 def test_tuple_forward(self): 6116 6117 def foo(a: Tuple['T']): 6118 pass 6119 6120 self.assertEqual(get_type_hints(foo, globals(), locals()), 6121 {'a': Tuple[T]}) 6122 6123 def foo(a: tuple[ForwardRef('T')]): 6124 pass 6125 6126 self.assertEqual(get_type_hints(foo, globals(), locals()), 6127 {'a': tuple[T]}) 6128 6129 def test_double_forward(self): 6130 def foo(a: 'List[\'int\']'): 6131 pass 6132 self.assertEqual(get_type_hints(foo, globals(), locals()), 6133 {'a': List[int]}) 6134 6135 def test_forward_recursion_actually(self): 6136 def namespace1(): 6137 a = typing.ForwardRef('A') 6138 A = a 6139 def fun(x: a): pass 6140 6141 ret = get_type_hints(fun, globals(), locals()) 6142 return a 6143 6144 def namespace2(): 6145 a = typing.ForwardRef('A') 6146 A = a 6147 def fun(x: a): pass 6148 6149 ret = get_type_hints(fun, globals(), locals()) 6150 return a 6151 6152 def cmp(o1, o2): 6153 return o1 == o2 6154 6155 with infinite_recursion(25): 6156 r1 = namespace1() 6157 r2 = namespace2() 6158 self.assertIsNot(r1, r2) 6159 self.assertRaises(RecursionError, cmp, r1, r2) 6160 6161 def test_union_forward_recursion(self): 6162 ValueList = List['Value'] 6163 Value = Union[str, ValueList] 6164 6165 class C: 6166 foo: List[Value] 6167 class D: 6168 foo: Union[Value, ValueList] 6169 class E: 6170 foo: Union[List[Value], ValueList] 6171 class F: 6172 foo: Union[Value, List[Value], ValueList] 6173 6174 self.assertEqual(get_type_hints(C, globals(), locals()), get_type_hints(C, globals(), locals())) 6175 self.assertEqual(get_type_hints(C, globals(), locals()), 6176 {'foo': List[Union[str, List[Union[str, List['Value']]]]]}) 6177 self.assertEqual(get_type_hints(D, globals(), locals()), 6178 {'foo': Union[str, List[Union[str, List['Value']]]]}) 6179 self.assertEqual(get_type_hints(E, globals(), locals()), 6180 {'foo': Union[ 6181 List[Union[str, List[Union[str, List['Value']]]]], 6182 List[Union[str, List['Value']]] 6183 ] 6184 }) 6185 self.assertEqual(get_type_hints(F, globals(), locals()), 6186 {'foo': Union[ 6187 str, 6188 List[Union[str, List['Value']]], 6189 List[Union[str, List[Union[str, List['Value']]]]] 6190 ] 6191 }) 6192 6193 def test_callable_forward(self): 6194 6195 def foo(a: Callable[['T'], 'T']): 6196 pass 6197 6198 self.assertEqual(get_type_hints(foo, globals(), locals()), 6199 {'a': Callable[[T], T]}) 6200 6201 def test_callable_with_ellipsis_forward(self): 6202 6203 def foo(a: 'Callable[..., T]'): 6204 pass 6205 6206 self.assertEqual(get_type_hints(foo, globals(), locals()), 6207 {'a': Callable[..., T]}) 6208 6209 def test_special_forms_forward(self): 6210 6211 class C: 6212 a: Annotated['ClassVar[int]', (3, 5)] = 4 6213 b: Annotated['Final[int]', "const"] = 4 6214 x: 'ClassVar' = 4 6215 y: 'Final' = 4 6216 6217 class CF: 6218 b: List['Final[int]'] = 4 6219 6220 self.assertEqual(get_type_hints(C, globals())['a'], ClassVar[int]) 6221 self.assertEqual(get_type_hints(C, globals())['b'], Final[int]) 6222 self.assertEqual(get_type_hints(C, globals())['x'], ClassVar) 6223 self.assertEqual(get_type_hints(C, globals())['y'], Final) 6224 with self.assertRaises(TypeError): 6225 get_type_hints(CF, globals()), 6226 6227 def test_syntax_error(self): 6228 6229 with self.assertRaises(SyntaxError): 6230 Generic['/T'] 6231 6232 def test_delayed_syntax_error(self): 6233 6234 def foo(a: 'Node[T'): 6235 pass 6236 6237 with self.assertRaises(SyntaxError): 6238 get_type_hints(foo) 6239 6240 def test_syntax_error_empty_string(self): 6241 for form in [typing.List, typing.Set, typing.Type, typing.Deque]: 6242 with self.subTest(form=form): 6243 with self.assertRaises(SyntaxError): 6244 form[''] 6245 6246 def test_name_error(self): 6247 6248 def foo(a: 'Noode[T]'): 6249 pass 6250 6251 with self.assertRaises(NameError): 6252 get_type_hints(foo, locals()) 6253 6254 def test_no_type_check(self): 6255 6256 @no_type_check 6257 def foo(a: 'whatevers') -> {}: 6258 pass 6259 6260 th = get_type_hints(foo) 6261 self.assertEqual(th, {}) 6262 6263 def test_no_type_check_class(self): 6264 6265 @no_type_check 6266 class C: 6267 def foo(a: 'whatevers') -> {}: 6268 pass 6269 6270 cth = get_type_hints(C.foo) 6271 self.assertEqual(cth, {}) 6272 ith = get_type_hints(C().foo) 6273 self.assertEqual(ith, {}) 6274 6275 def test_no_type_check_no_bases(self): 6276 class C: 6277 def meth(self, x: int): ... 6278 @no_type_check 6279 class D(C): 6280 c = C 6281 6282 # verify that @no_type_check never affects bases 6283 self.assertEqual(get_type_hints(C.meth), {'x': int}) 6284 6285 # and never child classes: 6286 class Child(D): 6287 def foo(self, x: int): ... 6288 6289 self.assertEqual(get_type_hints(Child.foo), {'x': int}) 6290 6291 def test_no_type_check_nested_types(self): 6292 # See https://bugs.python.org/issue46571 6293 class Other: 6294 o: int 6295 class B: # Has the same `__name__`` as `A.B` and different `__qualname__` 6296 o: int 6297 @no_type_check 6298 class A: 6299 a: int 6300 class B: 6301 b: int 6302 class C: 6303 c: int 6304 class D: 6305 d: int 6306 6307 Other = Other 6308 6309 for klass in [A, A.B, A.B.C, A.D]: 6310 with self.subTest(klass=klass): 6311 self.assertTrue(klass.__no_type_check__) 6312 self.assertEqual(get_type_hints(klass), {}) 6313 6314 for not_modified in [Other, B]: 6315 with self.subTest(not_modified=not_modified): 6316 with self.assertRaises(AttributeError): 6317 not_modified.__no_type_check__ 6318 self.assertNotEqual(get_type_hints(not_modified), {}) 6319 6320 def test_no_type_check_class_and_static_methods(self): 6321 @no_type_check 6322 class Some: 6323 @staticmethod 6324 def st(x: int) -> int: ... 6325 @classmethod 6326 def cl(cls, y: int) -> int: ... 6327 6328 self.assertTrue(Some.st.__no_type_check__) 6329 self.assertEqual(get_type_hints(Some.st), {}) 6330 self.assertTrue(Some.cl.__no_type_check__) 6331 self.assertEqual(get_type_hints(Some.cl), {}) 6332 6333 def test_no_type_check_other_module(self): 6334 self.assertTrue(NoTypeCheck_Outer.__no_type_check__) 6335 with self.assertRaises(AttributeError): 6336 ann_module8.NoTypeCheck_Outer.__no_type_check__ 6337 with self.assertRaises(AttributeError): 6338 ann_module8.NoTypeCheck_Outer.Inner.__no_type_check__ 6339 6340 self.assertTrue(NoTypeCheck_WithFunction.__no_type_check__) 6341 with self.assertRaises(AttributeError): 6342 ann_module8.NoTypeCheck_function.__no_type_check__ 6343 6344 def test_no_type_check_foreign_functions(self): 6345 # We should not modify this function: 6346 def some(*args: int) -> int: 6347 ... 6348 6349 @no_type_check 6350 class A: 6351 some_alias = some 6352 some_class = classmethod(some) 6353 some_static = staticmethod(some) 6354 6355 with self.assertRaises(AttributeError): 6356 some.__no_type_check__ 6357 self.assertEqual(get_type_hints(some), {'args': int, 'return': int}) 6358 6359 def test_no_type_check_lambda(self): 6360 @no_type_check 6361 class A: 6362 # Corner case: `lambda` is both an assignment and a function: 6363 bar: Callable[[int], int] = lambda arg: arg 6364 6365 self.assertTrue(A.bar.__no_type_check__) 6366 self.assertEqual(get_type_hints(A.bar), {}) 6367 6368 def test_no_type_check_TypeError(self): 6369 # This simply should not fail with 6370 # `TypeError: can't set attributes of built-in/extension type 'dict'` 6371 no_type_check(dict) 6372 6373 def test_no_type_check_forward_ref_as_string(self): 6374 class C: 6375 foo: typing.ClassVar[int] = 7 6376 class D: 6377 foo: ClassVar[int] = 7 6378 class E: 6379 foo: 'typing.ClassVar[int]' = 7 6380 class F: 6381 foo: 'ClassVar[int]' = 7 6382 6383 expected_result = {'foo': typing.ClassVar[int]} 6384 for clazz in [C, D, E, F]: 6385 self.assertEqual(get_type_hints(clazz), expected_result) 6386 6387 def test_meta_no_type_check(self): 6388 depr_msg = ( 6389 "'typing.no_type_check_decorator' is deprecated " 6390 "and slated for removal in Python 3.15" 6391 ) 6392 with self.assertWarnsRegex(DeprecationWarning, depr_msg): 6393 @no_type_check_decorator 6394 def magic_decorator(func): 6395 return func 6396 6397 self.assertEqual(magic_decorator.__name__, 'magic_decorator') 6398 6399 @magic_decorator 6400 def foo(a: 'whatevers') -> {}: 6401 pass 6402 6403 @magic_decorator 6404 class C: 6405 def foo(a: 'whatevers') -> {}: 6406 pass 6407 6408 self.assertEqual(foo.__name__, 'foo') 6409 th = get_type_hints(foo) 6410 self.assertEqual(th, {}) 6411 cth = get_type_hints(C.foo) 6412 self.assertEqual(cth, {}) 6413 ith = get_type_hints(C().foo) 6414 self.assertEqual(ith, {}) 6415 6416 def test_default_globals(self): 6417 code = ("class C:\n" 6418 " def foo(self, a: 'C') -> 'D': pass\n" 6419 "class D:\n" 6420 " def bar(self, b: 'D') -> C: pass\n" 6421 ) 6422 ns = {} 6423 exec(code, ns) 6424 hints = get_type_hints(ns['C'].foo) 6425 self.assertEqual(hints, {'a': ns['C'], 'return': ns['D']}) 6426 6427 def test_final_forward_ref(self): 6428 self.assertEqual(gth(Loop, globals())['attr'], Final[Loop]) 6429 self.assertNotEqual(gth(Loop, globals())['attr'], Final[int]) 6430 self.assertNotEqual(gth(Loop, globals())['attr'], Final) 6431 6432 def test_or(self): 6433 X = ForwardRef('X') 6434 # __or__/__ror__ itself 6435 self.assertEqual(X | "x", Union[X, "x"]) 6436 self.assertEqual("x" | X, Union["x", X]) 6437 6438 6439class InternalsTests(BaseTestCase): 6440 def test_deprecation_for_no_type_params_passed_to__evaluate(self): 6441 with self.assertWarnsRegex( 6442 DeprecationWarning, 6443 ( 6444 "Failing to pass a value to the 'type_params' parameter " 6445 "of 'typing._eval_type' is deprecated" 6446 ) 6447 ) as cm: 6448 self.assertEqual(typing._eval_type(list["int"], globals(), {}), list[int]) 6449 6450 self.assertEqual(cm.filename, __file__) 6451 6452 f = ForwardRef("int") 6453 6454 with self.assertWarnsRegex( 6455 DeprecationWarning, 6456 ( 6457 "Failing to pass a value to the 'type_params' parameter " 6458 "of 'typing.ForwardRef._evaluate' is deprecated" 6459 ) 6460 ) as cm: 6461 self.assertIs(f._evaluate(globals(), {}, recursive_guard=frozenset()), int) 6462 6463 self.assertEqual(cm.filename, __file__) 6464 6465 def test_collect_parameters(self): 6466 typing = import_helper.import_fresh_module("typing") 6467 with self.assertWarnsRegex( 6468 DeprecationWarning, 6469 "The private _collect_parameters function is deprecated" 6470 ) as cm: 6471 typing._collect_parameters 6472 self.assertEqual(cm.filename, __file__) 6473 6474 6475@lru_cache() 6476def cached_func(x, y): 6477 return 3 * x + y 6478 6479 6480class MethodHolder: 6481 @classmethod 6482 def clsmethod(cls): ... 6483 @staticmethod 6484 def stmethod(): ... 6485 def method(self): ... 6486 6487 6488class OverloadTests(BaseTestCase): 6489 6490 def test_overload_fails(self): 6491 with self.assertRaises(NotImplementedError): 6492 6493 @overload 6494 def blah(): 6495 pass 6496 6497 blah() 6498 6499 def test_overload_succeeds(self): 6500 @overload 6501 def blah(): 6502 pass 6503 6504 def blah(): 6505 pass 6506 6507 blah() 6508 6509 @cpython_only # gh-98713 6510 def test_overload_on_compiled_functions(self): 6511 with patch("typing._overload_registry", 6512 defaultdict(lambda: defaultdict(dict))): 6513 # The registry starts out empty: 6514 self.assertEqual(typing._overload_registry, {}) 6515 6516 # This should just not fail: 6517 overload(sum) 6518 overload(print) 6519 6520 # No overloads are recorded (but, it still has a side-effect): 6521 self.assertEqual(typing.get_overloads(sum), []) 6522 self.assertEqual(typing.get_overloads(print), []) 6523 6524 def set_up_overloads(self): 6525 def blah(): 6526 pass 6527 6528 overload1 = blah 6529 overload(blah) 6530 6531 def blah(): 6532 pass 6533 6534 overload2 = blah 6535 overload(blah) 6536 6537 def blah(): 6538 pass 6539 6540 return blah, [overload1, overload2] 6541 6542 # Make sure we don't clear the global overload registry 6543 @patch("typing._overload_registry", 6544 defaultdict(lambda: defaultdict(dict))) 6545 def test_overload_registry(self): 6546 # The registry starts out empty 6547 self.assertEqual(typing._overload_registry, {}) 6548 6549 impl, overloads = self.set_up_overloads() 6550 self.assertNotEqual(typing._overload_registry, {}) 6551 self.assertEqual(list(get_overloads(impl)), overloads) 6552 6553 def some_other_func(): pass 6554 overload(some_other_func) 6555 other_overload = some_other_func 6556 def some_other_func(): pass 6557 self.assertEqual(list(get_overloads(some_other_func)), [other_overload]) 6558 # Unrelated function still has no overloads: 6559 def not_overloaded(): pass 6560 self.assertEqual(list(get_overloads(not_overloaded)), []) 6561 6562 # Make sure that after we clear all overloads, the registry is 6563 # completely empty. 6564 clear_overloads() 6565 self.assertEqual(typing._overload_registry, {}) 6566 self.assertEqual(get_overloads(impl), []) 6567 6568 # Querying a function with no overloads shouldn't change the registry. 6569 def the_only_one(): pass 6570 self.assertEqual(get_overloads(the_only_one), []) 6571 self.assertEqual(typing._overload_registry, {}) 6572 6573 def test_overload_registry_repeated(self): 6574 for _ in range(2): 6575 impl, overloads = self.set_up_overloads() 6576 6577 self.assertEqual(list(get_overloads(impl)), overloads) 6578 6579 6580from test.typinganndata import ( 6581 ann_module, ann_module2, ann_module3, ann_module5, ann_module6, 6582) 6583 6584T_a = TypeVar('T_a') 6585 6586class AwaitableWrapper(typing.Awaitable[T_a]): 6587 6588 def __init__(self, value): 6589 self.value = value 6590 6591 def __await__(self) -> typing.Iterator[T_a]: 6592 yield 6593 return self.value 6594 6595class AsyncIteratorWrapper(typing.AsyncIterator[T_a]): 6596 6597 def __init__(self, value: typing.Iterable[T_a]): 6598 self.value = value 6599 6600 def __aiter__(self) -> typing.AsyncIterator[T_a]: 6601 return self 6602 6603 async def __anext__(self) -> T_a: 6604 data = await self.value 6605 if data: 6606 return data 6607 else: 6608 raise StopAsyncIteration 6609 6610class ACM: 6611 async def __aenter__(self) -> int: 6612 return 42 6613 async def __aexit__(self, etype, eval, tb): 6614 return None 6615 6616class A: 6617 y: float 6618class B(A): 6619 x: ClassVar[Optional['B']] = None 6620 y: int 6621 b: int 6622class CSub(B): 6623 z: ClassVar['CSub'] = B() 6624class G(Generic[T]): 6625 lst: ClassVar[List[T]] = [] 6626 6627class Loop: 6628 attr: Final['Loop'] 6629 6630class NoneAndForward: 6631 parent: 'NoneAndForward' 6632 meaning: None 6633 6634class CoolEmployee(NamedTuple): 6635 name: str 6636 cool: int 6637 6638class CoolEmployeeWithDefault(NamedTuple): 6639 name: str 6640 cool: int = 0 6641 6642class XMeth(NamedTuple): 6643 x: int 6644 def double(self): 6645 return 2 * self.x 6646 6647class XRepr(NamedTuple): 6648 x: int 6649 y: int = 1 6650 def __str__(self): 6651 return f'{self.x} -> {self.y}' 6652 def __add__(self, other): 6653 return 0 6654 6655Label = TypedDict('Label', [('label', str)]) 6656 6657class Point2D(TypedDict): 6658 x: int 6659 y: int 6660 6661class Point2DGeneric(Generic[T], TypedDict): 6662 a: T 6663 b: T 6664 6665class Bar(_typed_dict_helper.Foo, total=False): 6666 b: int 6667 6668class BarGeneric(_typed_dict_helper.FooGeneric[T], total=False): 6669 b: int 6670 6671class LabelPoint2D(Point2D, Label): ... 6672 6673class Options(TypedDict, total=False): 6674 log_level: int 6675 log_path: str 6676 6677class TotalMovie(TypedDict): 6678 title: str 6679 year: NotRequired[int] 6680 6681class NontotalMovie(TypedDict, total=False): 6682 title: Required[str] 6683 year: int 6684 6685class ParentNontotalMovie(TypedDict, total=False): 6686 title: Required[str] 6687 6688class ChildTotalMovie(ParentNontotalMovie): 6689 year: NotRequired[int] 6690 6691class ParentDeeplyAnnotatedMovie(TypedDict): 6692 title: Annotated[Annotated[Required[str], "foobar"], "another level"] 6693 6694class ChildDeeplyAnnotatedMovie(ParentDeeplyAnnotatedMovie): 6695 year: NotRequired[Annotated[int, 2000]] 6696 6697class AnnotatedMovie(TypedDict): 6698 title: Annotated[Required[str], "foobar"] 6699 year: NotRequired[Annotated[int, 2000]] 6700 6701class DeeplyAnnotatedMovie(TypedDict): 6702 title: Annotated[Annotated[Required[str], "foobar"], "another level"] 6703 year: NotRequired[Annotated[int, 2000]] 6704 6705class WeirdlyQuotedMovie(TypedDict): 6706 title: Annotated['Annotated[Required[str], "foobar"]', "another level"] 6707 year: NotRequired['Annotated[int, 2000]'] 6708 6709class HasForeignBaseClass(mod_generics_cache.A): 6710 some_xrepr: 'XRepr' 6711 other_a: 'mod_generics_cache.A' 6712 6713async def g_with(am: typing.AsyncContextManager[int]): 6714 x: int 6715 async with am as x: 6716 return x 6717 6718try: 6719 g_with(ACM()).send(None) 6720except StopIteration as e: 6721 assert e.args[0] == 42 6722 6723gth = get_type_hints 6724 6725class ForRefExample: 6726 @ann_module.dec 6727 def func(self: 'ForRefExample'): 6728 pass 6729 6730 @ann_module.dec 6731 @ann_module.dec 6732 def nested(self: 'ForRefExample'): 6733 pass 6734 6735 6736class GetTypeHintTests(BaseTestCase): 6737 def test_get_type_hints_from_various_objects(self): 6738 # For invalid objects should fail with TypeError (not AttributeError etc). 6739 with self.assertRaises(TypeError): 6740 gth(123) 6741 with self.assertRaises(TypeError): 6742 gth('abc') 6743 with self.assertRaises(TypeError): 6744 gth(None) 6745 6746 def test_get_type_hints_modules(self): 6747 ann_module_type_hints = {1: 2, 'f': Tuple[int, int], 'x': int, 'y': str, 'u': int | float} 6748 self.assertEqual(gth(ann_module), ann_module_type_hints) 6749 self.assertEqual(gth(ann_module2), {}) 6750 self.assertEqual(gth(ann_module3), {}) 6751 6752 @skip("known bug") 6753 def test_get_type_hints_modules_forwardref(self): 6754 # FIXME: This currently exposes a bug in typing. Cached forward references 6755 # don't account for the case where there are multiple types of the same 6756 # name coming from different modules in the same program. 6757 mgc_hints = {'default_a': Optional[mod_generics_cache.A], 6758 'default_b': Optional[mod_generics_cache.B]} 6759 self.assertEqual(gth(mod_generics_cache), mgc_hints) 6760 6761 def test_get_type_hints_classes(self): 6762 self.assertEqual(gth(ann_module.C), # gth will find the right globalns 6763 {'y': Optional[ann_module.C]}) 6764 self.assertIsInstance(gth(ann_module.j_class), dict) 6765 self.assertEqual(gth(ann_module.M), {'123': 123, 'o': type}) 6766 self.assertEqual(gth(ann_module.D), 6767 {'j': str, 'k': str, 'y': Optional[ann_module.C]}) 6768 self.assertEqual(gth(ann_module.Y), {'z': int}) 6769 self.assertEqual(gth(ann_module.h_class), 6770 {'y': Optional[ann_module.C]}) 6771 self.assertEqual(gth(ann_module.S), {'x': str, 'y': str}) 6772 self.assertEqual(gth(ann_module.foo), {'x': int}) 6773 self.assertEqual(gth(NoneAndForward), 6774 {'parent': NoneAndForward, 'meaning': type(None)}) 6775 self.assertEqual(gth(HasForeignBaseClass), 6776 {'some_xrepr': XRepr, 'other_a': mod_generics_cache.A, 6777 'some_b': mod_generics_cache.B}) 6778 self.assertEqual(gth(XRepr.__new__), 6779 {'x': int, 'y': int}) 6780 self.assertEqual(gth(mod_generics_cache.B), 6781 {'my_inner_a1': mod_generics_cache.B.A, 6782 'my_inner_a2': mod_generics_cache.B.A, 6783 'my_outer_a': mod_generics_cache.A}) 6784 6785 def test_get_type_hints_classes_no_implicit_optional(self): 6786 class WithNoneDefault: 6787 field: int = None # most type-checkers won't be happy with it 6788 6789 self.assertEqual(gth(WithNoneDefault), {'field': int}) 6790 6791 def test_respect_no_type_check(self): 6792 @no_type_check 6793 class NoTpCheck: 6794 class Inn: 6795 def __init__(self, x: 'not a type'): ... 6796 self.assertTrue(NoTpCheck.__no_type_check__) 6797 self.assertTrue(NoTpCheck.Inn.__init__.__no_type_check__) 6798 self.assertEqual(gth(ann_module2.NTC.meth), {}) 6799 class ABase(Generic[T]): 6800 def meth(x: int): ... 6801 @no_type_check 6802 class Der(ABase): ... 6803 self.assertEqual(gth(ABase.meth), {'x': int}) 6804 6805 def test_get_type_hints_for_builtins(self): 6806 # Should not fail for built-in classes and functions. 6807 self.assertEqual(gth(int), {}) 6808 self.assertEqual(gth(type), {}) 6809 self.assertEqual(gth(dir), {}) 6810 self.assertEqual(gth(len), {}) 6811 self.assertEqual(gth(object.__str__), {}) 6812 self.assertEqual(gth(object().__str__), {}) 6813 self.assertEqual(gth(str.join), {}) 6814 6815 def test_previous_behavior(self): 6816 def testf(x, y): ... 6817 testf.__annotations__['x'] = 'int' 6818 self.assertEqual(gth(testf), {'x': int}) 6819 def testg(x: None): ... 6820 self.assertEqual(gth(testg), {'x': type(None)}) 6821 6822 def test_get_type_hints_for_object_with_annotations(self): 6823 class A: ... 6824 class B: ... 6825 b = B() 6826 b.__annotations__ = {'x': 'A'} 6827 self.assertEqual(gth(b, locals()), {'x': A}) 6828 6829 def test_get_type_hints_ClassVar(self): 6830 self.assertEqual(gth(ann_module2.CV, ann_module2.__dict__), 6831 {'var': typing.ClassVar[ann_module2.CV]}) 6832 self.assertEqual(gth(B, globals()), 6833 {'y': int, 'x': ClassVar[Optional[B]], 'b': int}) 6834 self.assertEqual(gth(CSub, globals()), 6835 {'z': ClassVar[CSub], 'y': int, 'b': int, 6836 'x': ClassVar[Optional[B]]}) 6837 self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) 6838 6839 def test_get_type_hints_wrapped_decoratored_func(self): 6840 expects = {'self': ForRefExample} 6841 self.assertEqual(gth(ForRefExample.func), expects) 6842 self.assertEqual(gth(ForRefExample.nested), expects) 6843 6844 def test_get_type_hints_annotated(self): 6845 def foobar(x: List['X']): ... 6846 X = Annotated[int, (1, 10)] 6847 self.assertEqual( 6848 get_type_hints(foobar, globals(), locals()), 6849 {'x': List[int]} 6850 ) 6851 self.assertEqual( 6852 get_type_hints(foobar, globals(), locals(), include_extras=True), 6853 {'x': List[Annotated[int, (1, 10)]]} 6854 ) 6855 6856 def foobar(x: list[ForwardRef('X')]): ... 6857 X = Annotated[int, (1, 10)] 6858 self.assertEqual( 6859 get_type_hints(foobar, globals(), locals()), 6860 {'x': list[int]} 6861 ) 6862 self.assertEqual( 6863 get_type_hints(foobar, globals(), locals(), include_extras=True), 6864 {'x': list[Annotated[int, (1, 10)]]} 6865 ) 6866 6867 BA = Tuple[Annotated[T, (1, 0)], ...] 6868 def barfoo(x: BA): ... 6869 self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], Tuple[T, ...]) 6870 self.assertEqual( 6871 get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], 6872 BA 6873 ) 6874 6875 BA = tuple[Annotated[T, (1, 0)], ...] 6876 def barfoo(x: BA): ... 6877 self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], tuple[T, ...]) 6878 self.assertEqual( 6879 get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], 6880 BA 6881 ) 6882 6883 def barfoo2(x: typing.Callable[..., Annotated[List[T], "const"]], 6884 y: typing.Union[int, Annotated[T, "mutable"]]): ... 6885 self.assertEqual( 6886 get_type_hints(barfoo2, globals(), locals()), 6887 {'x': typing.Callable[..., List[T]], 'y': typing.Union[int, T]} 6888 ) 6889 6890 BA2 = typing.Callable[..., List[T]] 6891 def barfoo3(x: BA2): ... 6892 self.assertIs( 6893 get_type_hints(barfoo3, globals(), locals(), include_extras=True)["x"], 6894 BA2 6895 ) 6896 BA3 = typing.Annotated[int | float, "const"] 6897 def barfoo4(x: BA3): ... 6898 self.assertEqual( 6899 get_type_hints(barfoo4, globals(), locals()), 6900 {"x": int | float} 6901 ) 6902 self.assertEqual( 6903 get_type_hints(barfoo4, globals(), locals(), include_extras=True), 6904 {"x": typing.Annotated[int | float, "const"]} 6905 ) 6906 6907 def test_get_type_hints_annotated_in_union(self): # bpo-46603 6908 def with_union(x: int | list[Annotated[str, 'meta']]): ... 6909 6910 self.assertEqual(get_type_hints(with_union), {'x': int | list[str]}) 6911 self.assertEqual( 6912 get_type_hints(with_union, include_extras=True), 6913 {'x': int | list[Annotated[str, 'meta']]}, 6914 ) 6915 6916 def test_get_type_hints_annotated_refs(self): 6917 6918 Const = Annotated[T, "Const"] 6919 6920 class MySet(Generic[T]): 6921 6922 def __ior__(self, other: "Const[MySet[T]]") -> "MySet[T]": 6923 ... 6924 6925 def __iand__(self, other: Const["MySet[T]"]) -> "MySet[T]": 6926 ... 6927 6928 self.assertEqual( 6929 get_type_hints(MySet.__iand__, globals(), locals()), 6930 {'other': MySet[T], 'return': MySet[T]} 6931 ) 6932 6933 self.assertEqual( 6934 get_type_hints(MySet.__iand__, globals(), locals(), include_extras=True), 6935 {'other': Const[MySet[T]], 'return': MySet[T]} 6936 ) 6937 6938 self.assertEqual( 6939 get_type_hints(MySet.__ior__, globals(), locals()), 6940 {'other': MySet[T], 'return': MySet[T]} 6941 ) 6942 6943 def test_get_type_hints_annotated_with_none_default(self): 6944 # See: https://bugs.python.org/issue46195 6945 def annotated_with_none_default(x: Annotated[int, 'data'] = None): ... 6946 self.assertEqual( 6947 get_type_hints(annotated_with_none_default), 6948 {'x': int}, 6949 ) 6950 self.assertEqual( 6951 get_type_hints(annotated_with_none_default, include_extras=True), 6952 {'x': Annotated[int, 'data']}, 6953 ) 6954 6955 def test_get_type_hints_classes_str_annotations(self): 6956 class Foo: 6957 y = str 6958 x: 'y' 6959 # This previously raised an error under PEP 563. 6960 self.assertEqual(get_type_hints(Foo), {'x': str}) 6961 6962 def test_get_type_hints_bad_module(self): 6963 # bpo-41515 6964 class BadModule: 6965 pass 6966 BadModule.__module__ = 'bad' # Something not in sys.modules 6967 self.assertNotIn('bad', sys.modules) 6968 self.assertEqual(get_type_hints(BadModule), {}) 6969 6970 def test_get_type_hints_annotated_bad_module(self): 6971 # See https://bugs.python.org/issue44468 6972 class BadBase: 6973 foo: tuple 6974 class BadType(BadBase): 6975 bar: list 6976 BadType.__module__ = BadBase.__module__ = 'bad' 6977 self.assertNotIn('bad', sys.modules) 6978 self.assertEqual(get_type_hints(BadType), {'foo': tuple, 'bar': list}) 6979 6980 def test_forward_ref_and_final(self): 6981 # https://bugs.python.org/issue45166 6982 hints = get_type_hints(ann_module5) 6983 self.assertEqual(hints, {'name': Final[str]}) 6984 6985 hints = get_type_hints(ann_module5.MyClass) 6986 self.assertEqual(hints, {'value': Final}) 6987 6988 def test_top_level_class_var(self): 6989 # https://bugs.python.org/issue45166 6990 with self.assertRaisesRegex( 6991 TypeError, 6992 r'typing.ClassVar\[int\] is not valid as type argument', 6993 ): 6994 get_type_hints(ann_module6) 6995 6996 def test_get_type_hints_typeddict(self): 6997 self.assertEqual(get_type_hints(TotalMovie), {'title': str, 'year': int}) 6998 self.assertEqual(get_type_hints(TotalMovie, include_extras=True), { 6999 'title': str, 7000 'year': NotRequired[int], 7001 }) 7002 7003 self.assertEqual(get_type_hints(AnnotatedMovie), {'title': str, 'year': int}) 7004 self.assertEqual(get_type_hints(AnnotatedMovie, include_extras=True), { 7005 'title': Annotated[Required[str], "foobar"], 7006 'year': NotRequired[Annotated[int, 2000]], 7007 }) 7008 7009 self.assertEqual(get_type_hints(DeeplyAnnotatedMovie), {'title': str, 'year': int}) 7010 self.assertEqual(get_type_hints(DeeplyAnnotatedMovie, include_extras=True), { 7011 'title': Annotated[Required[str], "foobar", "another level"], 7012 'year': NotRequired[Annotated[int, 2000]], 7013 }) 7014 7015 self.assertEqual(get_type_hints(WeirdlyQuotedMovie), {'title': str, 'year': int}) 7016 self.assertEqual(get_type_hints(WeirdlyQuotedMovie, include_extras=True), { 7017 'title': Annotated[Required[str], "foobar", "another level"], 7018 'year': NotRequired[Annotated[int, 2000]], 7019 }) 7020 7021 self.assertEqual(get_type_hints(_typed_dict_helper.VeryAnnotated), {'a': int}) 7022 self.assertEqual(get_type_hints(_typed_dict_helper.VeryAnnotated, include_extras=True), { 7023 'a': Annotated[Required[int], "a", "b", "c"] 7024 }) 7025 7026 self.assertEqual(get_type_hints(ChildTotalMovie), {"title": str, "year": int}) 7027 self.assertEqual(get_type_hints(ChildTotalMovie, include_extras=True), { 7028 "title": Required[str], "year": NotRequired[int] 7029 }) 7030 7031 self.assertEqual(get_type_hints(ChildDeeplyAnnotatedMovie), {"title": str, "year": int}) 7032 self.assertEqual(get_type_hints(ChildDeeplyAnnotatedMovie, include_extras=True), { 7033 "title": Annotated[Required[str], "foobar", "another level"], 7034 "year": NotRequired[Annotated[int, 2000]] 7035 }) 7036 7037 def test_get_type_hints_collections_abc_callable(self): 7038 # https://github.com/python/cpython/issues/91621 7039 P = ParamSpec('P') 7040 def f(x: collections.abc.Callable[[int], int]): ... 7041 def g(x: collections.abc.Callable[..., int]): ... 7042 def h(x: collections.abc.Callable[P, int]): ... 7043 7044 self.assertEqual(get_type_hints(f), {'x': collections.abc.Callable[[int], int]}) 7045 self.assertEqual(get_type_hints(g), {'x': collections.abc.Callable[..., int]}) 7046 self.assertEqual(get_type_hints(h), {'x': collections.abc.Callable[P, int]}) 7047 7048 7049class GetUtilitiesTestCase(TestCase): 7050 def test_get_origin(self): 7051 T = TypeVar('T') 7052 Ts = TypeVarTuple('Ts') 7053 P = ParamSpec('P') 7054 class C(Generic[T]): pass 7055 self.assertIs(get_origin(C[int]), C) 7056 self.assertIs(get_origin(C[T]), C) 7057 self.assertIs(get_origin(int), None) 7058 self.assertIs(get_origin(ClassVar[int]), ClassVar) 7059 self.assertIs(get_origin(Union[int, str]), Union) 7060 self.assertIs(get_origin(Literal[42, 43]), Literal) 7061 self.assertIs(get_origin(Final[List[int]]), Final) 7062 self.assertIs(get_origin(Generic), Generic) 7063 self.assertIs(get_origin(Generic[T]), Generic) 7064 self.assertIs(get_origin(List[Tuple[T, T]][int]), list) 7065 self.assertIs(get_origin(Annotated[T, 'thing']), Annotated) 7066 self.assertIs(get_origin(List), list) 7067 self.assertIs(get_origin(Tuple), tuple) 7068 self.assertIs(get_origin(Callable), collections.abc.Callable) 7069 self.assertIs(get_origin(list[int]), list) 7070 self.assertIs(get_origin(list), None) 7071 self.assertIs(get_origin(list | str), types.UnionType) 7072 self.assertIs(get_origin(P.args), P) 7073 self.assertIs(get_origin(P.kwargs), P) 7074 self.assertIs(get_origin(Required[int]), Required) 7075 self.assertIs(get_origin(NotRequired[int]), NotRequired) 7076 self.assertIs(get_origin((*Ts,)[0]), Unpack) 7077 self.assertIs(get_origin(Unpack[Ts]), Unpack) 7078 self.assertIs(get_origin((*tuple[*Ts],)[0]), tuple) 7079 self.assertIs(get_origin(Unpack[Tuple[Unpack[Ts]]]), Unpack) 7080 7081 def test_get_args(self): 7082 T = TypeVar('T') 7083 class C(Generic[T]): pass 7084 self.assertEqual(get_args(C[int]), (int,)) 7085 self.assertEqual(get_args(C[T]), (T,)) 7086 self.assertEqual(get_args(typing.SupportsAbs[int]), (int,)) # Protocol 7087 self.assertEqual(get_args(typing.SupportsAbs[T]), (T,)) 7088 self.assertEqual(get_args(Point2DGeneric[int]), (int,)) # TypedDict 7089 self.assertEqual(get_args(Point2DGeneric[T]), (T,)) 7090 self.assertEqual(get_args(T), ()) 7091 self.assertEqual(get_args(int), ()) 7092 self.assertEqual(get_args(Any), ()) 7093 self.assertEqual(get_args(Self), ()) 7094 self.assertEqual(get_args(LiteralString), ()) 7095 self.assertEqual(get_args(ClassVar[int]), (int,)) 7096 self.assertEqual(get_args(Union[int, str]), (int, str)) 7097 self.assertEqual(get_args(Literal[42, 43]), (42, 43)) 7098 self.assertEqual(get_args(Final[List[int]]), (List[int],)) 7099 self.assertEqual(get_args(Optional[int]), (int, type(None))) 7100 self.assertEqual(get_args(Union[int, None]), (int, type(None))) 7101 self.assertEqual(get_args(Union[int, Tuple[T, int]][str]), 7102 (int, Tuple[str, int])) 7103 self.assertEqual(get_args(typing.Dict[int, Tuple[T, T]][Optional[int]]), 7104 (int, Tuple[Optional[int], Optional[int]])) 7105 self.assertEqual(get_args(Callable[[], T][int]), ([], int)) 7106 self.assertEqual(get_args(Callable[..., int]), (..., int)) 7107 self.assertEqual(get_args(Callable[[int], str]), ([int], str)) 7108 self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]), 7109 (int, Callable[[Tuple[T, ...]], str])) 7110 self.assertEqual(get_args(Tuple[int, ...]), (int, ...)) 7111 self.assertEqual(get_args(Tuple[()]), ()) 7112 self.assertEqual(get_args(Annotated[T, 'one', 2, ['three']]), (T, 'one', 2, ['three'])) 7113 self.assertEqual(get_args(List), ()) 7114 self.assertEqual(get_args(Tuple), ()) 7115 self.assertEqual(get_args(Callable), ()) 7116 self.assertEqual(get_args(list[int]), (int,)) 7117 self.assertEqual(get_args(list), ()) 7118 self.assertEqual(get_args(collections.abc.Callable[[int], str]), ([int], str)) 7119 self.assertEqual(get_args(collections.abc.Callable[..., str]), (..., str)) 7120 self.assertEqual(get_args(collections.abc.Callable[[], str]), ([], str)) 7121 self.assertEqual(get_args(collections.abc.Callable[[int], str]), 7122 get_args(Callable[[int], str])) 7123 P = ParamSpec('P') 7124 self.assertEqual(get_args(P), ()) 7125 self.assertEqual(get_args(P.args), ()) 7126 self.assertEqual(get_args(P.kwargs), ()) 7127 self.assertEqual(get_args(Callable[P, int]), (P, int)) 7128 self.assertEqual(get_args(collections.abc.Callable[P, int]), (P, int)) 7129 self.assertEqual(get_args(Callable[Concatenate[int, P], int]), 7130 (Concatenate[int, P], int)) 7131 self.assertEqual(get_args(collections.abc.Callable[Concatenate[int, P], int]), 7132 (Concatenate[int, P], int)) 7133 self.assertEqual(get_args(Concatenate[int, str, P]), (int, str, P)) 7134 self.assertEqual(get_args(list | str), (list, str)) 7135 self.assertEqual(get_args(Required[int]), (int,)) 7136 self.assertEqual(get_args(NotRequired[int]), (int,)) 7137 self.assertEqual(get_args(TypeAlias), ()) 7138 self.assertEqual(get_args(TypeGuard[int]), (int,)) 7139 self.assertEqual(get_args(TypeIs[range]), (range,)) 7140 Ts = TypeVarTuple('Ts') 7141 self.assertEqual(get_args(Ts), ()) 7142 self.assertEqual(get_args((*Ts,)[0]), (Ts,)) 7143 self.assertEqual(get_args(Unpack[Ts]), (Ts,)) 7144 self.assertEqual(get_args(tuple[*Ts]), (*Ts,)) 7145 self.assertEqual(get_args(tuple[Unpack[Ts]]), (Unpack[Ts],)) 7146 self.assertEqual(get_args((*tuple[*Ts],)[0]), (*Ts,)) 7147 self.assertEqual(get_args(Unpack[tuple[Unpack[Ts]]]), (tuple[Unpack[Ts]],)) 7148 7149 7150class CollectionsAbcTests(BaseTestCase): 7151 7152 def test_hashable(self): 7153 self.assertIsInstance(42, typing.Hashable) 7154 self.assertNotIsInstance([], typing.Hashable) 7155 7156 def test_iterable(self): 7157 self.assertIsInstance([], typing.Iterable) 7158 # Due to ABC caching, the second time takes a separate code 7159 # path and could fail. So call this a few times. 7160 self.assertIsInstance([], typing.Iterable) 7161 self.assertIsInstance([], typing.Iterable) 7162 self.assertNotIsInstance(42, typing.Iterable) 7163 # Just in case, also test issubclass() a few times. 7164 self.assertIsSubclass(list, typing.Iterable) 7165 self.assertIsSubclass(list, typing.Iterable) 7166 7167 def test_iterator(self): 7168 it = iter([]) 7169 self.assertIsInstance(it, typing.Iterator) 7170 self.assertNotIsInstance(42, typing.Iterator) 7171 7172 def test_awaitable(self): 7173 async def foo() -> typing.Awaitable[int]: 7174 return await AwaitableWrapper(42) 7175 g = foo() 7176 self.assertIsInstance(g, typing.Awaitable) 7177 self.assertNotIsInstance(foo, typing.Awaitable) 7178 g.send(None) # Run foo() till completion, to avoid warning. 7179 7180 def test_coroutine(self): 7181 async def foo(): 7182 return 7183 g = foo() 7184 self.assertIsInstance(g, typing.Coroutine) 7185 with self.assertRaises(TypeError): 7186 isinstance(g, typing.Coroutine[int]) 7187 self.assertNotIsInstance(foo, typing.Coroutine) 7188 try: 7189 g.send(None) 7190 except StopIteration: 7191 pass 7192 7193 def test_async_iterable(self): 7194 base_it = range(10) # type: Iterator[int] 7195 it = AsyncIteratorWrapper(base_it) 7196 self.assertIsInstance(it, typing.AsyncIterable) 7197 self.assertIsInstance(it, typing.AsyncIterable) 7198 self.assertNotIsInstance(42, typing.AsyncIterable) 7199 7200 def test_async_iterator(self): 7201 base_it = range(10) # type: Iterator[int] 7202 it = AsyncIteratorWrapper(base_it) 7203 self.assertIsInstance(it, typing.AsyncIterator) 7204 self.assertNotIsInstance(42, typing.AsyncIterator) 7205 7206 def test_sized(self): 7207 self.assertIsInstance([], typing.Sized) 7208 self.assertNotIsInstance(42, typing.Sized) 7209 7210 def test_container(self): 7211 self.assertIsInstance([], typing.Container) 7212 self.assertNotIsInstance(42, typing.Container) 7213 7214 def test_collection(self): 7215 self.assertIsInstance(tuple(), typing.Collection) 7216 self.assertIsInstance(frozenset(), typing.Collection) 7217 self.assertIsSubclass(dict, typing.Collection) 7218 self.assertNotIsInstance(42, typing.Collection) 7219 7220 def test_abstractset(self): 7221 self.assertIsInstance(set(), typing.AbstractSet) 7222 self.assertNotIsInstance(42, typing.AbstractSet) 7223 7224 def test_mutableset(self): 7225 self.assertIsInstance(set(), typing.MutableSet) 7226 self.assertNotIsInstance(frozenset(), typing.MutableSet) 7227 7228 def test_mapping(self): 7229 self.assertIsInstance({}, typing.Mapping) 7230 self.assertNotIsInstance(42, typing.Mapping) 7231 7232 def test_mutablemapping(self): 7233 self.assertIsInstance({}, typing.MutableMapping) 7234 self.assertNotIsInstance(42, typing.MutableMapping) 7235 7236 def test_sequence(self): 7237 self.assertIsInstance([], typing.Sequence) 7238 self.assertNotIsInstance(42, typing.Sequence) 7239 7240 def test_mutablesequence(self): 7241 self.assertIsInstance([], typing.MutableSequence) 7242 self.assertNotIsInstance((), typing.MutableSequence) 7243 7244 def test_bytestring(self): 7245 with self.assertWarns(DeprecationWarning): 7246 self.assertIsInstance(b'', typing.ByteString) 7247 with self.assertWarns(DeprecationWarning): 7248 self.assertIsInstance(bytearray(b''), typing.ByteString) 7249 with self.assertWarns(DeprecationWarning): 7250 class Foo(typing.ByteString): ... 7251 with self.assertWarns(DeprecationWarning): 7252 class Bar(typing.ByteString, typing.Awaitable): ... 7253 7254 def test_list(self): 7255 self.assertIsSubclass(list, typing.List) 7256 7257 def test_deque(self): 7258 self.assertIsSubclass(collections.deque, typing.Deque) 7259 class MyDeque(typing.Deque[int]): ... 7260 self.assertIsInstance(MyDeque(), collections.deque) 7261 7262 def test_counter(self): 7263 self.assertIsSubclass(collections.Counter, typing.Counter) 7264 7265 def test_set(self): 7266 self.assertIsSubclass(set, typing.Set) 7267 self.assertNotIsSubclass(frozenset, typing.Set) 7268 7269 def test_frozenset(self): 7270 self.assertIsSubclass(frozenset, typing.FrozenSet) 7271 self.assertNotIsSubclass(set, typing.FrozenSet) 7272 7273 def test_dict(self): 7274 self.assertIsSubclass(dict, typing.Dict) 7275 7276 def test_dict_subscribe(self): 7277 K = TypeVar('K') 7278 V = TypeVar('V') 7279 self.assertEqual(Dict[K, V][str, int], Dict[str, int]) 7280 self.assertEqual(Dict[K, int][str], Dict[str, int]) 7281 self.assertEqual(Dict[str, V][int], Dict[str, int]) 7282 self.assertEqual(Dict[K, List[V]][str, int], Dict[str, List[int]]) 7283 self.assertEqual(Dict[K, List[int]][str], Dict[str, List[int]]) 7284 self.assertEqual(Dict[K, list[V]][str, int], Dict[str, list[int]]) 7285 self.assertEqual(Dict[K, list[int]][str], Dict[str, list[int]]) 7286 7287 def test_no_list_instantiation(self): 7288 with self.assertRaises(TypeError): 7289 typing.List() 7290 with self.assertRaises(TypeError): 7291 typing.List[T]() 7292 with self.assertRaises(TypeError): 7293 typing.List[int]() 7294 7295 def test_list_subclass(self): 7296 7297 class MyList(typing.List[int]): 7298 pass 7299 7300 a = MyList() 7301 self.assertIsInstance(a, MyList) 7302 self.assertIsInstance(a, typing.Sequence) 7303 7304 self.assertIsSubclass(MyList, list) 7305 self.assertNotIsSubclass(list, MyList) 7306 7307 def test_no_dict_instantiation(self): 7308 with self.assertRaises(TypeError): 7309 typing.Dict() 7310 with self.assertRaises(TypeError): 7311 typing.Dict[KT, VT]() 7312 with self.assertRaises(TypeError): 7313 typing.Dict[str, int]() 7314 7315 def test_dict_subclass(self): 7316 7317 class MyDict(typing.Dict[str, int]): 7318 pass 7319 7320 d = MyDict() 7321 self.assertIsInstance(d, MyDict) 7322 self.assertIsInstance(d, typing.MutableMapping) 7323 7324 self.assertIsSubclass(MyDict, dict) 7325 self.assertNotIsSubclass(dict, MyDict) 7326 7327 def test_defaultdict_instantiation(self): 7328 self.assertIs(type(typing.DefaultDict()), collections.defaultdict) 7329 self.assertIs(type(typing.DefaultDict[KT, VT]()), collections.defaultdict) 7330 self.assertIs(type(typing.DefaultDict[str, int]()), collections.defaultdict) 7331 7332 def test_defaultdict_subclass(self): 7333 7334 class MyDefDict(typing.DefaultDict[str, int]): 7335 pass 7336 7337 dd = MyDefDict() 7338 self.assertIsInstance(dd, MyDefDict) 7339 7340 self.assertIsSubclass(MyDefDict, collections.defaultdict) 7341 self.assertNotIsSubclass(collections.defaultdict, MyDefDict) 7342 7343 def test_ordereddict_instantiation(self): 7344 self.assertIs(type(typing.OrderedDict()), collections.OrderedDict) 7345 self.assertIs(type(typing.OrderedDict[KT, VT]()), collections.OrderedDict) 7346 self.assertIs(type(typing.OrderedDict[str, int]()), collections.OrderedDict) 7347 7348 def test_ordereddict_subclass(self): 7349 7350 class MyOrdDict(typing.OrderedDict[str, int]): 7351 pass 7352 7353 od = MyOrdDict() 7354 self.assertIsInstance(od, MyOrdDict) 7355 7356 self.assertIsSubclass(MyOrdDict, collections.OrderedDict) 7357 self.assertNotIsSubclass(collections.OrderedDict, MyOrdDict) 7358 7359 def test_chainmap_instantiation(self): 7360 self.assertIs(type(typing.ChainMap()), collections.ChainMap) 7361 self.assertIs(type(typing.ChainMap[KT, VT]()), collections.ChainMap) 7362 self.assertIs(type(typing.ChainMap[str, int]()), collections.ChainMap) 7363 class CM(typing.ChainMap[KT, VT]): ... 7364 self.assertIs(type(CM[int, str]()), CM) 7365 7366 def test_chainmap_subclass(self): 7367 7368 class MyChainMap(typing.ChainMap[str, int]): 7369 pass 7370 7371 cm = MyChainMap() 7372 self.assertIsInstance(cm, MyChainMap) 7373 7374 self.assertIsSubclass(MyChainMap, collections.ChainMap) 7375 self.assertNotIsSubclass(collections.ChainMap, MyChainMap) 7376 7377 def test_deque_instantiation(self): 7378 self.assertIs(type(typing.Deque()), collections.deque) 7379 self.assertIs(type(typing.Deque[T]()), collections.deque) 7380 self.assertIs(type(typing.Deque[int]()), collections.deque) 7381 class D(typing.Deque[T]): ... 7382 self.assertIs(type(D[int]()), D) 7383 7384 def test_counter_instantiation(self): 7385 self.assertIs(type(typing.Counter()), collections.Counter) 7386 self.assertIs(type(typing.Counter[T]()), collections.Counter) 7387 self.assertIs(type(typing.Counter[int]()), collections.Counter) 7388 class C(typing.Counter[T]): ... 7389 self.assertIs(type(C[int]()), C) 7390 7391 def test_counter_subclass_instantiation(self): 7392 7393 class MyCounter(typing.Counter[int]): 7394 pass 7395 7396 d = MyCounter() 7397 self.assertIsInstance(d, MyCounter) 7398 self.assertIsInstance(d, typing.Counter) 7399 self.assertIsInstance(d, collections.Counter) 7400 7401 def test_no_set_instantiation(self): 7402 with self.assertRaises(TypeError): 7403 typing.Set() 7404 with self.assertRaises(TypeError): 7405 typing.Set[T]() 7406 with self.assertRaises(TypeError): 7407 typing.Set[int]() 7408 7409 def test_set_subclass_instantiation(self): 7410 7411 class MySet(typing.Set[int]): 7412 pass 7413 7414 d = MySet() 7415 self.assertIsInstance(d, MySet) 7416 7417 def test_no_frozenset_instantiation(self): 7418 with self.assertRaises(TypeError): 7419 typing.FrozenSet() 7420 with self.assertRaises(TypeError): 7421 typing.FrozenSet[T]() 7422 with self.assertRaises(TypeError): 7423 typing.FrozenSet[int]() 7424 7425 def test_frozenset_subclass_instantiation(self): 7426 7427 class MyFrozenSet(typing.FrozenSet[int]): 7428 pass 7429 7430 d = MyFrozenSet() 7431 self.assertIsInstance(d, MyFrozenSet) 7432 7433 def test_no_tuple_instantiation(self): 7434 with self.assertRaises(TypeError): 7435 Tuple() 7436 with self.assertRaises(TypeError): 7437 Tuple[T]() 7438 with self.assertRaises(TypeError): 7439 Tuple[int]() 7440 7441 def test_generator(self): 7442 def foo(): 7443 yield 42 7444 g = foo() 7445 self.assertIsSubclass(type(g), typing.Generator) 7446 7447 def test_generator_default(self): 7448 g1 = typing.Generator[int] 7449 g2 = typing.Generator[int, None, None] 7450 self.assertEqual(get_args(g1), (int, type(None), type(None))) 7451 self.assertEqual(get_args(g1), get_args(g2)) 7452 7453 g3 = typing.Generator[int, float] 7454 g4 = typing.Generator[int, float, None] 7455 self.assertEqual(get_args(g3), (int, float, type(None))) 7456 self.assertEqual(get_args(g3), get_args(g4)) 7457 7458 def test_no_generator_instantiation(self): 7459 with self.assertRaises(TypeError): 7460 typing.Generator() 7461 with self.assertRaises(TypeError): 7462 typing.Generator[T, T, T]() 7463 with self.assertRaises(TypeError): 7464 typing.Generator[int, int, int]() 7465 7466 def test_async_generator(self): 7467 async def f(): 7468 yield 42 7469 g = f() 7470 self.assertIsSubclass(type(g), typing.AsyncGenerator) 7471 7472 def test_no_async_generator_instantiation(self): 7473 with self.assertRaises(TypeError): 7474 typing.AsyncGenerator() 7475 with self.assertRaises(TypeError): 7476 typing.AsyncGenerator[T, T]() 7477 with self.assertRaises(TypeError): 7478 typing.AsyncGenerator[int, int]() 7479 7480 def test_subclassing(self): 7481 7482 class MMA(typing.MutableMapping): 7483 pass 7484 7485 with self.assertRaises(TypeError): # It's abstract 7486 MMA() 7487 7488 class MMC(MMA): 7489 def __getitem__(self, k): 7490 return None 7491 def __setitem__(self, k, v): 7492 pass 7493 def __delitem__(self, k): 7494 pass 7495 def __iter__(self): 7496 return iter(()) 7497 def __len__(self): 7498 return 0 7499 7500 self.assertEqual(len(MMC()), 0) 7501 self.assertTrue(callable(MMC.update)) 7502 self.assertIsInstance(MMC(), typing.Mapping) 7503 7504 class MMB(typing.MutableMapping[KT, VT]): 7505 def __getitem__(self, k): 7506 return None 7507 def __setitem__(self, k, v): 7508 pass 7509 def __delitem__(self, k): 7510 pass 7511 def __iter__(self): 7512 return iter(()) 7513 def __len__(self): 7514 return 0 7515 7516 self.assertEqual(len(MMB()), 0) 7517 self.assertEqual(len(MMB[str, str]()), 0) 7518 self.assertEqual(len(MMB[KT, VT]()), 0) 7519 7520 self.assertNotIsSubclass(dict, MMA) 7521 self.assertNotIsSubclass(dict, MMB) 7522 7523 self.assertIsSubclass(MMA, typing.Mapping) 7524 self.assertIsSubclass(MMB, typing.Mapping) 7525 self.assertIsSubclass(MMC, typing.Mapping) 7526 7527 self.assertIsInstance(MMB[KT, VT](), typing.Mapping) 7528 self.assertIsInstance(MMB[KT, VT](), collections.abc.Mapping) 7529 7530 self.assertIsSubclass(MMA, collections.abc.Mapping) 7531 self.assertIsSubclass(MMB, collections.abc.Mapping) 7532 self.assertIsSubclass(MMC, collections.abc.Mapping) 7533 7534 with self.assertRaises(TypeError): 7535 issubclass(MMB[str, str], typing.Mapping) 7536 self.assertIsSubclass(MMC, MMA) 7537 7538 class I(typing.Iterable): ... 7539 self.assertNotIsSubclass(list, I) 7540 7541 class G(typing.Generator[int, int, int]): ... 7542 def g(): yield 0 7543 self.assertIsSubclass(G, typing.Generator) 7544 self.assertIsSubclass(G, typing.Iterable) 7545 self.assertIsSubclass(G, collections.abc.Generator) 7546 self.assertIsSubclass(G, collections.abc.Iterable) 7547 self.assertNotIsSubclass(type(g), G) 7548 7549 def test_subclassing_async_generator(self): 7550 class G(typing.AsyncGenerator[int, int]): 7551 def asend(self, value): 7552 pass 7553 def athrow(self, typ, val=None, tb=None): 7554 pass 7555 7556 async def g(): yield 0 7557 7558 self.assertIsSubclass(G, typing.AsyncGenerator) 7559 self.assertIsSubclass(G, typing.AsyncIterable) 7560 self.assertIsSubclass(G, collections.abc.AsyncGenerator) 7561 self.assertIsSubclass(G, collections.abc.AsyncIterable) 7562 self.assertNotIsSubclass(type(g), G) 7563 7564 instance = G() 7565 self.assertIsInstance(instance, typing.AsyncGenerator) 7566 self.assertIsInstance(instance, typing.AsyncIterable) 7567 self.assertIsInstance(instance, collections.abc.AsyncGenerator) 7568 self.assertIsInstance(instance, collections.abc.AsyncIterable) 7569 self.assertNotIsInstance(type(g), G) 7570 self.assertNotIsInstance(g, G) 7571 7572 def test_subclassing_subclasshook(self): 7573 7574 class Base(typing.Iterable): 7575 @classmethod 7576 def __subclasshook__(cls, other): 7577 if other.__name__ == 'Foo': 7578 return True 7579 else: 7580 return False 7581 7582 class C(Base): ... 7583 class Foo: ... 7584 class Bar: ... 7585 self.assertIsSubclass(Foo, Base) 7586 self.assertIsSubclass(Foo, C) 7587 self.assertNotIsSubclass(Bar, C) 7588 7589 def test_subclassing_register(self): 7590 7591 class A(typing.Container): ... 7592 class B(A): ... 7593 7594 class C: ... 7595 A.register(C) 7596 self.assertIsSubclass(C, A) 7597 self.assertNotIsSubclass(C, B) 7598 7599 class D: ... 7600 B.register(D) 7601 self.assertIsSubclass(D, A) 7602 self.assertIsSubclass(D, B) 7603 7604 class M(): ... 7605 collections.abc.MutableMapping.register(M) 7606 self.assertIsSubclass(M, typing.Mapping) 7607 7608 def test_collections_as_base(self): 7609 7610 class M(collections.abc.Mapping): ... 7611 self.assertIsSubclass(M, typing.Mapping) 7612 self.assertIsSubclass(M, typing.Iterable) 7613 7614 class S(collections.abc.MutableSequence): ... 7615 self.assertIsSubclass(S, typing.MutableSequence) 7616 self.assertIsSubclass(S, typing.Iterable) 7617 7618 class I(collections.abc.Iterable): ... 7619 self.assertIsSubclass(I, typing.Iterable) 7620 7621 class A(collections.abc.Mapping, metaclass=abc.ABCMeta): ... 7622 class B: ... 7623 A.register(B) 7624 self.assertIsSubclass(B, typing.Mapping) 7625 7626 def test_or_and_ror(self): 7627 self.assertEqual(typing.Sized | typing.Awaitable, Union[typing.Sized, typing.Awaitable]) 7628 self.assertEqual(typing.Coroutine | typing.Hashable, Union[typing.Coroutine, typing.Hashable]) 7629 7630 7631class OtherABCTests(BaseTestCase): 7632 7633 def test_contextmanager(self): 7634 @contextlib.contextmanager 7635 def manager(): 7636 yield 42 7637 7638 cm = manager() 7639 self.assertIsInstance(cm, typing.ContextManager) 7640 self.assertNotIsInstance(42, typing.ContextManager) 7641 7642 def test_contextmanager_type_params(self): 7643 cm1 = typing.ContextManager[int] 7644 self.assertEqual(get_args(cm1), (int, bool | None)) 7645 cm2 = typing.ContextManager[int, None] 7646 self.assertEqual(get_args(cm2), (int, types.NoneType)) 7647 7648 type gen_cm[T1, T2] = typing.ContextManager[T1, T2] 7649 self.assertEqual(get_args(gen_cm.__value__[int, None]), (int, types.NoneType)) 7650 7651 def test_async_contextmanager(self): 7652 class NotACM: 7653 pass 7654 self.assertIsInstance(ACM(), typing.AsyncContextManager) 7655 self.assertNotIsInstance(NotACM(), typing.AsyncContextManager) 7656 @contextlib.contextmanager 7657 def manager(): 7658 yield 42 7659 7660 cm = manager() 7661 self.assertNotIsInstance(cm, typing.AsyncContextManager) 7662 self.assertEqual(typing.AsyncContextManager[int].__args__, (int, bool | None)) 7663 with self.assertRaises(TypeError): 7664 isinstance(42, typing.AsyncContextManager[int]) 7665 with self.assertRaises(TypeError): 7666 typing.AsyncContextManager[int, str, float] 7667 7668 def test_asynccontextmanager_type_params(self): 7669 cm1 = typing.AsyncContextManager[int] 7670 self.assertEqual(get_args(cm1), (int, bool | None)) 7671 cm2 = typing.AsyncContextManager[int, None] 7672 self.assertEqual(get_args(cm2), (int, types.NoneType)) 7673 7674 7675class TypeTests(BaseTestCase): 7676 7677 def test_type_basic(self): 7678 7679 class User: pass 7680 class BasicUser(User): pass 7681 class ProUser(User): pass 7682 7683 def new_user(user_class: Type[User]) -> User: 7684 return user_class() 7685 7686 new_user(BasicUser) 7687 7688 def test_type_typevar(self): 7689 7690 class User: pass 7691 class BasicUser(User): pass 7692 class ProUser(User): pass 7693 7694 U = TypeVar('U', bound=User) 7695 7696 def new_user(user_class: Type[U]) -> U: 7697 return user_class() 7698 7699 new_user(BasicUser) 7700 7701 def test_type_optional(self): 7702 A = Optional[Type[BaseException]] 7703 7704 def foo(a: A) -> Optional[BaseException]: 7705 if a is None: 7706 return None 7707 else: 7708 return a() 7709 7710 self.assertIsInstance(foo(KeyboardInterrupt), KeyboardInterrupt) 7711 self.assertIsNone(foo(None)) 7712 7713 7714class TestModules(TestCase): 7715 func_names = ['_idfunc'] 7716 7717 def test_c_functions(self): 7718 for fname in self.func_names: 7719 self.assertEqual(getattr(typing, fname).__module__, '_typing') 7720 7721 7722class NewTypeTests(BaseTestCase): 7723 @classmethod 7724 def setUpClass(cls): 7725 global UserId 7726 UserId = typing.NewType('UserId', int) 7727 cls.UserName = typing.NewType(cls.__qualname__ + '.UserName', str) 7728 7729 @classmethod 7730 def tearDownClass(cls): 7731 global UserId 7732 del UserId 7733 del cls.UserName 7734 7735 def test_basic(self): 7736 self.assertIsInstance(UserId(5), int) 7737 self.assertIsInstance(self.UserName('Joe'), str) 7738 self.assertEqual(UserId(5) + 1, 6) 7739 7740 def test_errors(self): 7741 with self.assertRaises(TypeError): 7742 issubclass(UserId, int) 7743 with self.assertRaises(TypeError): 7744 class D(UserId): 7745 pass 7746 7747 def test_or(self): 7748 for cls in (int, self.UserName): 7749 with self.subTest(cls=cls): 7750 self.assertEqual(UserId | cls, typing.Union[UserId, cls]) 7751 self.assertEqual(cls | UserId, typing.Union[cls, UserId]) 7752 7753 self.assertEqual(typing.get_args(UserId | cls), (UserId, cls)) 7754 self.assertEqual(typing.get_args(cls | UserId), (cls, UserId)) 7755 7756 def test_special_attrs(self): 7757 self.assertEqual(UserId.__name__, 'UserId') 7758 self.assertEqual(UserId.__qualname__, 'UserId') 7759 self.assertEqual(UserId.__module__, __name__) 7760 self.assertEqual(UserId.__supertype__, int) 7761 7762 UserName = self.UserName 7763 self.assertEqual(UserName.__name__, 'UserName') 7764 self.assertEqual(UserName.__qualname__, 7765 self.__class__.__qualname__ + '.UserName') 7766 self.assertEqual(UserName.__module__, __name__) 7767 self.assertEqual(UserName.__supertype__, str) 7768 7769 def test_repr(self): 7770 self.assertEqual(repr(UserId), f'{__name__}.UserId') 7771 self.assertEqual(repr(self.UserName), 7772 f'{__name__}.{self.__class__.__qualname__}.UserName') 7773 7774 def test_pickle(self): 7775 UserAge = typing.NewType('UserAge', float) 7776 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 7777 with self.subTest(proto=proto): 7778 pickled = pickle.dumps(UserId, proto) 7779 loaded = pickle.loads(pickled) 7780 self.assertIs(loaded, UserId) 7781 7782 pickled = pickle.dumps(self.UserName, proto) 7783 loaded = pickle.loads(pickled) 7784 self.assertIs(loaded, self.UserName) 7785 7786 with self.assertRaises(pickle.PicklingError): 7787 pickle.dumps(UserAge, proto) 7788 7789 def test_missing__name__(self): 7790 code = ("import typing\n" 7791 "NT = typing.NewType('NT', int)\n" 7792 ) 7793 exec(code, {}) 7794 7795 def test_error_message_when_subclassing(self): 7796 with self.assertRaisesRegex( 7797 TypeError, 7798 re.escape( 7799 "Cannot subclass an instance of NewType. Perhaps you were looking for: " 7800 "`ProUserId = NewType('ProUserId', UserId)`" 7801 ) 7802 ): 7803 class ProUserId(UserId): 7804 ... 7805 7806 7807class NamedTupleTests(BaseTestCase): 7808 class NestedEmployee(NamedTuple): 7809 name: str 7810 cool: int 7811 7812 def test_basics(self): 7813 Emp = NamedTuple('Emp', [('name', str), ('id', int)]) 7814 self.assertIsSubclass(Emp, tuple) 7815 joe = Emp('Joe', 42) 7816 jim = Emp(name='Jim', id=1) 7817 self.assertIsInstance(joe, Emp) 7818 self.assertIsInstance(joe, tuple) 7819 self.assertEqual(joe.name, 'Joe') 7820 self.assertEqual(joe.id, 42) 7821 self.assertEqual(jim.name, 'Jim') 7822 self.assertEqual(jim.id, 1) 7823 self.assertEqual(Emp.__name__, 'Emp') 7824 self.assertEqual(Emp._fields, ('name', 'id')) 7825 self.assertEqual(Emp.__annotations__, 7826 collections.OrderedDict([('name', str), ('id', int)])) 7827 7828 def test_annotation_usage(self): 7829 tim = CoolEmployee('Tim', 9000) 7830 self.assertIsInstance(tim, CoolEmployee) 7831 self.assertIsInstance(tim, tuple) 7832 self.assertEqual(tim.name, 'Tim') 7833 self.assertEqual(tim.cool, 9000) 7834 self.assertEqual(CoolEmployee.__name__, 'CoolEmployee') 7835 self.assertEqual(CoolEmployee._fields, ('name', 'cool')) 7836 self.assertEqual(CoolEmployee.__annotations__, 7837 collections.OrderedDict(name=str, cool=int)) 7838 7839 def test_annotation_usage_with_default(self): 7840 jelle = CoolEmployeeWithDefault('Jelle') 7841 self.assertIsInstance(jelle, CoolEmployeeWithDefault) 7842 self.assertIsInstance(jelle, tuple) 7843 self.assertEqual(jelle.name, 'Jelle') 7844 self.assertEqual(jelle.cool, 0) 7845 cooler_employee = CoolEmployeeWithDefault('Sjoerd', 1) 7846 self.assertEqual(cooler_employee.cool, 1) 7847 7848 self.assertEqual(CoolEmployeeWithDefault.__name__, 'CoolEmployeeWithDefault') 7849 self.assertEqual(CoolEmployeeWithDefault._fields, ('name', 'cool')) 7850 self.assertEqual(CoolEmployeeWithDefault.__annotations__, 7851 dict(name=str, cool=int)) 7852 self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0)) 7853 7854 with self.assertRaises(TypeError): 7855 class NonDefaultAfterDefault(NamedTuple): 7856 x: int = 3 7857 y: int 7858 7859 def test_annotation_usage_with_methods(self): 7860 self.assertEqual(XMeth(1).double(), 2) 7861 self.assertEqual(XMeth(42).x, XMeth(42)[0]) 7862 self.assertEqual(str(XRepr(42)), '42 -> 1') 7863 self.assertEqual(XRepr(1, 2) + XRepr(3), 0) 7864 7865 with self.assertRaises(AttributeError): 7866 class XMethBad(NamedTuple): 7867 x: int 7868 def _fields(self): 7869 return 'no chance for this' 7870 7871 with self.assertRaises(AttributeError): 7872 class XMethBad2(NamedTuple): 7873 x: int 7874 def _source(self): 7875 return 'no chance for this as well' 7876 7877 def test_multiple_inheritance(self): 7878 class A: 7879 pass 7880 with self.assertRaises(TypeError): 7881 class X(NamedTuple, A): 7882 x: int 7883 with self.assertRaises(TypeError): 7884 class Y(NamedTuple, tuple): 7885 x: int 7886 with self.assertRaises(TypeError): 7887 class Z(NamedTuple, NamedTuple): 7888 x: int 7889 class B(NamedTuple): 7890 x: int 7891 with self.assertRaises(TypeError): 7892 class C(NamedTuple, B): 7893 y: str 7894 7895 def test_generic(self): 7896 class X(NamedTuple, Generic[T]): 7897 x: T 7898 self.assertEqual(X.__bases__, (tuple, Generic)) 7899 self.assertEqual(X.__orig_bases__, (NamedTuple, Generic[T])) 7900 self.assertEqual(X.__mro__, (X, tuple, Generic, object)) 7901 7902 class Y(Generic[T], NamedTuple): 7903 x: T 7904 self.assertEqual(Y.__bases__, (Generic, tuple)) 7905 self.assertEqual(Y.__orig_bases__, (Generic[T], NamedTuple)) 7906 self.assertEqual(Y.__mro__, (Y, Generic, tuple, object)) 7907 7908 for G in X, Y: 7909 with self.subTest(type=G): 7910 self.assertEqual(G.__parameters__, (T,)) 7911 self.assertEqual(G[T].__args__, (T,)) 7912 self.assertEqual(get_args(G[T]), (T,)) 7913 A = G[int] 7914 self.assertIs(A.__origin__, G) 7915 self.assertEqual(A.__args__, (int,)) 7916 self.assertEqual(get_args(A), (int,)) 7917 self.assertEqual(A.__parameters__, ()) 7918 7919 a = A(3) 7920 self.assertIs(type(a), G) 7921 self.assertEqual(a.x, 3) 7922 7923 with self.assertRaises(TypeError): 7924 G[int, str] 7925 7926 def test_generic_pep695(self): 7927 class X[T](NamedTuple): 7928 x: T 7929 T, = X.__type_params__ 7930 self.assertIsInstance(T, TypeVar) 7931 self.assertEqual(T.__name__, 'T') 7932 self.assertEqual(X.__bases__, (tuple, Generic)) 7933 self.assertEqual(X.__orig_bases__, (NamedTuple, Generic[T])) 7934 self.assertEqual(X.__mro__, (X, tuple, Generic, object)) 7935 self.assertEqual(X.__parameters__, (T,)) 7936 self.assertEqual(X[str].__args__, (str,)) 7937 self.assertEqual(X[str].__parameters__, ()) 7938 7939 def test_non_generic_subscript(self): 7940 # For backward compatibility, subscription works 7941 # on arbitrary NamedTuple types. 7942 class Group(NamedTuple): 7943 key: T 7944 group: list[T] 7945 A = Group[int] 7946 self.assertEqual(A.__origin__, Group) 7947 self.assertEqual(A.__parameters__, ()) 7948 self.assertEqual(A.__args__, (int,)) 7949 a = A(1, [2]) 7950 self.assertIs(type(a), Group) 7951 self.assertEqual(a, (1, [2])) 7952 7953 def test_namedtuple_keyword_usage(self): 7954 with self.assertWarnsRegex( 7955 DeprecationWarning, 7956 "Creating NamedTuple classes using keyword arguments is deprecated" 7957 ): 7958 LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int) 7959 7960 nick = LocalEmployee('Nick', 25) 7961 self.assertIsInstance(nick, tuple) 7962 self.assertEqual(nick.name, 'Nick') 7963 self.assertEqual(LocalEmployee.__name__, 'LocalEmployee') 7964 self.assertEqual(LocalEmployee._fields, ('name', 'age')) 7965 self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int)) 7966 7967 with self.assertRaisesRegex( 7968 TypeError, 7969 "Either list of fields or keywords can be provided to NamedTuple, not both" 7970 ): 7971 NamedTuple('Name', [('x', int)], y=str) 7972 7973 with self.assertRaisesRegex( 7974 TypeError, 7975 "Either list of fields or keywords can be provided to NamedTuple, not both" 7976 ): 7977 NamedTuple('Name', [], y=str) 7978 7979 with self.assertRaisesRegex( 7980 TypeError, 7981 ( 7982 r"Cannot pass `None` as the 'fields' parameter " 7983 r"and also specify fields using keyword arguments" 7984 ) 7985 ): 7986 NamedTuple('Name', None, x=int) 7987 7988 def test_namedtuple_special_keyword_names(self): 7989 with self.assertWarnsRegex( 7990 DeprecationWarning, 7991 "Creating NamedTuple classes using keyword arguments is deprecated" 7992 ): 7993 NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list) 7994 7995 self.assertEqual(NT.__name__, 'NT') 7996 self.assertEqual(NT._fields, ('cls', 'self', 'typename', 'fields')) 7997 a = NT(cls=str, self=42, typename='foo', fields=[('bar', tuple)]) 7998 self.assertEqual(a.cls, str) 7999 self.assertEqual(a.self, 42) 8000 self.assertEqual(a.typename, 'foo') 8001 self.assertEqual(a.fields, [('bar', tuple)]) 8002 8003 def test_empty_namedtuple(self): 8004 expected_warning = re.escape( 8005 "Failing to pass a value for the 'fields' parameter is deprecated " 8006 "and will be disallowed in Python 3.15. " 8007 "To create a NamedTuple class with 0 fields " 8008 "using the functional syntax, " 8009 "pass an empty list, e.g. `NT1 = NamedTuple('NT1', [])`." 8010 ) 8011 with self.assertWarnsRegex(DeprecationWarning, fr"^{expected_warning}$"): 8012 NT1 = NamedTuple('NT1') 8013 8014 expected_warning = re.escape( 8015 "Passing `None` as the 'fields' parameter is deprecated " 8016 "and will be disallowed in Python 3.15. " 8017 "To create a NamedTuple class with 0 fields " 8018 "using the functional syntax, " 8019 "pass an empty list, e.g. `NT2 = NamedTuple('NT2', [])`." 8020 ) 8021 with self.assertWarnsRegex(DeprecationWarning, fr"^{expected_warning}$"): 8022 NT2 = NamedTuple('NT2', None) 8023 8024 NT3 = NamedTuple('NT2', []) 8025 8026 class CNT(NamedTuple): 8027 pass # empty body 8028 8029 for struct in NT1, NT2, NT3, CNT: 8030 with self.subTest(struct=struct): 8031 self.assertEqual(struct._fields, ()) 8032 self.assertEqual(struct._field_defaults, {}) 8033 self.assertEqual(struct.__annotations__, {}) 8034 self.assertIsInstance(struct(), struct) 8035 8036 def test_namedtuple_errors(self): 8037 with self.assertRaises(TypeError): 8038 NamedTuple.__new__() 8039 8040 with self.assertRaisesRegex( 8041 TypeError, 8042 "missing 1 required positional argument" 8043 ): 8044 NamedTuple() 8045 8046 with self.assertRaisesRegex( 8047 TypeError, 8048 "takes from 1 to 2 positional arguments but 3 were given" 8049 ): 8050 NamedTuple('Emp', [('name', str)], None) 8051 8052 with self.assertRaisesRegex( 8053 ValueError, 8054 "Field names cannot start with an underscore" 8055 ): 8056 NamedTuple('Emp', [('_name', str)]) 8057 8058 with self.assertRaisesRegex( 8059 TypeError, 8060 "missing 1 required positional argument: 'typename'" 8061 ): 8062 NamedTuple(typename='Emp', name=str, id=int) 8063 8064 def test_copy_and_pickle(self): 8065 global Emp # pickle wants to reference the class by name 8066 Emp = NamedTuple('Emp', [('name', str), ('cool', int)]) 8067 for cls in Emp, CoolEmployee, self.NestedEmployee: 8068 with self.subTest(cls=cls): 8069 jane = cls('jane', 37) 8070 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 8071 z = pickle.dumps(jane, proto) 8072 jane2 = pickle.loads(z) 8073 self.assertEqual(jane2, jane) 8074 self.assertIsInstance(jane2, cls) 8075 8076 jane2 = copy(jane) 8077 self.assertEqual(jane2, jane) 8078 self.assertIsInstance(jane2, cls) 8079 8080 jane2 = deepcopy(jane) 8081 self.assertEqual(jane2, jane) 8082 self.assertIsInstance(jane2, cls) 8083 8084 def test_orig_bases(self): 8085 T = TypeVar('T') 8086 8087 class SimpleNamedTuple(NamedTuple): 8088 pass 8089 8090 class GenericNamedTuple(NamedTuple, Generic[T]): 8091 pass 8092 8093 self.assertEqual(SimpleNamedTuple.__orig_bases__, (NamedTuple,)) 8094 self.assertEqual(GenericNamedTuple.__orig_bases__, (NamedTuple, Generic[T])) 8095 8096 CallNamedTuple = NamedTuple('CallNamedTuple', []) 8097 8098 self.assertEqual(CallNamedTuple.__orig_bases__, (NamedTuple,)) 8099 8100 def test_setname_called_on_values_in_class_dictionary(self): 8101 class Vanilla: 8102 def __set_name__(self, owner, name): 8103 self.name = name 8104 8105 class Foo(NamedTuple): 8106 attr = Vanilla() 8107 8108 foo = Foo() 8109 self.assertEqual(len(foo), 0) 8110 self.assertNotIn('attr', Foo._fields) 8111 self.assertIsInstance(foo.attr, Vanilla) 8112 self.assertEqual(foo.attr.name, "attr") 8113 8114 class Bar(NamedTuple): 8115 attr: Vanilla = Vanilla() 8116 8117 bar = Bar() 8118 self.assertEqual(len(bar), 1) 8119 self.assertIn('attr', Bar._fields) 8120 self.assertIsInstance(bar.attr, Vanilla) 8121 self.assertEqual(bar.attr.name, "attr") 8122 8123 def test_setname_raises_the_same_as_on_other_classes(self): 8124 class CustomException(BaseException): pass 8125 8126 class Annoying: 8127 def __set_name__(self, owner, name): 8128 raise CustomException 8129 8130 annoying = Annoying() 8131 8132 with self.assertRaises(CustomException) as cm: 8133 class NormalClass: 8134 attr = annoying 8135 normal_exception = cm.exception 8136 8137 with self.assertRaises(CustomException) as cm: 8138 class NamedTupleClass(NamedTuple): 8139 attr = annoying 8140 namedtuple_exception = cm.exception 8141 8142 self.assertIs(type(namedtuple_exception), CustomException) 8143 self.assertIs(type(namedtuple_exception), type(normal_exception)) 8144 8145 self.assertEqual(len(namedtuple_exception.__notes__), 1) 8146 self.assertEqual( 8147 len(namedtuple_exception.__notes__), len(normal_exception.__notes__) 8148 ) 8149 8150 expected_note = ( 8151 "Error calling __set_name__ on 'Annoying' instance " 8152 "'attr' in 'NamedTupleClass'" 8153 ) 8154 self.assertEqual(namedtuple_exception.__notes__[0], expected_note) 8155 self.assertEqual( 8156 namedtuple_exception.__notes__[0], 8157 normal_exception.__notes__[0].replace("NormalClass", "NamedTupleClass") 8158 ) 8159 8160 def test_strange_errors_when_accessing_set_name_itself(self): 8161 class CustomException(Exception): pass 8162 8163 class Meta(type): 8164 def __getattribute__(self, attr): 8165 if attr == "__set_name__": 8166 raise CustomException 8167 return object.__getattribute__(self, attr) 8168 8169 class VeryAnnoying(metaclass=Meta): pass 8170 8171 very_annoying = VeryAnnoying() 8172 8173 with self.assertRaises(CustomException): 8174 class Foo(NamedTuple): 8175 attr = very_annoying 8176 8177 8178class TypedDictTests(BaseTestCase): 8179 def test_basics_functional_syntax(self): 8180 Emp = TypedDict('Emp', {'name': str, 'id': int}) 8181 self.assertIsSubclass(Emp, dict) 8182 self.assertIsSubclass(Emp, typing.MutableMapping) 8183 self.assertNotIsSubclass(Emp, collections.abc.Sequence) 8184 jim = Emp(name='Jim', id=1) 8185 self.assertIs(type(jim), dict) 8186 self.assertEqual(jim['name'], 'Jim') 8187 self.assertEqual(jim['id'], 1) 8188 self.assertEqual(Emp.__name__, 'Emp') 8189 self.assertEqual(Emp.__module__, __name__) 8190 self.assertEqual(Emp.__bases__, (dict,)) 8191 self.assertEqual(Emp.__annotations__, {'name': str, 'id': int}) 8192 self.assertEqual(Emp.__total__, True) 8193 self.assertEqual(Emp.__required_keys__, {'name', 'id'}) 8194 self.assertIsInstance(Emp.__required_keys__, frozenset) 8195 self.assertEqual(Emp.__optional_keys__, set()) 8196 self.assertIsInstance(Emp.__optional_keys__, frozenset) 8197 8198 def test_typeddict_create_errors(self): 8199 with self.assertRaises(TypeError): 8200 TypedDict.__new__() 8201 with self.assertRaises(TypeError): 8202 TypedDict() 8203 with self.assertRaises(TypeError): 8204 TypedDict('Emp', [('name', str)], None) 8205 with self.assertRaises(TypeError): 8206 TypedDict(_typename='Emp') 8207 with self.assertRaises(TypeError): 8208 TypedDict('Emp', name=str, id=int) 8209 8210 def test_typeddict_errors(self): 8211 Emp = TypedDict('Emp', {'name': str, 'id': int}) 8212 self.assertEqual(TypedDict.__module__, 'typing') 8213 jim = Emp(name='Jim', id=1) 8214 with self.assertRaises(TypeError): 8215 isinstance({}, Emp) 8216 with self.assertRaises(TypeError): 8217 isinstance(jim, Emp) 8218 with self.assertRaises(TypeError): 8219 issubclass(dict, Emp) 8220 with self.assertRaises(TypeError): 8221 TypedDict('Hi', [('x', int)], y=int) 8222 8223 def test_py36_class_syntax_usage(self): 8224 self.assertEqual(LabelPoint2D.__name__, 'LabelPoint2D') 8225 self.assertEqual(LabelPoint2D.__module__, __name__) 8226 self.assertEqual(LabelPoint2D.__annotations__, {'x': int, 'y': int, 'label': str}) 8227 self.assertEqual(LabelPoint2D.__bases__, (dict,)) 8228 self.assertEqual(LabelPoint2D.__total__, True) 8229 self.assertNotIsSubclass(LabelPoint2D, typing.Sequence) 8230 not_origin = Point2D(x=0, y=1) 8231 self.assertEqual(not_origin['x'], 0) 8232 self.assertEqual(not_origin['y'], 1) 8233 other = LabelPoint2D(x=0, y=1, label='hi') 8234 self.assertEqual(other['label'], 'hi') 8235 8236 def test_pickle(self): 8237 global EmpD # pickle wants to reference the class by name 8238 EmpD = TypedDict('EmpD', {'name': str, 'id': int}) 8239 jane = EmpD({'name': 'jane', 'id': 37}) 8240 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 8241 z = pickle.dumps(jane, proto) 8242 jane2 = pickle.loads(z) 8243 self.assertEqual(jane2, jane) 8244 self.assertEqual(jane2, {'name': 'jane', 'id': 37}) 8245 ZZ = pickle.dumps(EmpD, proto) 8246 EmpDnew = pickle.loads(ZZ) 8247 self.assertEqual(EmpDnew({'name': 'jane', 'id': 37}), jane) 8248 8249 def test_pickle_generic(self): 8250 point = Point2DGeneric(a=5.0, b=3.0) 8251 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 8252 z = pickle.dumps(point, proto) 8253 point2 = pickle.loads(z) 8254 self.assertEqual(point2, point) 8255 self.assertEqual(point2, {'a': 5.0, 'b': 3.0}) 8256 ZZ = pickle.dumps(Point2DGeneric, proto) 8257 Point2DGenericNew = pickle.loads(ZZ) 8258 self.assertEqual(Point2DGenericNew({'a': 5.0, 'b': 3.0}), point) 8259 8260 def test_optional(self): 8261 EmpD = TypedDict('EmpD', {'name': str, 'id': int}) 8262 8263 self.assertEqual(typing.Optional[EmpD], typing.Union[None, EmpD]) 8264 self.assertNotEqual(typing.List[EmpD], typing.Tuple[EmpD]) 8265 8266 def test_total(self): 8267 D = TypedDict('D', {'x': int}, total=False) 8268 self.assertEqual(D(), {}) 8269 self.assertEqual(D(x=1), {'x': 1}) 8270 self.assertEqual(D.__total__, False) 8271 self.assertEqual(D.__required_keys__, frozenset()) 8272 self.assertIsInstance(D.__required_keys__, frozenset) 8273 self.assertEqual(D.__optional_keys__, {'x'}) 8274 self.assertIsInstance(D.__optional_keys__, frozenset) 8275 8276 self.assertEqual(Options(), {}) 8277 self.assertEqual(Options(log_level=2), {'log_level': 2}) 8278 self.assertEqual(Options.__total__, False) 8279 self.assertEqual(Options.__required_keys__, frozenset()) 8280 self.assertEqual(Options.__optional_keys__, {'log_level', 'log_path'}) 8281 8282 def test_total_inherits_non_total(self): 8283 class TD1(TypedDict, total=False): 8284 a: int 8285 8286 self.assertIs(TD1.__total__, False) 8287 8288 class TD2(TD1): 8289 b: str 8290 8291 self.assertIs(TD2.__total__, True) 8292 8293 def test_optional_keys(self): 8294 class Point2Dor3D(Point2D, total=False): 8295 z: int 8296 8297 self.assertEqual(Point2Dor3D.__required_keys__, frozenset(['x', 'y'])) 8298 self.assertIsInstance(Point2Dor3D.__required_keys__, frozenset) 8299 self.assertEqual(Point2Dor3D.__optional_keys__, frozenset(['z'])) 8300 self.assertIsInstance(Point2Dor3D.__optional_keys__, frozenset) 8301 8302 def test_keys_inheritance(self): 8303 class BaseAnimal(TypedDict): 8304 name: str 8305 8306 class Animal(BaseAnimal, total=False): 8307 voice: str 8308 tail: bool 8309 8310 class Cat(Animal): 8311 fur_color: str 8312 8313 self.assertEqual(BaseAnimal.__required_keys__, frozenset(['name'])) 8314 self.assertEqual(BaseAnimal.__optional_keys__, frozenset([])) 8315 self.assertEqual(BaseAnimal.__annotations__, {'name': str}) 8316 8317 self.assertEqual(Animal.__required_keys__, frozenset(['name'])) 8318 self.assertEqual(Animal.__optional_keys__, frozenset(['tail', 'voice'])) 8319 self.assertEqual(Animal.__annotations__, { 8320 'name': str, 8321 'tail': bool, 8322 'voice': str, 8323 }) 8324 8325 self.assertEqual(Cat.__required_keys__, frozenset(['name', 'fur_color'])) 8326 self.assertEqual(Cat.__optional_keys__, frozenset(['tail', 'voice'])) 8327 self.assertEqual(Cat.__annotations__, { 8328 'fur_color': str, 8329 'name': str, 8330 'tail': bool, 8331 'voice': str, 8332 }) 8333 8334 def test_keys_inheritance_with_same_name(self): 8335 class NotTotal(TypedDict, total=False): 8336 a: int 8337 8338 class Total(NotTotal): 8339 a: int 8340 8341 self.assertEqual(NotTotal.__required_keys__, frozenset()) 8342 self.assertEqual(NotTotal.__optional_keys__, frozenset(['a'])) 8343 self.assertEqual(Total.__required_keys__, frozenset(['a'])) 8344 self.assertEqual(Total.__optional_keys__, frozenset()) 8345 8346 class Base(TypedDict): 8347 a: NotRequired[int] 8348 b: Required[int] 8349 8350 class Child(Base): 8351 a: Required[int] 8352 b: NotRequired[int] 8353 8354 self.assertEqual(Base.__required_keys__, frozenset(['b'])) 8355 self.assertEqual(Base.__optional_keys__, frozenset(['a'])) 8356 self.assertEqual(Child.__required_keys__, frozenset(['a'])) 8357 self.assertEqual(Child.__optional_keys__, frozenset(['b'])) 8358 8359 def test_multiple_inheritance_with_same_key(self): 8360 class Base1(TypedDict): 8361 a: NotRequired[int] 8362 8363 class Base2(TypedDict): 8364 a: Required[str] 8365 8366 class Child(Base1, Base2): 8367 pass 8368 8369 # Last base wins 8370 self.assertEqual(Child.__annotations__, {'a': Required[str]}) 8371 self.assertEqual(Child.__required_keys__, frozenset(['a'])) 8372 self.assertEqual(Child.__optional_keys__, frozenset()) 8373 8374 def test_required_notrequired_keys(self): 8375 self.assertEqual(NontotalMovie.__required_keys__, 8376 frozenset({"title"})) 8377 self.assertEqual(NontotalMovie.__optional_keys__, 8378 frozenset({"year"})) 8379 8380 self.assertEqual(TotalMovie.__required_keys__, 8381 frozenset({"title"})) 8382 self.assertEqual(TotalMovie.__optional_keys__, 8383 frozenset({"year"})) 8384 8385 self.assertEqual(_typed_dict_helper.VeryAnnotated.__required_keys__, 8386 frozenset()) 8387 self.assertEqual(_typed_dict_helper.VeryAnnotated.__optional_keys__, 8388 frozenset({"a"})) 8389 8390 self.assertEqual(AnnotatedMovie.__required_keys__, 8391 frozenset({"title"})) 8392 self.assertEqual(AnnotatedMovie.__optional_keys__, 8393 frozenset({"year"})) 8394 8395 self.assertEqual(WeirdlyQuotedMovie.__required_keys__, 8396 frozenset({"title"})) 8397 self.assertEqual(WeirdlyQuotedMovie.__optional_keys__, 8398 frozenset({"year"})) 8399 8400 self.assertEqual(ChildTotalMovie.__required_keys__, 8401 frozenset({"title"})) 8402 self.assertEqual(ChildTotalMovie.__optional_keys__, 8403 frozenset({"year"})) 8404 8405 self.assertEqual(ChildDeeplyAnnotatedMovie.__required_keys__, 8406 frozenset({"title"})) 8407 self.assertEqual(ChildDeeplyAnnotatedMovie.__optional_keys__, 8408 frozenset({"year"})) 8409 8410 def test_multiple_inheritance(self): 8411 class One(TypedDict): 8412 one: int 8413 class Two(TypedDict): 8414 two: str 8415 class Untotal(TypedDict, total=False): 8416 untotal: str 8417 Inline = TypedDict('Inline', {'inline': bool}) 8418 class Regular: 8419 pass 8420 8421 class Child(One, Two): 8422 child: bool 8423 self.assertEqual( 8424 Child.__required_keys__, 8425 frozenset(['one', 'two', 'child']), 8426 ) 8427 self.assertEqual( 8428 Child.__optional_keys__, 8429 frozenset([]), 8430 ) 8431 self.assertEqual( 8432 Child.__annotations__, 8433 {'one': int, 'two': str, 'child': bool}, 8434 ) 8435 8436 class ChildWithOptional(One, Untotal): 8437 child: bool 8438 self.assertEqual( 8439 ChildWithOptional.__required_keys__, 8440 frozenset(['one', 'child']), 8441 ) 8442 self.assertEqual( 8443 ChildWithOptional.__optional_keys__, 8444 frozenset(['untotal']), 8445 ) 8446 self.assertEqual( 8447 ChildWithOptional.__annotations__, 8448 {'one': int, 'untotal': str, 'child': bool}, 8449 ) 8450 8451 class ChildWithTotalFalse(One, Untotal, total=False): 8452 child: bool 8453 self.assertEqual( 8454 ChildWithTotalFalse.__required_keys__, 8455 frozenset(['one']), 8456 ) 8457 self.assertEqual( 8458 ChildWithTotalFalse.__optional_keys__, 8459 frozenset(['untotal', 'child']), 8460 ) 8461 self.assertEqual( 8462 ChildWithTotalFalse.__annotations__, 8463 {'one': int, 'untotal': str, 'child': bool}, 8464 ) 8465 8466 class ChildWithInlineAndOptional(Untotal, Inline): 8467 child: bool 8468 self.assertEqual( 8469 ChildWithInlineAndOptional.__required_keys__, 8470 frozenset(['inline', 'child']), 8471 ) 8472 self.assertEqual( 8473 ChildWithInlineAndOptional.__optional_keys__, 8474 frozenset(['untotal']), 8475 ) 8476 self.assertEqual( 8477 ChildWithInlineAndOptional.__annotations__, 8478 {'inline': bool, 'untotal': str, 'child': bool}, 8479 ) 8480 8481 wrong_bases = [ 8482 (One, Regular), 8483 (Regular, One), 8484 (One, Two, Regular), 8485 (Inline, Regular), 8486 (Untotal, Regular), 8487 ] 8488 for bases in wrong_bases: 8489 with self.subTest(bases=bases): 8490 with self.assertRaisesRegex( 8491 TypeError, 8492 'cannot inherit from both a TypedDict type and a non-TypedDict', 8493 ): 8494 class Wrong(*bases): 8495 pass 8496 8497 def test_is_typeddict(self): 8498 self.assertIs(is_typeddict(Point2D), True) 8499 self.assertIs(is_typeddict(Union[str, int]), False) 8500 # classes, not instances 8501 self.assertIs(is_typeddict(Point2D()), False) 8502 call_based = TypedDict('call_based', {'a': int}) 8503 self.assertIs(is_typeddict(call_based), True) 8504 self.assertIs(is_typeddict(call_based()), False) 8505 8506 T = TypeVar("T") 8507 class BarGeneric(TypedDict, Generic[T]): 8508 a: T 8509 self.assertIs(is_typeddict(BarGeneric), True) 8510 self.assertIs(is_typeddict(BarGeneric[int]), False) 8511 self.assertIs(is_typeddict(BarGeneric()), False) 8512 8513 class NewGeneric[T](TypedDict): 8514 a: T 8515 self.assertIs(is_typeddict(NewGeneric), True) 8516 self.assertIs(is_typeddict(NewGeneric[int]), False) 8517 self.assertIs(is_typeddict(NewGeneric()), False) 8518 8519 # The TypedDict constructor is not itself a TypedDict 8520 self.assertIs(is_typeddict(TypedDict), False) 8521 8522 def test_get_type_hints(self): 8523 self.assertEqual( 8524 get_type_hints(Bar), 8525 {'a': typing.Optional[int], 'b': int} 8526 ) 8527 8528 def test_get_type_hints_generic(self): 8529 self.assertEqual( 8530 get_type_hints(BarGeneric), 8531 {'a': typing.Optional[T], 'b': int} 8532 ) 8533 8534 class FooBarGeneric(BarGeneric[int]): 8535 c: str 8536 8537 self.assertEqual( 8538 get_type_hints(FooBarGeneric), 8539 {'a': typing.Optional[T], 'b': int, 'c': str} 8540 ) 8541 8542 def test_pep695_generic_typeddict(self): 8543 class A[T](TypedDict): 8544 a: T 8545 8546 T, = A.__type_params__ 8547 self.assertIsInstance(T, TypeVar) 8548 self.assertEqual(T.__name__, 'T') 8549 self.assertEqual(A.__bases__, (Generic, dict)) 8550 self.assertEqual(A.__orig_bases__, (TypedDict, Generic[T])) 8551 self.assertEqual(A.__mro__, (A, Generic, dict, object)) 8552 self.assertEqual(A.__parameters__, (T,)) 8553 self.assertEqual(A[str].__parameters__, ()) 8554 self.assertEqual(A[str].__args__, (str,)) 8555 8556 def test_generic_inheritance(self): 8557 class A(TypedDict, Generic[T]): 8558 a: T 8559 8560 self.assertEqual(A.__bases__, (Generic, dict)) 8561 self.assertEqual(A.__orig_bases__, (TypedDict, Generic[T])) 8562 self.assertEqual(A.__mro__, (A, Generic, dict, object)) 8563 self.assertEqual(A.__parameters__, (T,)) 8564 self.assertEqual(A[str].__parameters__, ()) 8565 self.assertEqual(A[str].__args__, (str,)) 8566 8567 class A2(Generic[T], TypedDict): 8568 a: T 8569 8570 self.assertEqual(A2.__bases__, (Generic, dict)) 8571 self.assertEqual(A2.__orig_bases__, (Generic[T], TypedDict)) 8572 self.assertEqual(A2.__mro__, (A2, Generic, dict, object)) 8573 self.assertEqual(A2.__parameters__, (T,)) 8574 self.assertEqual(A2[str].__parameters__, ()) 8575 self.assertEqual(A2[str].__args__, (str,)) 8576 8577 class B(A[KT], total=False): 8578 b: KT 8579 8580 self.assertEqual(B.__bases__, (Generic, dict)) 8581 self.assertEqual(B.__orig_bases__, (A[KT],)) 8582 self.assertEqual(B.__mro__, (B, Generic, dict, object)) 8583 self.assertEqual(B.__parameters__, (KT,)) 8584 self.assertEqual(B.__total__, False) 8585 self.assertEqual(B.__optional_keys__, frozenset(['b'])) 8586 self.assertEqual(B.__required_keys__, frozenset(['a'])) 8587 8588 self.assertEqual(B[str].__parameters__, ()) 8589 self.assertEqual(B[str].__args__, (str,)) 8590 self.assertEqual(B[str].__origin__, B) 8591 8592 class C(B[int]): 8593 c: int 8594 8595 self.assertEqual(C.__bases__, (Generic, dict)) 8596 self.assertEqual(C.__orig_bases__, (B[int],)) 8597 self.assertEqual(C.__mro__, (C, Generic, dict, object)) 8598 self.assertEqual(C.__parameters__, ()) 8599 self.assertEqual(C.__total__, True) 8600 self.assertEqual(C.__optional_keys__, frozenset(['b'])) 8601 self.assertEqual(C.__required_keys__, frozenset(['a', 'c'])) 8602 self.assertEqual(C.__annotations__, { 8603 'a': T, 8604 'b': KT, 8605 'c': int, 8606 }) 8607 with self.assertRaises(TypeError): 8608 C[str] 8609 8610 8611 class Point3D(Point2DGeneric[T], Generic[T, KT]): 8612 c: KT 8613 8614 self.assertEqual(Point3D.__bases__, (Generic, dict)) 8615 self.assertEqual(Point3D.__orig_bases__, (Point2DGeneric[T], Generic[T, KT])) 8616 self.assertEqual(Point3D.__mro__, (Point3D, Generic, dict, object)) 8617 self.assertEqual(Point3D.__parameters__, (T, KT)) 8618 self.assertEqual(Point3D.__total__, True) 8619 self.assertEqual(Point3D.__optional_keys__, frozenset()) 8620 self.assertEqual(Point3D.__required_keys__, frozenset(['a', 'b', 'c'])) 8621 self.assertEqual(Point3D.__annotations__, { 8622 'a': T, 8623 'b': T, 8624 'c': KT, 8625 }) 8626 self.assertEqual(Point3D[int, str].__origin__, Point3D) 8627 8628 with self.assertRaises(TypeError): 8629 Point3D[int] 8630 8631 with self.assertRaises(TypeError): 8632 class Point3D(Point2DGeneric[T], Generic[KT]): 8633 c: KT 8634 8635 def test_implicit_any_inheritance(self): 8636 class A(TypedDict, Generic[T]): 8637 a: T 8638 8639 class B(A[KT], total=False): 8640 b: KT 8641 8642 class WithImplicitAny(B): 8643 c: int 8644 8645 self.assertEqual(WithImplicitAny.__bases__, (Generic, dict,)) 8646 self.assertEqual(WithImplicitAny.__mro__, (WithImplicitAny, Generic, dict, object)) 8647 # Consistent with GenericTests.test_implicit_any 8648 self.assertEqual(WithImplicitAny.__parameters__, ()) 8649 self.assertEqual(WithImplicitAny.__total__, True) 8650 self.assertEqual(WithImplicitAny.__optional_keys__, frozenset(['b'])) 8651 self.assertEqual(WithImplicitAny.__required_keys__, frozenset(['a', 'c'])) 8652 self.assertEqual(WithImplicitAny.__annotations__, { 8653 'a': T, 8654 'b': KT, 8655 'c': int, 8656 }) 8657 with self.assertRaises(TypeError): 8658 WithImplicitAny[str] 8659 8660 def test_non_generic_subscript(self): 8661 # For backward compatibility, subscription works 8662 # on arbitrary TypedDict types. 8663 class TD(TypedDict): 8664 a: T 8665 A = TD[int] 8666 self.assertEqual(A.__origin__, TD) 8667 self.assertEqual(A.__parameters__, ()) 8668 self.assertEqual(A.__args__, (int,)) 8669 a = A(a = 1) 8670 self.assertIs(type(a), dict) 8671 self.assertEqual(a, {'a': 1}) 8672 8673 def test_orig_bases(self): 8674 T = TypeVar('T') 8675 8676 class Parent(TypedDict): 8677 pass 8678 8679 class Child(Parent): 8680 pass 8681 8682 class OtherChild(Parent): 8683 pass 8684 8685 class MixedChild(Child, OtherChild, Parent): 8686 pass 8687 8688 class GenericParent(TypedDict, Generic[T]): 8689 pass 8690 8691 class GenericChild(GenericParent[int]): 8692 pass 8693 8694 class OtherGenericChild(GenericParent[str]): 8695 pass 8696 8697 class MixedGenericChild(GenericChild, OtherGenericChild, GenericParent[float]): 8698 pass 8699 8700 class MultipleGenericBases(GenericParent[int], GenericParent[float]): 8701 pass 8702 8703 CallTypedDict = TypedDict('CallTypedDict', {}) 8704 8705 self.assertEqual(Parent.__orig_bases__, (TypedDict,)) 8706 self.assertEqual(Child.__orig_bases__, (Parent,)) 8707 self.assertEqual(OtherChild.__orig_bases__, (Parent,)) 8708 self.assertEqual(MixedChild.__orig_bases__, (Child, OtherChild, Parent,)) 8709 self.assertEqual(GenericParent.__orig_bases__, (TypedDict, Generic[T])) 8710 self.assertEqual(GenericChild.__orig_bases__, (GenericParent[int],)) 8711 self.assertEqual(OtherGenericChild.__orig_bases__, (GenericParent[str],)) 8712 self.assertEqual(MixedGenericChild.__orig_bases__, (GenericChild, OtherGenericChild, GenericParent[float])) 8713 self.assertEqual(MultipleGenericBases.__orig_bases__, (GenericParent[int], GenericParent[float])) 8714 self.assertEqual(CallTypedDict.__orig_bases__, (TypedDict,)) 8715 8716 def test_zero_fields_typeddicts(self): 8717 T1 = TypedDict("T1", {}) 8718 class T2(TypedDict): pass 8719 class T3[tvar](TypedDict): pass 8720 S = TypeVar("S") 8721 class T4(TypedDict, Generic[S]): pass 8722 8723 expected_warning = re.escape( 8724 "Failing to pass a value for the 'fields' parameter is deprecated " 8725 "and will be disallowed in Python 3.15. " 8726 "To create a TypedDict class with 0 fields " 8727 "using the functional syntax, " 8728 "pass an empty dictionary, e.g. `T5 = TypedDict('T5', {})`." 8729 ) 8730 with self.assertWarnsRegex(DeprecationWarning, fr"^{expected_warning}$"): 8731 T5 = TypedDict('T5') 8732 8733 expected_warning = re.escape( 8734 "Passing `None` as the 'fields' parameter is deprecated " 8735 "and will be disallowed in Python 3.15. " 8736 "To create a TypedDict class with 0 fields " 8737 "using the functional syntax, " 8738 "pass an empty dictionary, e.g. `T6 = TypedDict('T6', {})`." 8739 ) 8740 with self.assertWarnsRegex(DeprecationWarning, fr"^{expected_warning}$"): 8741 T6 = TypedDict('T6', None) 8742 8743 for klass in T1, T2, T3, T4, T5, T6: 8744 with self.subTest(klass=klass.__name__): 8745 self.assertEqual(klass.__annotations__, {}) 8746 self.assertEqual(klass.__required_keys__, set()) 8747 self.assertEqual(klass.__optional_keys__, set()) 8748 self.assertIsInstance(klass(), dict) 8749 8750 def test_readonly_inheritance(self): 8751 class Base1(TypedDict): 8752 a: ReadOnly[int] 8753 8754 class Child1(Base1): 8755 b: str 8756 8757 self.assertEqual(Child1.__readonly_keys__, frozenset({'a'})) 8758 self.assertEqual(Child1.__mutable_keys__, frozenset({'b'})) 8759 8760 class Base2(TypedDict): 8761 a: ReadOnly[int] 8762 8763 class Child2(Base2): 8764 b: str 8765 8766 self.assertEqual(Child1.__readonly_keys__, frozenset({'a'})) 8767 self.assertEqual(Child1.__mutable_keys__, frozenset({'b'})) 8768 8769 def test_cannot_make_mutable_key_readonly(self): 8770 class Base(TypedDict): 8771 a: int 8772 8773 with self.assertRaises(TypeError): 8774 class Child(Base): 8775 a: ReadOnly[int] 8776 8777 def test_can_make_readonly_key_mutable(self): 8778 class Base(TypedDict): 8779 a: ReadOnly[int] 8780 8781 class Child(Base): 8782 a: int 8783 8784 self.assertEqual(Child.__readonly_keys__, frozenset()) 8785 self.assertEqual(Child.__mutable_keys__, frozenset({'a'})) 8786 8787 def test_combine_qualifiers(self): 8788 class AllTheThings(TypedDict): 8789 a: Annotated[Required[ReadOnly[int]], "why not"] 8790 b: Required[Annotated[ReadOnly[int], "why not"]] 8791 c: ReadOnly[NotRequired[Annotated[int, "why not"]]] 8792 d: NotRequired[Annotated[int, "why not"]] 8793 8794 self.assertEqual(AllTheThings.__required_keys__, frozenset({'a', 'b'})) 8795 self.assertEqual(AllTheThings.__optional_keys__, frozenset({'c', 'd'})) 8796 self.assertEqual(AllTheThings.__readonly_keys__, frozenset({'a', 'b', 'c'})) 8797 self.assertEqual(AllTheThings.__mutable_keys__, frozenset({'d'})) 8798 8799 self.assertEqual( 8800 get_type_hints(AllTheThings, include_extras=False), 8801 {'a': int, 'b': int, 'c': int, 'd': int}, 8802 ) 8803 self.assertEqual( 8804 get_type_hints(AllTheThings, include_extras=True), 8805 { 8806 'a': Annotated[Required[ReadOnly[int]], 'why not'], 8807 'b': Required[Annotated[ReadOnly[int], 'why not']], 8808 'c': ReadOnly[NotRequired[Annotated[int, 'why not']]], 8809 'd': NotRequired[Annotated[int, 'why not']], 8810 }, 8811 ) 8812 8813 8814class RequiredTests(BaseTestCase): 8815 8816 def test_basics(self): 8817 with self.assertRaises(TypeError): 8818 Required[NotRequired] 8819 with self.assertRaises(TypeError): 8820 Required[int, str] 8821 with self.assertRaises(TypeError): 8822 Required[int][str] 8823 8824 def test_repr(self): 8825 self.assertEqual(repr(Required), 'typing.Required') 8826 cv = Required[int] 8827 self.assertEqual(repr(cv), 'typing.Required[int]') 8828 cv = Required[Employee] 8829 self.assertEqual(repr(cv), f'typing.Required[{__name__}.Employee]') 8830 8831 def test_cannot_subclass(self): 8832 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 8833 class C(type(Required)): 8834 pass 8835 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 8836 class D(type(Required[int])): 8837 pass 8838 with self.assertRaisesRegex(TypeError, 8839 r'Cannot subclass typing\.Required'): 8840 class E(Required): 8841 pass 8842 with self.assertRaisesRegex(TypeError, 8843 r'Cannot subclass typing\.Required\[int\]'): 8844 class F(Required[int]): 8845 pass 8846 8847 def test_cannot_init(self): 8848 with self.assertRaises(TypeError): 8849 Required() 8850 with self.assertRaises(TypeError): 8851 type(Required)() 8852 with self.assertRaises(TypeError): 8853 type(Required[Optional[int]])() 8854 8855 def test_no_isinstance(self): 8856 with self.assertRaises(TypeError): 8857 isinstance(1, Required[int]) 8858 with self.assertRaises(TypeError): 8859 issubclass(int, Required) 8860 8861 8862class NotRequiredTests(BaseTestCase): 8863 8864 def test_basics(self): 8865 with self.assertRaises(TypeError): 8866 NotRequired[Required] 8867 with self.assertRaises(TypeError): 8868 NotRequired[int, str] 8869 with self.assertRaises(TypeError): 8870 NotRequired[int][str] 8871 8872 def test_repr(self): 8873 self.assertEqual(repr(NotRequired), 'typing.NotRequired') 8874 cv = NotRequired[int] 8875 self.assertEqual(repr(cv), 'typing.NotRequired[int]') 8876 cv = NotRequired[Employee] 8877 self.assertEqual(repr(cv), f'typing.NotRequired[{__name__}.Employee]') 8878 8879 def test_cannot_subclass(self): 8880 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 8881 class C(type(NotRequired)): 8882 pass 8883 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 8884 class D(type(NotRequired[int])): 8885 pass 8886 with self.assertRaisesRegex(TypeError, 8887 r'Cannot subclass typing\.NotRequired'): 8888 class E(NotRequired): 8889 pass 8890 with self.assertRaisesRegex(TypeError, 8891 r'Cannot subclass typing\.NotRequired\[int\]'): 8892 class F(NotRequired[int]): 8893 pass 8894 8895 def test_cannot_init(self): 8896 with self.assertRaises(TypeError): 8897 NotRequired() 8898 with self.assertRaises(TypeError): 8899 type(NotRequired)() 8900 with self.assertRaises(TypeError): 8901 type(NotRequired[Optional[int]])() 8902 8903 def test_no_isinstance(self): 8904 with self.assertRaises(TypeError): 8905 isinstance(1, NotRequired[int]) 8906 with self.assertRaises(TypeError): 8907 issubclass(int, NotRequired) 8908 8909 8910class IOTests(BaseTestCase): 8911 8912 def test_io(self): 8913 8914 def stuff(a: IO) -> AnyStr: 8915 return a.readline() 8916 8917 a = stuff.__annotations__['a'] 8918 self.assertEqual(a.__parameters__, (AnyStr,)) 8919 8920 def test_textio(self): 8921 8922 def stuff(a: TextIO) -> str: 8923 return a.readline() 8924 8925 a = stuff.__annotations__['a'] 8926 self.assertEqual(a.__parameters__, ()) 8927 8928 def test_binaryio(self): 8929 8930 def stuff(a: BinaryIO) -> bytes: 8931 return a.readline() 8932 8933 a = stuff.__annotations__['a'] 8934 self.assertEqual(a.__parameters__, ()) 8935 8936 8937class RETests(BaseTestCase): 8938 # Much of this is really testing _TypeAlias. 8939 8940 def test_basics(self): 8941 pat = re.compile('[a-z]+', re.I) 8942 self.assertIsSubclass(pat.__class__, Pattern) 8943 self.assertIsSubclass(type(pat), Pattern) 8944 self.assertIsInstance(pat, Pattern) 8945 8946 mat = pat.search('12345abcde.....') 8947 self.assertIsSubclass(mat.__class__, Match) 8948 self.assertIsSubclass(type(mat), Match) 8949 self.assertIsInstance(mat, Match) 8950 8951 # these should just work 8952 Pattern[Union[str, bytes]] 8953 Match[Union[bytes, str]] 8954 8955 def test_alias_equality(self): 8956 self.assertEqual(Pattern[str], Pattern[str]) 8957 self.assertNotEqual(Pattern[str], Pattern[bytes]) 8958 self.assertNotEqual(Pattern[str], Match[str]) 8959 self.assertNotEqual(Pattern[str], str) 8960 8961 def test_errors(self): 8962 m = Match[Union[str, bytes]] 8963 with self.assertRaises(TypeError): 8964 m[str] 8965 with self.assertRaises(TypeError): 8966 # We don't support isinstance(). 8967 isinstance(42, Pattern[str]) 8968 with self.assertRaises(TypeError): 8969 # We don't support issubclass(). 8970 issubclass(Pattern[bytes], Pattern[str]) 8971 8972 def test_repr(self): 8973 self.assertEqual(repr(Pattern), 'typing.Pattern') 8974 self.assertEqual(repr(Pattern[str]), 'typing.Pattern[str]') 8975 self.assertEqual(repr(Pattern[bytes]), 'typing.Pattern[bytes]') 8976 self.assertEqual(repr(Match), 'typing.Match') 8977 self.assertEqual(repr(Match[str]), 'typing.Match[str]') 8978 self.assertEqual(repr(Match[bytes]), 'typing.Match[bytes]') 8979 8980 def test_cannot_subclass(self): 8981 with self.assertRaisesRegex( 8982 TypeError, 8983 r"type 're\.Match' is not an acceptable base type", 8984 ): 8985 class A(typing.Match): 8986 pass 8987 with self.assertRaisesRegex( 8988 TypeError, 8989 r"type 're\.Pattern' is not an acceptable base type", 8990 ): 8991 class B(typing.Pattern): 8992 pass 8993 8994 8995class AnnotatedTests(BaseTestCase): 8996 8997 def test_new(self): 8998 with self.assertRaisesRegex( 8999 TypeError, 'Cannot instantiate typing.Annotated', 9000 ): 9001 Annotated() 9002 9003 def test_repr(self): 9004 self.assertEqual( 9005 repr(Annotated[int, 4, 5]), 9006 "typing.Annotated[int, 4, 5]" 9007 ) 9008 self.assertEqual( 9009 repr(Annotated[List[int], 4, 5]), 9010 "typing.Annotated[typing.List[int], 4, 5]" 9011 ) 9012 9013 def test_dir(self): 9014 dir_items = set(dir(Annotated[int, 4])) 9015 for required_item in [ 9016 '__args__', '__parameters__', '__origin__', 9017 '__metadata__', 9018 ]: 9019 with self.subTest(required_item=required_item): 9020 self.assertIn(required_item, dir_items) 9021 9022 def test_flatten(self): 9023 A = Annotated[Annotated[int, 4], 5] 9024 self.assertEqual(A, Annotated[int, 4, 5]) 9025 self.assertEqual(A.__metadata__, (4, 5)) 9026 self.assertEqual(A.__origin__, int) 9027 9028 def test_deduplicate_from_union(self): 9029 # Regular: 9030 self.assertEqual(get_args(Annotated[int, 1] | int), 9031 (Annotated[int, 1], int)) 9032 self.assertEqual(get_args(Union[Annotated[int, 1], int]), 9033 (Annotated[int, 1], int)) 9034 self.assertEqual(get_args(Annotated[int, 1] | Annotated[int, 2] | int), 9035 (Annotated[int, 1], Annotated[int, 2], int)) 9036 self.assertEqual(get_args(Union[Annotated[int, 1], Annotated[int, 2], int]), 9037 (Annotated[int, 1], Annotated[int, 2], int)) 9038 self.assertEqual(get_args(Annotated[int, 1] | Annotated[str, 1] | int), 9039 (Annotated[int, 1], Annotated[str, 1], int)) 9040 self.assertEqual(get_args(Union[Annotated[int, 1], Annotated[str, 1], int]), 9041 (Annotated[int, 1], Annotated[str, 1], int)) 9042 9043 # Duplicates: 9044 self.assertEqual(Annotated[int, 1] | Annotated[int, 1] | int, 9045 Annotated[int, 1] | int) 9046 self.assertEqual(Union[Annotated[int, 1], Annotated[int, 1], int], 9047 Union[Annotated[int, 1], int]) 9048 9049 # Unhashable metadata: 9050 self.assertEqual(get_args(str | Annotated[int, {}] | Annotated[int, set()] | int), 9051 (str, Annotated[int, {}], Annotated[int, set()], int)) 9052 self.assertEqual(get_args(Union[str, Annotated[int, {}], Annotated[int, set()], int]), 9053 (str, Annotated[int, {}], Annotated[int, set()], int)) 9054 self.assertEqual(get_args(str | Annotated[int, {}] | Annotated[str, {}] | int), 9055 (str, Annotated[int, {}], Annotated[str, {}], int)) 9056 self.assertEqual(get_args(Union[str, Annotated[int, {}], Annotated[str, {}], int]), 9057 (str, Annotated[int, {}], Annotated[str, {}], int)) 9058 9059 self.assertEqual(get_args(Annotated[int, 1] | str | Annotated[str, {}] | int), 9060 (Annotated[int, 1], str, Annotated[str, {}], int)) 9061 self.assertEqual(get_args(Union[Annotated[int, 1], str, Annotated[str, {}], int]), 9062 (Annotated[int, 1], str, Annotated[str, {}], int)) 9063 9064 import dataclasses 9065 @dataclasses.dataclass 9066 class ValueRange: 9067 lo: int 9068 hi: int 9069 v = ValueRange(1, 2) 9070 self.assertEqual(get_args(Annotated[int, v] | None), 9071 (Annotated[int, v], types.NoneType)) 9072 self.assertEqual(get_args(Union[Annotated[int, v], None]), 9073 (Annotated[int, v], types.NoneType)) 9074 self.assertEqual(get_args(Optional[Annotated[int, v]]), 9075 (Annotated[int, v], types.NoneType)) 9076 9077 # Unhashable metadata duplicated: 9078 self.assertEqual(Annotated[int, {}] | Annotated[int, {}] | int, 9079 Annotated[int, {}] | int) 9080 self.assertEqual(Annotated[int, {}] | Annotated[int, {}] | int, 9081 int | Annotated[int, {}]) 9082 self.assertEqual(Union[Annotated[int, {}], Annotated[int, {}], int], 9083 Union[Annotated[int, {}], int]) 9084 self.assertEqual(Union[Annotated[int, {}], Annotated[int, {}], int], 9085 Union[int, Annotated[int, {}]]) 9086 9087 def test_order_in_union(self): 9088 expr1 = Annotated[int, 1] | str | Annotated[str, {}] | int 9089 for args in itertools.permutations(get_args(expr1)): 9090 with self.subTest(args=args): 9091 self.assertEqual(expr1, reduce(operator.or_, args)) 9092 9093 expr2 = Union[Annotated[int, 1], str, Annotated[str, {}], int] 9094 for args in itertools.permutations(get_args(expr2)): 9095 with self.subTest(args=args): 9096 self.assertEqual(expr2, Union[args]) 9097 9098 def test_specialize(self): 9099 L = Annotated[List[T], "my decoration"] 9100 LI = Annotated[List[int], "my decoration"] 9101 self.assertEqual(L[int], Annotated[List[int], "my decoration"]) 9102 self.assertEqual(L[int].__metadata__, ("my decoration",)) 9103 self.assertEqual(L[int].__origin__, List[int]) 9104 with self.assertRaises(TypeError): 9105 LI[int] 9106 with self.assertRaises(TypeError): 9107 L[int, float] 9108 9109 def test_hash_eq(self): 9110 self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1) 9111 self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4]) 9112 self.assertNotEqual(Annotated[int, 4, 5], Annotated[str, 4, 5]) 9113 self.assertNotEqual(Annotated[int, 4], Annotated[int, 4, 4]) 9114 self.assertEqual( 9115 {Annotated[int, 4, 5], Annotated[int, 4, 5], Annotated[T, 4, 5]}, 9116 {Annotated[int, 4, 5], Annotated[T, 4, 5]} 9117 ) 9118 # Unhashable `metadata` raises `TypeError`: 9119 a1 = Annotated[int, []] 9120 with self.assertRaises(TypeError): 9121 hash(a1) 9122 9123 class A: 9124 __hash__ = None 9125 a2 = Annotated[int, A()] 9126 with self.assertRaises(TypeError): 9127 hash(a2) 9128 9129 def test_instantiate(self): 9130 class C: 9131 classvar = 4 9132 9133 def __init__(self, x): 9134 self.x = x 9135 9136 def __eq__(self, other): 9137 if not isinstance(other, C): 9138 return NotImplemented 9139 return other.x == self.x 9140 9141 A = Annotated[C, "a decoration"] 9142 a = A(5) 9143 c = C(5) 9144 self.assertEqual(a, c) 9145 self.assertEqual(a.x, c.x) 9146 self.assertEqual(a.classvar, c.classvar) 9147 9148 def test_instantiate_generic(self): 9149 MyCount = Annotated[typing.Counter[T], "my decoration"] 9150 self.assertEqual(MyCount([4, 4, 5]), {4: 2, 5: 1}) 9151 self.assertEqual(MyCount[int]([4, 4, 5]), {4: 2, 5: 1}) 9152 9153 def test_instantiate_immutable(self): 9154 class C: 9155 def __setattr__(self, key, value): 9156 raise Exception("should be ignored") 9157 9158 A = Annotated[C, "a decoration"] 9159 # gh-115165: This used to cause RuntimeError to be raised 9160 # when we tried to set `__orig_class__` on the `C` instance 9161 # returned by the `A()` call 9162 self.assertIsInstance(A(), C) 9163 9164 def test_cannot_instantiate_forward(self): 9165 A = Annotated["int", (5, 6)] 9166 with self.assertRaises(TypeError): 9167 A(5) 9168 9169 def test_cannot_instantiate_type_var(self): 9170 A = Annotated[T, (5, 6)] 9171 with self.assertRaises(TypeError): 9172 A(5) 9173 9174 def test_cannot_getattr_typevar(self): 9175 with self.assertRaises(AttributeError): 9176 Annotated[T, (5, 7)].x 9177 9178 def test_attr_passthrough(self): 9179 class C: 9180 classvar = 4 9181 9182 A = Annotated[C, "a decoration"] 9183 self.assertEqual(A.classvar, 4) 9184 A.x = 5 9185 self.assertEqual(C.x, 5) 9186 9187 def test_special_form_containment(self): 9188 class C: 9189 classvar: Annotated[ClassVar[int], "a decoration"] = 4 9190 const: Annotated[Final[int], "Const"] = 4 9191 9192 self.assertEqual(get_type_hints(C, globals())['classvar'], ClassVar[int]) 9193 self.assertEqual(get_type_hints(C, globals())['const'], Final[int]) 9194 9195 def test_special_forms_nesting(self): 9196 # These are uncommon types and are to ensure runtime 9197 # is lax on validation. See gh-89547 for more context. 9198 class CF: 9199 x: ClassVar[Final[int]] 9200 9201 class FC: 9202 x: Final[ClassVar[int]] 9203 9204 class ACF: 9205 x: Annotated[ClassVar[Final[int]], "a decoration"] 9206 9207 class CAF: 9208 x: ClassVar[Annotated[Final[int], "a decoration"]] 9209 9210 class AFC: 9211 x: Annotated[Final[ClassVar[int]], "a decoration"] 9212 9213 class FAC: 9214 x: Final[Annotated[ClassVar[int], "a decoration"]] 9215 9216 self.assertEqual(get_type_hints(CF, globals())['x'], ClassVar[Final[int]]) 9217 self.assertEqual(get_type_hints(FC, globals())['x'], Final[ClassVar[int]]) 9218 self.assertEqual(get_type_hints(ACF, globals())['x'], ClassVar[Final[int]]) 9219 self.assertEqual(get_type_hints(CAF, globals())['x'], ClassVar[Final[int]]) 9220 self.assertEqual(get_type_hints(AFC, globals())['x'], Final[ClassVar[int]]) 9221 self.assertEqual(get_type_hints(FAC, globals())['x'], Final[ClassVar[int]]) 9222 9223 def test_cannot_subclass(self): 9224 with self.assertRaisesRegex(TypeError, "Cannot subclass .*Annotated"): 9225 class C(Annotated): 9226 pass 9227 9228 def test_cannot_check_instance(self): 9229 with self.assertRaises(TypeError): 9230 isinstance(5, Annotated[int, "positive"]) 9231 9232 def test_cannot_check_subclass(self): 9233 with self.assertRaises(TypeError): 9234 issubclass(int, Annotated[int, "positive"]) 9235 9236 def test_too_few_type_args(self): 9237 with self.assertRaisesRegex(TypeError, 'at least two arguments'): 9238 Annotated[int] 9239 9240 def test_pickle(self): 9241 samples = [typing.Any, typing.Union[int, str], 9242 typing.Optional[str], Tuple[int, ...], 9243 typing.Callable[[str], bytes]] 9244 9245 for t in samples: 9246 x = Annotated[t, "a"] 9247 9248 for prot in range(pickle.HIGHEST_PROTOCOL + 1): 9249 with self.subTest(protocol=prot, type=t): 9250 pickled = pickle.dumps(x, prot) 9251 restored = pickle.loads(pickled) 9252 self.assertEqual(x, restored) 9253 9254 global _Annotated_test_G 9255 9256 class _Annotated_test_G(Generic[T]): 9257 x = 1 9258 9259 G = Annotated[_Annotated_test_G[int], "A decoration"] 9260 G.foo = 42 9261 G.bar = 'abc' 9262 9263 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 9264 z = pickle.dumps(G, proto) 9265 x = pickle.loads(z) 9266 self.assertEqual(x.foo, 42) 9267 self.assertEqual(x.bar, 'abc') 9268 self.assertEqual(x.x, 1) 9269 9270 def test_subst(self): 9271 dec = "a decoration" 9272 dec2 = "another decoration" 9273 9274 S = Annotated[T, dec2] 9275 self.assertEqual(S[int], Annotated[int, dec2]) 9276 9277 self.assertEqual(S[Annotated[int, dec]], Annotated[int, dec, dec2]) 9278 L = Annotated[List[T], dec] 9279 9280 self.assertEqual(L[int], Annotated[List[int], dec]) 9281 with self.assertRaises(TypeError): 9282 L[int, int] 9283 9284 self.assertEqual(S[L[int]], Annotated[List[int], dec, dec2]) 9285 9286 D = Annotated[typing.Dict[KT, VT], dec] 9287 self.assertEqual(D[str, int], Annotated[typing.Dict[str, int], dec]) 9288 with self.assertRaises(TypeError): 9289 D[int] 9290 9291 It = Annotated[int, dec] 9292 with self.assertRaises(TypeError): 9293 It[None] 9294 9295 LI = L[int] 9296 with self.assertRaises(TypeError): 9297 LI[None] 9298 9299 def test_typevar_subst(self): 9300 dec = "a decoration" 9301 Ts = TypeVarTuple('Ts') 9302 T = TypeVar('T') 9303 T1 = TypeVar('T1') 9304 T2 = TypeVar('T2') 9305 9306 A = Annotated[tuple[*Ts], dec] 9307 self.assertEqual(A[int], Annotated[tuple[int], dec]) 9308 self.assertEqual(A[str, int], Annotated[tuple[str, int], dec]) 9309 with self.assertRaises(TypeError): 9310 Annotated[*Ts, dec] 9311 9312 B = Annotated[Tuple[Unpack[Ts]], dec] 9313 self.assertEqual(B[int], Annotated[Tuple[int], dec]) 9314 self.assertEqual(B[str, int], Annotated[Tuple[str, int], dec]) 9315 with self.assertRaises(TypeError): 9316 Annotated[Unpack[Ts], dec] 9317 9318 C = Annotated[tuple[T, *Ts], dec] 9319 self.assertEqual(C[int], Annotated[tuple[int], dec]) 9320 self.assertEqual(C[int, str], Annotated[tuple[int, str], dec]) 9321 self.assertEqual( 9322 C[int, str, float], 9323 Annotated[tuple[int, str, float], dec] 9324 ) 9325 with self.assertRaises(TypeError): 9326 C[()] 9327 9328 D = Annotated[Tuple[T, Unpack[Ts]], dec] 9329 self.assertEqual(D[int], Annotated[Tuple[int], dec]) 9330 self.assertEqual(D[int, str], Annotated[Tuple[int, str], dec]) 9331 self.assertEqual( 9332 D[int, str, float], 9333 Annotated[Tuple[int, str, float], dec] 9334 ) 9335 with self.assertRaises(TypeError): 9336 D[()] 9337 9338 E = Annotated[tuple[*Ts, T], dec] 9339 self.assertEqual(E[int], Annotated[tuple[int], dec]) 9340 self.assertEqual(E[int, str], Annotated[tuple[int, str], dec]) 9341 self.assertEqual( 9342 E[int, str, float], 9343 Annotated[tuple[int, str, float], dec] 9344 ) 9345 with self.assertRaises(TypeError): 9346 E[()] 9347 9348 F = Annotated[Tuple[Unpack[Ts], T], dec] 9349 self.assertEqual(F[int], Annotated[Tuple[int], dec]) 9350 self.assertEqual(F[int, str], Annotated[Tuple[int, str], dec]) 9351 self.assertEqual( 9352 F[int, str, float], 9353 Annotated[Tuple[int, str, float], dec] 9354 ) 9355 with self.assertRaises(TypeError): 9356 F[()] 9357 9358 G = Annotated[tuple[T1, *Ts, T2], dec] 9359 self.assertEqual(G[int, str], Annotated[tuple[int, str], dec]) 9360 self.assertEqual( 9361 G[int, str, float], 9362 Annotated[tuple[int, str, float], dec] 9363 ) 9364 self.assertEqual( 9365 G[int, str, bool, float], 9366 Annotated[tuple[int, str, bool, float], dec] 9367 ) 9368 with self.assertRaises(TypeError): 9369 G[int] 9370 9371 H = Annotated[Tuple[T1, Unpack[Ts], T2], dec] 9372 self.assertEqual(H[int, str], Annotated[Tuple[int, str], dec]) 9373 self.assertEqual( 9374 H[int, str, float], 9375 Annotated[Tuple[int, str, float], dec] 9376 ) 9377 self.assertEqual( 9378 H[int, str, bool, float], 9379 Annotated[Tuple[int, str, bool, float], dec] 9380 ) 9381 with self.assertRaises(TypeError): 9382 H[int] 9383 9384 # Now let's try creating an alias from an alias. 9385 9386 Ts2 = TypeVarTuple('Ts2') 9387 T3 = TypeVar('T3') 9388 T4 = TypeVar('T4') 9389 9390 # G is Annotated[tuple[T1, *Ts, T2], dec]. 9391 I = G[T3, *Ts2, T4] 9392 J = G[T3, Unpack[Ts2], T4] 9393 9394 for x, y in [ 9395 (I, Annotated[tuple[T3, *Ts2, T4], dec]), 9396 (J, Annotated[tuple[T3, Unpack[Ts2], T4], dec]), 9397 (I[int, str], Annotated[tuple[int, str], dec]), 9398 (J[int, str], Annotated[tuple[int, str], dec]), 9399 (I[int, str, float], Annotated[tuple[int, str, float], dec]), 9400 (J[int, str, float], Annotated[tuple[int, str, float], dec]), 9401 (I[int, str, bool, float], 9402 Annotated[tuple[int, str, bool, float], dec]), 9403 (J[int, str, bool, float], 9404 Annotated[tuple[int, str, bool, float], dec]), 9405 ]: 9406 self.assertEqual(x, y) 9407 9408 with self.assertRaises(TypeError): 9409 I[int] 9410 with self.assertRaises(TypeError): 9411 J[int] 9412 9413 def test_annotated_in_other_types(self): 9414 X = List[Annotated[T, 5]] 9415 self.assertEqual(X[int], List[Annotated[int, 5]]) 9416 9417 def test_annotated_mro(self): 9418 class X(Annotated[int, (1, 10)]): ... 9419 self.assertEqual(X.__mro__, (X, int, object), 9420 "Annotated should be transparent.") 9421 9422 def test_annotated_cached_with_types(self): 9423 class A(str): ... 9424 class B(str): ... 9425 9426 field_a1 = Annotated[str, A("X")] 9427 field_a2 = Annotated[str, B("X")] 9428 a1_metadata = field_a1.__metadata__[0] 9429 a2_metadata = field_a2.__metadata__[0] 9430 9431 self.assertIs(type(a1_metadata), A) 9432 self.assertEqual(a1_metadata, A("X")) 9433 self.assertIs(type(a2_metadata), B) 9434 self.assertEqual(a2_metadata, B("X")) 9435 self.assertIsNot(type(a1_metadata), type(a2_metadata)) 9436 9437 field_b1 = Annotated[str, A("Y")] 9438 field_b2 = Annotated[str, B("Y")] 9439 b1_metadata = field_b1.__metadata__[0] 9440 b2_metadata = field_b2.__metadata__[0] 9441 9442 self.assertIs(type(b1_metadata), A) 9443 self.assertEqual(b1_metadata, A("Y")) 9444 self.assertIs(type(b2_metadata), B) 9445 self.assertEqual(b2_metadata, B("Y")) 9446 self.assertIsNot(type(b1_metadata), type(b2_metadata)) 9447 9448 field_c1 = Annotated[int, 1] 9449 field_c2 = Annotated[int, 1.0] 9450 field_c3 = Annotated[int, True] 9451 9452 self.assertIs(type(field_c1.__metadata__[0]), int) 9453 self.assertIs(type(field_c2.__metadata__[0]), float) 9454 self.assertIs(type(field_c3.__metadata__[0]), bool) 9455 9456 9457class TypeAliasTests(BaseTestCase): 9458 def test_canonical_usage_with_variable_annotation(self): 9459 Alias: TypeAlias = Employee 9460 9461 def test_canonical_usage_with_type_comment(self): 9462 Alias = Employee # type: TypeAlias 9463 9464 def test_cannot_instantiate(self): 9465 with self.assertRaises(TypeError): 9466 TypeAlias() 9467 9468 def test_no_isinstance(self): 9469 with self.assertRaises(TypeError): 9470 isinstance(42, TypeAlias) 9471 9472 def test_stringized_usage(self): 9473 class A: 9474 a: "TypeAlias" 9475 self.assertEqual(get_type_hints(A), {'a': TypeAlias}) 9476 9477 def test_no_issubclass(self): 9478 with self.assertRaises(TypeError): 9479 issubclass(Employee, TypeAlias) 9480 9481 with self.assertRaises(TypeError): 9482 issubclass(TypeAlias, Employee) 9483 9484 def test_cannot_subclass(self): 9485 with self.assertRaisesRegex(TypeError, 9486 r'Cannot subclass typing\.TypeAlias'): 9487 class C(TypeAlias): 9488 pass 9489 9490 with self.assertRaises(TypeError): 9491 class D(type(TypeAlias)): 9492 pass 9493 9494 def test_repr(self): 9495 self.assertEqual(repr(TypeAlias), 'typing.TypeAlias') 9496 9497 def test_cannot_subscript(self): 9498 with self.assertRaises(TypeError): 9499 TypeAlias[int] 9500 9501 9502class ParamSpecTests(BaseTestCase): 9503 9504 def test_basic_plain(self): 9505 P = ParamSpec('P') 9506 self.assertEqual(P, P) 9507 self.assertIsInstance(P, ParamSpec) 9508 self.assertEqual(P.__name__, 'P') 9509 self.assertEqual(P.__module__, __name__) 9510 9511 def test_basic_with_exec(self): 9512 ns = {} 9513 exec('from typing import ParamSpec; P = ParamSpec("P")', ns, ns) 9514 P = ns['P'] 9515 self.assertIsInstance(P, ParamSpec) 9516 self.assertEqual(P.__name__, 'P') 9517 self.assertIs(P.__module__, None) 9518 9519 def test_valid_uses(self): 9520 P = ParamSpec('P') 9521 T = TypeVar('T') 9522 C1 = Callable[P, int] 9523 self.assertEqual(C1.__args__, (P, int)) 9524 self.assertEqual(C1.__parameters__, (P,)) 9525 C2 = Callable[P, T] 9526 self.assertEqual(C2.__args__, (P, T)) 9527 self.assertEqual(C2.__parameters__, (P, T)) 9528 # Test collections.abc.Callable too. 9529 C3 = collections.abc.Callable[P, int] 9530 self.assertEqual(C3.__args__, (P, int)) 9531 self.assertEqual(C3.__parameters__, (P,)) 9532 C4 = collections.abc.Callable[P, T] 9533 self.assertEqual(C4.__args__, (P, T)) 9534 self.assertEqual(C4.__parameters__, (P, T)) 9535 9536 def test_args_kwargs(self): 9537 P = ParamSpec('P') 9538 P_2 = ParamSpec('P_2') 9539 self.assertIn('args', dir(P)) 9540 self.assertIn('kwargs', dir(P)) 9541 self.assertIsInstance(P.args, ParamSpecArgs) 9542 self.assertIsInstance(P.kwargs, ParamSpecKwargs) 9543 self.assertIs(P.args.__origin__, P) 9544 self.assertIs(P.kwargs.__origin__, P) 9545 self.assertEqual(P.args, P.args) 9546 self.assertEqual(P.kwargs, P.kwargs) 9547 self.assertNotEqual(P.args, P_2.args) 9548 self.assertNotEqual(P.kwargs, P_2.kwargs) 9549 self.assertNotEqual(P.args, P.kwargs) 9550 self.assertNotEqual(P.kwargs, P.args) 9551 self.assertNotEqual(P.args, P_2.kwargs) 9552 self.assertEqual(repr(P.args), "P.args") 9553 self.assertEqual(repr(P.kwargs), "P.kwargs") 9554 9555 def test_stringized(self): 9556 P = ParamSpec('P') 9557 class C(Generic[P]): 9558 func: Callable["P", int] 9559 def foo(self, *args: "P.args", **kwargs: "P.kwargs"): 9560 pass 9561 9562 self.assertEqual(gth(C, globals(), locals()), {"func": Callable[P, int]}) 9563 self.assertEqual( 9564 gth(C.foo, globals(), locals()), {"args": P.args, "kwargs": P.kwargs} 9565 ) 9566 9567 def test_user_generics(self): 9568 T = TypeVar("T") 9569 P = ParamSpec("P") 9570 P_2 = ParamSpec("P_2") 9571 9572 class X(Generic[T, P]): 9573 f: Callable[P, int] 9574 x: T 9575 G1 = X[int, P_2] 9576 self.assertEqual(G1.__args__, (int, P_2)) 9577 self.assertEqual(G1.__parameters__, (P_2,)) 9578 with self.assertRaisesRegex(TypeError, "few arguments for"): 9579 X[int] 9580 with self.assertRaisesRegex(TypeError, "many arguments for"): 9581 X[int, P_2, str] 9582 9583 G2 = X[int, Concatenate[int, P_2]] 9584 self.assertEqual(G2.__args__, (int, Concatenate[int, P_2])) 9585 self.assertEqual(G2.__parameters__, (P_2,)) 9586 9587 G3 = X[int, [int, bool]] 9588 self.assertEqual(G3.__args__, (int, (int, bool))) 9589 self.assertEqual(G3.__parameters__, ()) 9590 9591 G4 = X[int, ...] 9592 self.assertEqual(G4.__args__, (int, Ellipsis)) 9593 self.assertEqual(G4.__parameters__, ()) 9594 9595 class Z(Generic[P]): 9596 f: Callable[P, int] 9597 9598 G5 = Z[[int, str, bool]] 9599 self.assertEqual(G5.__args__, ((int, str, bool),)) 9600 self.assertEqual(G5.__parameters__, ()) 9601 9602 G6 = Z[int, str, bool] 9603 self.assertEqual(G6.__args__, ((int, str, bool),)) 9604 self.assertEqual(G6.__parameters__, ()) 9605 9606 # G5 and G6 should be equivalent according to the PEP 9607 self.assertEqual(G5.__args__, G6.__args__) 9608 self.assertEqual(G5.__origin__, G6.__origin__) 9609 self.assertEqual(G5.__parameters__, G6.__parameters__) 9610 self.assertEqual(G5, G6) 9611 9612 G7 = Z[int] 9613 self.assertEqual(G7.__args__, ((int,),)) 9614 self.assertEqual(G7.__parameters__, ()) 9615 9616 with self.assertRaisesRegex(TypeError, "many arguments for"): 9617 Z[[int, str], bool] 9618 with self.assertRaisesRegex(TypeError, "many arguments for"): 9619 Z[P_2, bool] 9620 9621 def test_multiple_paramspecs_in_user_generics(self): 9622 P = ParamSpec("P") 9623 P2 = ParamSpec("P2") 9624 9625 class X(Generic[P, P2]): 9626 f: Callable[P, int] 9627 g: Callable[P2, str] 9628 9629 G1 = X[[int, str], [bytes]] 9630 G2 = X[[int], [str, bytes]] 9631 self.assertNotEqual(G1, G2) 9632 self.assertEqual(G1.__args__, ((int, str), (bytes,))) 9633 self.assertEqual(G2.__args__, ((int,), (str, bytes))) 9634 9635 def test_typevartuple_and_paramspecs_in_user_generics(self): 9636 Ts = TypeVarTuple("Ts") 9637 P = ParamSpec("P") 9638 9639 class X(Generic[*Ts, P]): 9640 f: Callable[P, int] 9641 g: Tuple[*Ts] 9642 9643 G1 = X[int, [bytes]] 9644 self.assertEqual(G1.__args__, (int, (bytes,))) 9645 G2 = X[int, str, [bytes]] 9646 self.assertEqual(G2.__args__, (int, str, (bytes,))) 9647 G3 = X[[bytes]] 9648 self.assertEqual(G3.__args__, ((bytes,),)) 9649 G4 = X[[]] 9650 self.assertEqual(G4.__args__, ((),)) 9651 with self.assertRaises(TypeError): 9652 X[()] 9653 9654 class Y(Generic[P, *Ts]): 9655 f: Callable[P, int] 9656 g: Tuple[*Ts] 9657 9658 G1 = Y[[bytes], int] 9659 self.assertEqual(G1.__args__, ((bytes,), int)) 9660 G2 = Y[[bytes], int, str] 9661 self.assertEqual(G2.__args__, ((bytes,), int, str)) 9662 G3 = Y[[bytes]] 9663 self.assertEqual(G3.__args__, ((bytes,),)) 9664 G4 = Y[[]] 9665 self.assertEqual(G4.__args__, ((),)) 9666 with self.assertRaises(TypeError): 9667 Y[()] 9668 9669 def test_typevartuple_and_paramspecs_in_generic_aliases(self): 9670 P = ParamSpec('P') 9671 T = TypeVar('T') 9672 Ts = TypeVarTuple('Ts') 9673 9674 for C in Callable, collections.abc.Callable: 9675 with self.subTest(generic=C): 9676 A = C[P, Tuple[*Ts]] 9677 B = A[[int, str], bytes, float] 9678 self.assertEqual(B.__args__, (int, str, Tuple[bytes, float])) 9679 9680 class X(Generic[T, P]): 9681 pass 9682 9683 A = X[Tuple[*Ts], P] 9684 B = A[bytes, float, [int, str]] 9685 self.assertEqual(B.__args__, (Tuple[bytes, float], (int, str,))) 9686 9687 class Y(Generic[P, T]): 9688 pass 9689 9690 A = Y[P, Tuple[*Ts]] 9691 B = A[[int, str], bytes, float] 9692 self.assertEqual(B.__args__, ((int, str,), Tuple[bytes, float])) 9693 9694 def test_var_substitution(self): 9695 P = ParamSpec("P") 9696 subst = P.__typing_subst__ 9697 self.assertEqual(subst((int, str)), (int, str)) 9698 self.assertEqual(subst([int, str]), (int, str)) 9699 self.assertEqual(subst([None]), (type(None),)) 9700 self.assertIs(subst(...), ...) 9701 self.assertIs(subst(P), P) 9702 self.assertEqual(subst(Concatenate[int, P]), Concatenate[int, P]) 9703 9704 def test_bad_var_substitution(self): 9705 T = TypeVar('T') 9706 P = ParamSpec('P') 9707 bad_args = (42, int, None, T, int|str, Union[int, str]) 9708 for arg in bad_args: 9709 with self.subTest(arg=arg): 9710 with self.assertRaises(TypeError): 9711 P.__typing_subst__(arg) 9712 with self.assertRaises(TypeError): 9713 typing.Callable[P, T][arg, str] 9714 with self.assertRaises(TypeError): 9715 collections.abc.Callable[P, T][arg, str] 9716 9717 def test_type_var_subst_for_other_type_vars(self): 9718 T = TypeVar('T') 9719 T2 = TypeVar('T2') 9720 P = ParamSpec('P') 9721 P2 = ParamSpec('P2') 9722 Ts = TypeVarTuple('Ts') 9723 9724 class Base(Generic[P]): 9725 pass 9726 9727 A1 = Base[T] 9728 self.assertEqual(A1.__parameters__, (T,)) 9729 self.assertEqual(A1.__args__, ((T,),)) 9730 self.assertEqual(A1[int], Base[int]) 9731 9732 A2 = Base[[T]] 9733 self.assertEqual(A2.__parameters__, (T,)) 9734 self.assertEqual(A2.__args__, ((T,),)) 9735 self.assertEqual(A2[int], Base[int]) 9736 9737 A3 = Base[[int, T]] 9738 self.assertEqual(A3.__parameters__, (T,)) 9739 self.assertEqual(A3.__args__, ((int, T),)) 9740 self.assertEqual(A3[str], Base[[int, str]]) 9741 9742 A4 = Base[[T, int, T2]] 9743 self.assertEqual(A4.__parameters__, (T, T2)) 9744 self.assertEqual(A4.__args__, ((T, int, T2),)) 9745 self.assertEqual(A4[str, bool], Base[[str, int, bool]]) 9746 9747 A5 = Base[[*Ts, int]] 9748 self.assertEqual(A5.__parameters__, (Ts,)) 9749 self.assertEqual(A5.__args__, ((*Ts, int),)) 9750 self.assertEqual(A5[str, bool], Base[[str, bool, int]]) 9751 9752 A5_2 = Base[[int, *Ts]] 9753 self.assertEqual(A5_2.__parameters__, (Ts,)) 9754 self.assertEqual(A5_2.__args__, ((int, *Ts),)) 9755 self.assertEqual(A5_2[str, bool], Base[[int, str, bool]]) 9756 9757 A6 = Base[[T, *Ts]] 9758 self.assertEqual(A6.__parameters__, (T, Ts)) 9759 self.assertEqual(A6.__args__, ((T, *Ts),)) 9760 self.assertEqual(A6[int, str, bool], Base[[int, str, bool]]) 9761 9762 A7 = Base[[T, T]] 9763 self.assertEqual(A7.__parameters__, (T,)) 9764 self.assertEqual(A7.__args__, ((T, T),)) 9765 self.assertEqual(A7[int], Base[[int, int]]) 9766 9767 A8 = Base[[T, list[T]]] 9768 self.assertEqual(A8.__parameters__, (T,)) 9769 self.assertEqual(A8.__args__, ((T, list[T]),)) 9770 self.assertEqual(A8[int], Base[[int, list[int]]]) 9771 9772 A9 = Base[[Tuple[*Ts], *Ts]] 9773 self.assertEqual(A9.__parameters__, (Ts,)) 9774 self.assertEqual(A9.__args__, ((Tuple[*Ts], *Ts),)) 9775 self.assertEqual(A9[int, str], Base[Tuple[int, str], int, str]) 9776 9777 A10 = Base[P2] 9778 self.assertEqual(A10.__parameters__, (P2,)) 9779 self.assertEqual(A10.__args__, (P2,)) 9780 self.assertEqual(A10[[int, str]], Base[[int, str]]) 9781 9782 class DoubleP(Generic[P, P2]): 9783 pass 9784 9785 B1 = DoubleP[P, P2] 9786 self.assertEqual(B1.__parameters__, (P, P2)) 9787 self.assertEqual(B1.__args__, (P, P2)) 9788 self.assertEqual(B1[[int, str], [bool]], DoubleP[[int, str], [bool]]) 9789 self.assertEqual(B1[[], []], DoubleP[[], []]) 9790 9791 B2 = DoubleP[[int, str], P2] 9792 self.assertEqual(B2.__parameters__, (P2,)) 9793 self.assertEqual(B2.__args__, ((int, str), P2)) 9794 self.assertEqual(B2[[bool, bool]], DoubleP[[int, str], [bool, bool]]) 9795 self.assertEqual(B2[[]], DoubleP[[int, str], []]) 9796 9797 B3 = DoubleP[P, [bool, bool]] 9798 self.assertEqual(B3.__parameters__, (P,)) 9799 self.assertEqual(B3.__args__, (P, (bool, bool))) 9800 self.assertEqual(B3[[int, str]], DoubleP[[int, str], [bool, bool]]) 9801 self.assertEqual(B3[[]], DoubleP[[], [bool, bool]]) 9802 9803 B4 = DoubleP[[T, int], [bool, T2]] 9804 self.assertEqual(B4.__parameters__, (T, T2)) 9805 self.assertEqual(B4.__args__, ((T, int), (bool, T2))) 9806 self.assertEqual(B4[str, float], DoubleP[[str, int], [bool, float]]) 9807 9808 B5 = DoubleP[[*Ts, int], [bool, T2]] 9809 self.assertEqual(B5.__parameters__, (Ts, T2)) 9810 self.assertEqual(B5.__args__, ((*Ts, int), (bool, T2))) 9811 self.assertEqual(B5[str, bytes, float], 9812 DoubleP[[str, bytes, int], [bool, float]]) 9813 9814 B6 = DoubleP[[T, int], [bool, *Ts]] 9815 self.assertEqual(B6.__parameters__, (T, Ts)) 9816 self.assertEqual(B6.__args__, ((T, int), (bool, *Ts))) 9817 self.assertEqual(B6[str, bytes, float], 9818 DoubleP[[str, int], [bool, bytes, float]]) 9819 9820 class PandT(Generic[P, T]): 9821 pass 9822 9823 C1 = PandT[P, T] 9824 self.assertEqual(C1.__parameters__, (P, T)) 9825 self.assertEqual(C1.__args__, (P, T)) 9826 self.assertEqual(C1[[int, str], bool], PandT[[int, str], bool]) 9827 9828 C2 = PandT[[int, T], T] 9829 self.assertEqual(C2.__parameters__, (T,)) 9830 self.assertEqual(C2.__args__, ((int, T), T)) 9831 self.assertEqual(C2[str], PandT[[int, str], str]) 9832 9833 C3 = PandT[[int, *Ts], T] 9834 self.assertEqual(C3.__parameters__, (Ts, T)) 9835 self.assertEqual(C3.__args__, ((int, *Ts), T)) 9836 self.assertEqual(C3[str, bool, bytes], PandT[[int, str, bool], bytes]) 9837 9838 def test_paramspec_in_nested_generics(self): 9839 # Although ParamSpec should not be found in __parameters__ of most 9840 # generics, they probably should be found when nested in 9841 # a valid location. 9842 T = TypeVar("T") 9843 P = ParamSpec("P") 9844 C1 = Callable[P, T] 9845 G1 = List[C1] 9846 G2 = list[C1] 9847 G3 = list[C1] | int 9848 self.assertEqual(G1.__parameters__, (P, T)) 9849 self.assertEqual(G2.__parameters__, (P, T)) 9850 self.assertEqual(G3.__parameters__, (P, T)) 9851 C = Callable[[int, str], float] 9852 self.assertEqual(G1[[int, str], float], List[C]) 9853 self.assertEqual(G2[[int, str], float], list[C]) 9854 self.assertEqual(G3[[int, str], float], list[C] | int) 9855 9856 def test_paramspec_gets_copied(self): 9857 # bpo-46581 9858 P = ParamSpec('P') 9859 P2 = ParamSpec('P2') 9860 C1 = Callable[P, int] 9861 self.assertEqual(C1.__parameters__, (P,)) 9862 self.assertEqual(C1[P2].__parameters__, (P2,)) 9863 self.assertEqual(C1[str].__parameters__, ()) 9864 self.assertEqual(C1[str, T].__parameters__, (T,)) 9865 self.assertEqual(C1[Concatenate[str, P2]].__parameters__, (P2,)) 9866 self.assertEqual(C1[Concatenate[T, P2]].__parameters__, (T, P2)) 9867 self.assertEqual(C1[...].__parameters__, ()) 9868 9869 C2 = Callable[Concatenate[str, P], int] 9870 self.assertEqual(C2.__parameters__, (P,)) 9871 self.assertEqual(C2[P2].__parameters__, (P2,)) 9872 self.assertEqual(C2[str].__parameters__, ()) 9873 self.assertEqual(C2[str, T].__parameters__, (T,)) 9874 self.assertEqual(C2[Concatenate[str, P2]].__parameters__, (P2,)) 9875 self.assertEqual(C2[Concatenate[T, P2]].__parameters__, (T, P2)) 9876 9877 def test_cannot_subclass(self): 9878 with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpec'): 9879 class C(ParamSpec): pass 9880 with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpecArgs'): 9881 class D(ParamSpecArgs): pass 9882 with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpecKwargs'): 9883 class E(ParamSpecKwargs): pass 9884 P = ParamSpec('P') 9885 with self.assertRaisesRegex(TypeError, 9886 CANNOT_SUBCLASS_INSTANCE % 'ParamSpec'): 9887 class F(P): pass 9888 with self.assertRaisesRegex(TypeError, 9889 CANNOT_SUBCLASS_INSTANCE % 'ParamSpecArgs'): 9890 class G(P.args): pass 9891 with self.assertRaisesRegex(TypeError, 9892 CANNOT_SUBCLASS_INSTANCE % 'ParamSpecKwargs'): 9893 class H(P.kwargs): pass 9894 9895 9896class ConcatenateTests(BaseTestCase): 9897 def test_basics(self): 9898 P = ParamSpec('P') 9899 class MyClass: ... 9900 c = Concatenate[MyClass, P] 9901 self.assertNotEqual(c, Concatenate) 9902 9903 def test_dir(self): 9904 P = ParamSpec('P') 9905 dir_items = set(dir(Concatenate[int, P])) 9906 for required_item in [ 9907 '__args__', '__parameters__', '__origin__', 9908 ]: 9909 with self.subTest(required_item=required_item): 9910 self.assertIn(required_item, dir_items) 9911 9912 def test_valid_uses(self): 9913 P = ParamSpec('P') 9914 T = TypeVar('T') 9915 C1 = Callable[Concatenate[int, P], int] 9916 self.assertEqual(C1.__args__, (Concatenate[int, P], int)) 9917 self.assertEqual(C1.__parameters__, (P,)) 9918 C2 = Callable[Concatenate[int, T, P], T] 9919 self.assertEqual(C2.__args__, (Concatenate[int, T, P], T)) 9920 self.assertEqual(C2.__parameters__, (T, P)) 9921 9922 # Test collections.abc.Callable too. 9923 C3 = collections.abc.Callable[Concatenate[int, P], int] 9924 self.assertEqual(C3.__args__, (Concatenate[int, P], int)) 9925 self.assertEqual(C3.__parameters__, (P,)) 9926 C4 = collections.abc.Callable[Concatenate[int, T, P], T] 9927 self.assertEqual(C4.__args__, (Concatenate[int, T, P], T)) 9928 self.assertEqual(C4.__parameters__, (T, P)) 9929 9930 def test_var_substitution(self): 9931 T = TypeVar('T') 9932 P = ParamSpec('P') 9933 P2 = ParamSpec('P2') 9934 C = Concatenate[T, P] 9935 self.assertEqual(C[int, P2], Concatenate[int, P2]) 9936 self.assertEqual(C[int, [str, float]], (int, str, float)) 9937 self.assertEqual(C[int, []], (int,)) 9938 self.assertEqual(C[int, Concatenate[str, P2]], 9939 Concatenate[int, str, P2]) 9940 self.assertEqual(C[int, ...], Concatenate[int, ...]) 9941 9942 C = Concatenate[int, P] 9943 self.assertEqual(C[P2], Concatenate[int, P2]) 9944 self.assertEqual(C[[str, float]], (int, str, float)) 9945 self.assertEqual(C[str, float], (int, str, float)) 9946 self.assertEqual(C[[]], (int,)) 9947 self.assertEqual(C[Concatenate[str, P2]], Concatenate[int, str, P2]) 9948 self.assertEqual(C[...], Concatenate[int, ...]) 9949 9950class TypeGuardTests(BaseTestCase): 9951 def test_basics(self): 9952 TypeGuard[int] # OK 9953 9954 def foo(arg) -> TypeGuard[int]: ... 9955 self.assertEqual(gth(foo), {'return': TypeGuard[int]}) 9956 9957 with self.assertRaises(TypeError): 9958 TypeGuard[int, str] 9959 9960 def test_repr(self): 9961 self.assertEqual(repr(TypeGuard), 'typing.TypeGuard') 9962 cv = TypeGuard[int] 9963 self.assertEqual(repr(cv), 'typing.TypeGuard[int]') 9964 cv = TypeGuard[Employee] 9965 self.assertEqual(repr(cv), 'typing.TypeGuard[%s.Employee]' % __name__) 9966 cv = TypeGuard[tuple[int]] 9967 self.assertEqual(repr(cv), 'typing.TypeGuard[tuple[int]]') 9968 9969 def test_cannot_subclass(self): 9970 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 9971 class C(type(TypeGuard)): 9972 pass 9973 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 9974 class D(type(TypeGuard[int])): 9975 pass 9976 with self.assertRaisesRegex(TypeError, 9977 r'Cannot subclass typing\.TypeGuard'): 9978 class E(TypeGuard): 9979 pass 9980 with self.assertRaisesRegex(TypeError, 9981 r'Cannot subclass typing\.TypeGuard\[int\]'): 9982 class F(TypeGuard[int]): 9983 pass 9984 9985 def test_cannot_init(self): 9986 with self.assertRaises(TypeError): 9987 TypeGuard() 9988 with self.assertRaises(TypeError): 9989 type(TypeGuard)() 9990 with self.assertRaises(TypeError): 9991 type(TypeGuard[Optional[int]])() 9992 9993 def test_no_isinstance(self): 9994 with self.assertRaises(TypeError): 9995 isinstance(1, TypeGuard[int]) 9996 with self.assertRaises(TypeError): 9997 issubclass(int, TypeGuard) 9998 9999 10000class TypeIsTests(BaseTestCase): 10001 def test_basics(self): 10002 TypeIs[int] # OK 10003 10004 def foo(arg) -> TypeIs[int]: ... 10005 self.assertEqual(gth(foo), {'return': TypeIs[int]}) 10006 10007 with self.assertRaises(TypeError): 10008 TypeIs[int, str] 10009 10010 def test_repr(self): 10011 self.assertEqual(repr(TypeIs), 'typing.TypeIs') 10012 cv = TypeIs[int] 10013 self.assertEqual(repr(cv), 'typing.TypeIs[int]') 10014 cv = TypeIs[Employee] 10015 self.assertEqual(repr(cv), 'typing.TypeIs[%s.Employee]' % __name__) 10016 cv = TypeIs[tuple[int]] 10017 self.assertEqual(repr(cv), 'typing.TypeIs[tuple[int]]') 10018 10019 def test_cannot_subclass(self): 10020 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 10021 class C(type(TypeIs)): 10022 pass 10023 with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): 10024 class D(type(TypeIs[int])): 10025 pass 10026 with self.assertRaisesRegex(TypeError, 10027 r'Cannot subclass typing\.TypeIs'): 10028 class E(TypeIs): 10029 pass 10030 with self.assertRaisesRegex(TypeError, 10031 r'Cannot subclass typing\.TypeIs\[int\]'): 10032 class F(TypeIs[int]): 10033 pass 10034 10035 def test_cannot_init(self): 10036 with self.assertRaises(TypeError): 10037 TypeIs() 10038 with self.assertRaises(TypeError): 10039 type(TypeIs)() 10040 with self.assertRaises(TypeError): 10041 type(TypeIs[Optional[int]])() 10042 10043 def test_no_isinstance(self): 10044 with self.assertRaises(TypeError): 10045 isinstance(1, TypeIs[int]) 10046 with self.assertRaises(TypeError): 10047 issubclass(int, TypeIs) 10048 10049 10050SpecialAttrsP = typing.ParamSpec('SpecialAttrsP') 10051SpecialAttrsT = typing.TypeVar('SpecialAttrsT', int, float, complex) 10052 10053 10054class SpecialAttrsTests(BaseTestCase): 10055 10056 def test_special_attrs(self): 10057 cls_to_check = { 10058 # ABC classes 10059 typing.AbstractSet: 'AbstractSet', 10060 typing.AsyncContextManager: 'AsyncContextManager', 10061 typing.AsyncGenerator: 'AsyncGenerator', 10062 typing.AsyncIterable: 'AsyncIterable', 10063 typing.AsyncIterator: 'AsyncIterator', 10064 typing.Awaitable: 'Awaitable', 10065 typing.ByteString: 'ByteString', 10066 typing.Callable: 'Callable', 10067 typing.ChainMap: 'ChainMap', 10068 typing.Collection: 'Collection', 10069 typing.Container: 'Container', 10070 typing.ContextManager: 'ContextManager', 10071 typing.Coroutine: 'Coroutine', 10072 typing.Counter: 'Counter', 10073 typing.DefaultDict: 'DefaultDict', 10074 typing.Deque: 'Deque', 10075 typing.Dict: 'Dict', 10076 typing.FrozenSet: 'FrozenSet', 10077 typing.Generator: 'Generator', 10078 typing.Hashable: 'Hashable', 10079 typing.ItemsView: 'ItemsView', 10080 typing.Iterable: 'Iterable', 10081 typing.Iterator: 'Iterator', 10082 typing.KeysView: 'KeysView', 10083 typing.List: 'List', 10084 typing.Mapping: 'Mapping', 10085 typing.MappingView: 'MappingView', 10086 typing.MutableMapping: 'MutableMapping', 10087 typing.MutableSequence: 'MutableSequence', 10088 typing.MutableSet: 'MutableSet', 10089 typing.OrderedDict: 'OrderedDict', 10090 typing.Reversible: 'Reversible', 10091 typing.Sequence: 'Sequence', 10092 typing.Set: 'Set', 10093 typing.Sized: 'Sized', 10094 typing.Tuple: 'Tuple', 10095 typing.Type: 'Type', 10096 typing.ValuesView: 'ValuesView', 10097 # Subscribed ABC classes 10098 typing.AbstractSet[Any]: 'AbstractSet', 10099 typing.AsyncContextManager[Any, Any]: 'AsyncContextManager', 10100 typing.AsyncGenerator[Any, Any]: 'AsyncGenerator', 10101 typing.AsyncIterable[Any]: 'AsyncIterable', 10102 typing.AsyncIterator[Any]: 'AsyncIterator', 10103 typing.Awaitable[Any]: 'Awaitable', 10104 typing.Callable[[], Any]: 'Callable', 10105 typing.Callable[..., Any]: 'Callable', 10106 typing.ChainMap[Any, Any]: 'ChainMap', 10107 typing.Collection[Any]: 'Collection', 10108 typing.Container[Any]: 'Container', 10109 typing.ContextManager[Any, Any]: 'ContextManager', 10110 typing.Coroutine[Any, Any, Any]: 'Coroutine', 10111 typing.Counter[Any]: 'Counter', 10112 typing.DefaultDict[Any, Any]: 'DefaultDict', 10113 typing.Deque[Any]: 'Deque', 10114 typing.Dict[Any, Any]: 'Dict', 10115 typing.FrozenSet[Any]: 'FrozenSet', 10116 typing.Generator[Any, Any, Any]: 'Generator', 10117 typing.ItemsView[Any, Any]: 'ItemsView', 10118 typing.Iterable[Any]: 'Iterable', 10119 typing.Iterator[Any]: 'Iterator', 10120 typing.KeysView[Any]: 'KeysView', 10121 typing.List[Any]: 'List', 10122 typing.Mapping[Any, Any]: 'Mapping', 10123 typing.MappingView[Any]: 'MappingView', 10124 typing.MutableMapping[Any, Any]: 'MutableMapping', 10125 typing.MutableSequence[Any]: 'MutableSequence', 10126 typing.MutableSet[Any]: 'MutableSet', 10127 typing.OrderedDict[Any, Any]: 'OrderedDict', 10128 typing.Reversible[Any]: 'Reversible', 10129 typing.Sequence[Any]: 'Sequence', 10130 typing.Set[Any]: 'Set', 10131 typing.Tuple[Any]: 'Tuple', 10132 typing.Tuple[Any, ...]: 'Tuple', 10133 typing.Type[Any]: 'Type', 10134 typing.ValuesView[Any]: 'ValuesView', 10135 # Special Forms 10136 typing.Annotated: 'Annotated', 10137 typing.Any: 'Any', 10138 typing.ClassVar: 'ClassVar', 10139 typing.Concatenate: 'Concatenate', 10140 typing.Final: 'Final', 10141 typing.ForwardRef: 'ForwardRef', 10142 typing.Literal: 'Literal', 10143 typing.NewType: 'NewType', 10144 typing.NoReturn: 'NoReturn', 10145 typing.Never: 'Never', 10146 typing.Optional: 'Optional', 10147 typing.TypeAlias: 'TypeAlias', 10148 typing.TypeGuard: 'TypeGuard', 10149 typing.TypeIs: 'TypeIs', 10150 typing.TypeVar: 'TypeVar', 10151 typing.Union: 'Union', 10152 typing.Self: 'Self', 10153 # Subscribed special forms 10154 typing.Annotated[Any, "Annotation"]: 'Annotated', 10155 typing.Annotated[int, 'Annotation']: 'Annotated', 10156 typing.ClassVar[Any]: 'ClassVar', 10157 typing.Concatenate[Any, SpecialAttrsP]: 'Concatenate', 10158 typing.Final[Any]: 'Final', 10159 typing.Literal[Any]: 'Literal', 10160 typing.Literal[1, 2]: 'Literal', 10161 typing.Literal[True, 2]: 'Literal', 10162 typing.Optional[Any]: 'Optional', 10163 typing.TypeGuard[Any]: 'TypeGuard', 10164 typing.TypeIs[Any]: 'TypeIs', 10165 typing.Union[Any]: 'Any', 10166 typing.Union[int, float]: 'Union', 10167 # Incompatible special forms (tested in test_special_attrs2) 10168 # - typing.ForwardRef('set[Any]') 10169 # - typing.NewType('TypeName', Any) 10170 # - typing.ParamSpec('SpecialAttrsP') 10171 # - typing.TypeVar('T') 10172 } 10173 10174 for cls, name in cls_to_check.items(): 10175 with self.subTest(cls=cls): 10176 self.assertEqual(cls.__name__, name, str(cls)) 10177 self.assertEqual(cls.__qualname__, name, str(cls)) 10178 self.assertEqual(cls.__module__, 'typing', str(cls)) 10179 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 10180 s = pickle.dumps(cls, proto) 10181 loaded = pickle.loads(s) 10182 self.assertIs(cls, loaded) 10183 10184 TypeName = typing.NewType('SpecialAttrsTests.TypeName', Any) 10185 10186 def test_special_attrs2(self): 10187 # Forward refs provide a different introspection API. __name__ and 10188 # __qualname__ make little sense for forward refs as they can store 10189 # complex typing expressions. 10190 fr = typing.ForwardRef('set[Any]') 10191 self.assertFalse(hasattr(fr, '__name__')) 10192 self.assertFalse(hasattr(fr, '__qualname__')) 10193 self.assertEqual(fr.__module__, 'typing') 10194 # Forward refs are currently unpicklable. 10195 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 10196 with self.assertRaises(TypeError): 10197 pickle.dumps(fr, proto) 10198 10199 self.assertEqual(SpecialAttrsTests.TypeName.__name__, 'TypeName') 10200 self.assertEqual( 10201 SpecialAttrsTests.TypeName.__qualname__, 10202 'SpecialAttrsTests.TypeName', 10203 ) 10204 self.assertEqual( 10205 SpecialAttrsTests.TypeName.__module__, 10206 __name__, 10207 ) 10208 # NewTypes are picklable assuming correct qualname information. 10209 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 10210 s = pickle.dumps(SpecialAttrsTests.TypeName, proto) 10211 loaded = pickle.loads(s) 10212 self.assertIs(SpecialAttrsTests.TypeName, loaded) 10213 10214 # Type variables don't support non-global instantiation per PEP 484 10215 # restriction that "The argument to TypeVar() must be a string equal 10216 # to the variable name to which it is assigned". Thus, providing 10217 # __qualname__ is unnecessary. 10218 self.assertEqual(SpecialAttrsT.__name__, 'SpecialAttrsT') 10219 self.assertFalse(hasattr(SpecialAttrsT, '__qualname__')) 10220 self.assertEqual(SpecialAttrsT.__module__, __name__) 10221 # Module-level type variables are picklable. 10222 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 10223 s = pickle.dumps(SpecialAttrsT, proto) 10224 loaded = pickle.loads(s) 10225 self.assertIs(SpecialAttrsT, loaded) 10226 10227 self.assertEqual(SpecialAttrsP.__name__, 'SpecialAttrsP') 10228 self.assertFalse(hasattr(SpecialAttrsP, '__qualname__')) 10229 self.assertEqual(SpecialAttrsP.__module__, __name__) 10230 # Module-level ParamSpecs are picklable. 10231 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 10232 s = pickle.dumps(SpecialAttrsP, proto) 10233 loaded = pickle.loads(s) 10234 self.assertIs(SpecialAttrsP, loaded) 10235 10236 def test_genericalias_dir(self): 10237 class Foo(Generic[T]): 10238 def bar(self): 10239 pass 10240 baz = 3 10241 __magic__ = 4 10242 10243 # The class attributes of the original class should be visible even 10244 # in dir() of the GenericAlias. See bpo-45755. 10245 dir_items = set(dir(Foo[int])) 10246 for required_item in [ 10247 'bar', 'baz', 10248 '__args__', '__parameters__', '__origin__', 10249 ]: 10250 with self.subTest(required_item=required_item): 10251 self.assertIn(required_item, dir_items) 10252 self.assertNotIn('__magic__', dir_items) 10253 10254 10255class RevealTypeTests(BaseTestCase): 10256 def test_reveal_type(self): 10257 obj = object() 10258 with captured_stderr() as stderr: 10259 self.assertIs(obj, reveal_type(obj)) 10260 self.assertEqual(stderr.getvalue(), "Runtime type is 'object'\n") 10261 10262 10263class DataclassTransformTests(BaseTestCase): 10264 def test_decorator(self): 10265 def create_model(*, frozen: bool = False, kw_only: bool = True): 10266 return lambda cls: cls 10267 10268 decorated = dataclass_transform(kw_only_default=True, order_default=False)(create_model) 10269 10270 class CustomerModel: 10271 id: int 10272 10273 self.assertIs(decorated, create_model) 10274 self.assertEqual( 10275 decorated.__dataclass_transform__, 10276 { 10277 "eq_default": True, 10278 "order_default": False, 10279 "kw_only_default": True, 10280 "frozen_default": False, 10281 "field_specifiers": (), 10282 "kwargs": {}, 10283 } 10284 ) 10285 self.assertIs( 10286 decorated(frozen=True, kw_only=False)(CustomerModel), 10287 CustomerModel 10288 ) 10289 10290 def test_base_class(self): 10291 class ModelBase: 10292 def __init_subclass__(cls, *, frozen: bool = False): ... 10293 10294 Decorated = dataclass_transform( 10295 eq_default=True, 10296 order_default=True, 10297 # Arbitrary unrecognized kwargs are accepted at runtime. 10298 make_everything_awesome=True, 10299 )(ModelBase) 10300 10301 class CustomerModel(Decorated, frozen=True): 10302 id: int 10303 10304 self.assertIs(Decorated, ModelBase) 10305 self.assertEqual( 10306 Decorated.__dataclass_transform__, 10307 { 10308 "eq_default": True, 10309 "order_default": True, 10310 "kw_only_default": False, 10311 "frozen_default": False, 10312 "field_specifiers": (), 10313 "kwargs": {"make_everything_awesome": True}, 10314 } 10315 ) 10316 self.assertIsSubclass(CustomerModel, Decorated) 10317 10318 def test_metaclass(self): 10319 class Field: ... 10320 10321 class ModelMeta(type): 10322 def __new__( 10323 cls, name, bases, namespace, *, init: bool = True, 10324 ): 10325 return super().__new__(cls, name, bases, namespace) 10326 10327 Decorated = dataclass_transform( 10328 order_default=True, frozen_default=True, field_specifiers=(Field,) 10329 )(ModelMeta) 10330 10331 class ModelBase(metaclass=Decorated): ... 10332 10333 class CustomerModel(ModelBase, init=False): 10334 id: int 10335 10336 self.assertIs(Decorated, ModelMeta) 10337 self.assertEqual( 10338 Decorated.__dataclass_transform__, 10339 { 10340 "eq_default": True, 10341 "order_default": True, 10342 "kw_only_default": False, 10343 "frozen_default": True, 10344 "field_specifiers": (Field,), 10345 "kwargs": {}, 10346 } 10347 ) 10348 self.assertIsInstance(CustomerModel, Decorated) 10349 10350 10351class NoDefaultTests(BaseTestCase): 10352 def test_pickling(self): 10353 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 10354 s = pickle.dumps(NoDefault, proto) 10355 loaded = pickle.loads(s) 10356 self.assertIs(NoDefault, loaded) 10357 10358 def test_constructor(self): 10359 self.assertIs(NoDefault, type(NoDefault)()) 10360 with self.assertRaises(TypeError): 10361 type(NoDefault)(1) 10362 10363 def test_repr(self): 10364 self.assertEqual(repr(NoDefault), 'typing.NoDefault') 10365 10366 @requires_docstrings 10367 def test_doc(self): 10368 self.assertIsInstance(NoDefault.__doc__, str) 10369 10370 def test_class(self): 10371 self.assertIs(NoDefault.__class__, type(NoDefault)) 10372 10373 def test_no_call(self): 10374 with self.assertRaises(TypeError): 10375 NoDefault() 10376 10377 def test_no_attributes(self): 10378 with self.assertRaises(AttributeError): 10379 NoDefault.foo = 3 10380 with self.assertRaises(AttributeError): 10381 NoDefault.foo 10382 10383 # TypeError is consistent with the behavior of NoneType 10384 with self.assertRaises(TypeError): 10385 type(NoDefault).foo = 3 10386 with self.assertRaises(AttributeError): 10387 type(NoDefault).foo 10388 10389 10390class AllTests(BaseTestCase): 10391 """Tests for __all__.""" 10392 10393 def test_all(self): 10394 from typing import __all__ as a 10395 # Just spot-check the first and last of every category. 10396 self.assertIn('AbstractSet', a) 10397 self.assertIn('ValuesView', a) 10398 self.assertIn('cast', a) 10399 self.assertIn('overload', a) 10400 # Context managers. 10401 self.assertIn('ContextManager', a) 10402 self.assertIn('AsyncContextManager', a) 10403 # Check that former namespaces io and re are not exported. 10404 self.assertNotIn('io', a) 10405 self.assertNotIn('re', a) 10406 # Spot-check that stdlib modules aren't exported. 10407 self.assertNotIn('os', a) 10408 self.assertNotIn('sys', a) 10409 # Check that Text is defined. 10410 self.assertIn('Text', a) 10411 # Check previously missing classes. 10412 self.assertIn('SupportsBytes', a) 10413 self.assertIn('SupportsComplex', a) 10414 10415 def test_all_exported_names(self): 10416 # ensure all dynamically created objects are actualised 10417 for name in typing.__all__: 10418 getattr(typing, name) 10419 10420 actual_all = set(typing.__all__) 10421 computed_all = { 10422 k for k, v in vars(typing).items() 10423 # explicitly exported, not a thing with __module__ 10424 if k in actual_all or ( 10425 # avoid private names 10426 not k.startswith('_') and 10427 # there's a few types and metaclasses that aren't exported 10428 not k.endswith(('Meta', '_contra', '_co')) and 10429 not k.upper() == k and 10430 # but export all things that have __module__ == 'typing' 10431 getattr(v, '__module__', None) == typing.__name__ 10432 ) 10433 } 10434 self.assertSetEqual(computed_all, actual_all) 10435 10436 10437class TypeIterationTests(BaseTestCase): 10438 _UNITERABLE_TYPES = ( 10439 Any, 10440 Union, 10441 Union[str, int], 10442 Union[str, T], 10443 List, 10444 Tuple, 10445 Callable, 10446 Callable[..., T], 10447 Callable[[T], str], 10448 Annotated, 10449 Annotated[T, ''], 10450 ) 10451 10452 def test_cannot_iterate(self): 10453 expected_error_regex = "object is not iterable" 10454 for test_type in self._UNITERABLE_TYPES: 10455 with self.subTest(type=test_type): 10456 with self.assertRaisesRegex(TypeError, expected_error_regex): 10457 iter(test_type) 10458 with self.assertRaisesRegex(TypeError, expected_error_regex): 10459 list(test_type) 10460 with self.assertRaisesRegex(TypeError, expected_error_regex): 10461 for _ in test_type: 10462 pass 10463 10464 def test_is_not_instance_of_iterable(self): 10465 for type_to_test in self._UNITERABLE_TYPES: 10466 self.assertNotIsInstance(type_to_test, collections.abc.Iterable) 10467 10468 10469def load_tests(loader, tests, pattern): 10470 import doctest 10471 tests.addTests(doctest.DocTestSuite(typing)) 10472 return tests 10473 10474 10475if __name__ == '__main__': 10476 main() 10477