1import abc
2import collections
3import collections.abc
4import contextlib
5import copy
6import gc
7import importlib
8import inspect
9import io
10import pickle
11import re
12import subprocess
13import sys
14import tempfile
15import textwrap
16import types
17import typing
18import warnings
19from collections import defaultdict
20from functools import lru_cache
21from pathlib import Path
22from unittest import TestCase, main, skipIf, skipUnless
23from unittest.mock import patch
24
25import typing_extensions
26from _typed_dict_test_helper import Foo, FooGeneric, VeryAnnotated
27from typing_extensions import (
28    Annotated,
29    Any,
30    AnyStr,
31    AsyncContextManager,
32    AsyncIterator,
33    Awaitable,
34    Buffer,
35    Callable,
36    ClassVar,
37    Concatenate,
38    Dict,
39    Doc,
40    Final,
41    Generic,
42    IntVar,
43    Iterable,
44    Iterator,
45    List,
46    Literal,
47    LiteralString,
48    NamedTuple,
49    Never,
50    NewType,
51    NoDefault,
52    NoReturn,
53    NotRequired,
54    Optional,
55    ParamSpec,
56    ParamSpecArgs,
57    ParamSpecKwargs,
58    Protocol,
59    ReadOnly,
60    Required,
61    Self,
62    Set,
63    Tuple,
64    Type,
65    TypeAlias,
66    TypeAliasType,
67    TypedDict,
68    TypeGuard,
69    TypeIs,
70    TypeVar,
71    TypeVarTuple,
72    Union,
73    Unpack,
74    assert_never,
75    assert_type,
76    clear_overloads,
77    dataclass_transform,
78    deprecated,
79    final,
80    get_args,
81    get_origin,
82    get_original_bases,
83    get_overloads,
84    get_protocol_members,
85    get_type_hints,
86    is_protocol,
87    is_typeddict,
88    no_type_check,
89    overload,
90    override,
91    reveal_type,
92    runtime,
93    runtime_checkable,
94)
95
96NoneType = type(None)
97T = TypeVar("T")
98KT = TypeVar("KT")
99VT = TypeVar("VT")
100
101# Flags used to mark tests that only apply after a specific
102# version of the typing module.
103TYPING_3_9_0 = sys.version_info[:3] >= (3, 9, 0)
104TYPING_3_10_0 = sys.version_info[:3] >= (3, 10, 0)
105
106# 3.11 makes runtime type checks (_type_check) more lenient.
107TYPING_3_11_0 = sys.version_info[:3] >= (3, 11, 0)
108
109# 3.12 changes the representation of Unpack[] (PEP 692)
110TYPING_3_12_0 = sys.version_info[:3] >= (3, 12, 0)
111
112# 3.13 drops support for the keyword argument syntax of TypedDict
113TYPING_3_13_0 = sys.version_info[:3] >= (3, 13, 0)
114
115# https://github.com/python/cpython/pull/27017 was backported into some 3.9 and 3.10
116# versions, but not all
117HAS_FORWARD_MODULE = "module" in inspect.signature(typing._type_check).parameters
118
119skip_if_py313_beta_1 = skipIf(
120    sys.version_info[:5] == (3, 13, 0, 'beta', 1),
121    "Bugfixes will be released in 3.13.0b2"
122)
123
124ANN_MODULE_SOURCE = '''\
125import sys
126from typing import List, Optional
127from functools import wraps
128
129try:
130    __annotations__[1] = 2
131except NameError:
132    assert sys.version_info >= (3, 14)
133
134class C:
135
136    x = 5; y: Optional['C'] = None
137
138from typing import Tuple
139x: int = 5; y: str = x; f: Tuple[int, int]
140
141class M(type):
142    try:
143        __annotations__['123'] = 123
144    except NameError:
145        assert sys.version_info >= (3, 14)
146    o: type = object
147
148(pars): bool = True
149
150class D(C):
151    j: str = 'hi'; k: str= 'bye'
152
153from types import new_class
154h_class = new_class('H', (C,))
155j_class = new_class('J')
156
157class F():
158    z: int = 5
159    def __init__(self, x):
160        pass
161
162class Y(F):
163    def __init__(self):
164        super(F, self).__init__(123)
165
166class Meta(type):
167    def __new__(meta, name, bases, namespace):
168        return super().__new__(meta, name, bases, namespace)
169
170class S(metaclass = Meta):
171    x: str = 'something'
172    y: str = 'something else'
173
174def foo(x: int = 10):
175    def bar(y: List[str]):
176        x: str = 'yes'
177    bar()
178
179def dec(func):
180    @wraps(func)
181    def wrapper(*args, **kwargs):
182        return func(*args, **kwargs)
183    return wrapper
184'''
185
186ANN_MODULE_2_SOURCE = '''\
187from typing import no_type_check, ClassVar
188
189i: int = 1
190j: int
191x: float = i/10
192
193def f():
194    class C: ...
195    return C()
196
197f().new_attr: object = object()
198
199class C:
200    def __init__(self, x: int) -> None:
201        self.x = x
202
203c = C(5)
204c.new_attr: int = 10
205
206__annotations__ = {}
207
208
209@no_type_check
210class NTC:
211    def meth(self, param: complex) -> None:
212        ...
213
214class CV:
215    var: ClassVar['CV']
216
217CV.var = CV()
218'''
219
220ANN_MODULE_3_SOURCE = '''\
221def f_bad_ann():
222    __annotations__[1] = 2
223
224class C_OK:
225    def __init__(self, x: int) -> None:
226        self.x: no_such_name = x  # This one is OK as proposed by Guido
227
228class D_bad_ann:
229    def __init__(self, x: int) -> None:
230        sfel.y: int = 0
231
232def g_bad_ann():
233    no_such_name.attr: int = 0
234'''
235
236
237class BaseTestCase(TestCase):
238    def assertIsSubclass(self, cls, class_or_tuple, msg=None):
239        if not issubclass(cls, class_or_tuple):
240            message = f'{cls!r} is not a subclass of {class_or_tuple!r}'
241            if msg is not None:
242                message += f' : {msg}'
243            raise self.failureException(message)
244
245    def assertNotIsSubclass(self, cls, class_or_tuple, msg=None):
246        if issubclass(cls, class_or_tuple):
247            message = f'{cls!r} is a subclass of {class_or_tuple!r}'
248            if msg is not None:
249                message += f' : {msg}'
250            raise self.failureException(message)
251
252
253class Employee:
254    pass
255
256
257class BottomTypeTestsMixin:
258    bottom_type: ClassVar[Any]
259
260    def test_equality(self):
261        self.assertEqual(self.bottom_type, self.bottom_type)
262        self.assertIs(self.bottom_type, self.bottom_type)
263        self.assertNotEqual(self.bottom_type, None)
264
265    def test_get_origin(self):
266        self.assertIs(get_origin(self.bottom_type), None)
267
268    def test_instance_type_error(self):
269        with self.assertRaises(TypeError):
270            isinstance(42, self.bottom_type)
271
272    def test_subclass_type_error(self):
273        with self.assertRaises(TypeError):
274            issubclass(Employee, self.bottom_type)
275        with self.assertRaises(TypeError):
276            issubclass(NoReturn, self.bottom_type)
277
278    def test_not_generic(self):
279        with self.assertRaises(TypeError):
280            self.bottom_type[int]
281
282    def test_cannot_subclass(self):
283        with self.assertRaises(TypeError):
284            class A(self.bottom_type):
285                pass
286        with self.assertRaises(TypeError):
287            class B(type(self.bottom_type)):
288                pass
289
290    def test_cannot_instantiate(self):
291        with self.assertRaises(TypeError):
292            self.bottom_type()
293        with self.assertRaises(TypeError):
294            type(self.bottom_type)()
295
296    def test_pickle(self):
297        for proto in range(pickle.HIGHEST_PROTOCOL):
298            pickled = pickle.dumps(self.bottom_type, protocol=proto)
299            self.assertIs(self.bottom_type, pickle.loads(pickled))
300
301
302class NoReturnTests(BottomTypeTestsMixin, BaseTestCase):
303    bottom_type = NoReturn
304
305    def test_repr(self):
306        if hasattr(typing, 'NoReturn'):
307            self.assertEqual(repr(NoReturn), 'typing.NoReturn')
308        else:
309            self.assertEqual(repr(NoReturn), 'typing_extensions.NoReturn')
310
311    def test_get_type_hints(self):
312        def some(arg: NoReturn) -> NoReturn: ...
313        def some_str(arg: 'NoReturn') -> 'typing.NoReturn': ...
314
315        expected = {'arg': NoReturn, 'return': NoReturn}
316        for target in some, some_str:
317            with self.subTest(target=target):
318                self.assertEqual(gth(target), expected)
319
320    def test_not_equality(self):
321        self.assertNotEqual(NoReturn, Never)
322        self.assertNotEqual(Never, NoReturn)
323
324
325class NeverTests(BottomTypeTestsMixin, BaseTestCase):
326    bottom_type = Never
327
328    def test_repr(self):
329        if hasattr(typing, 'Never'):
330            self.assertEqual(repr(Never), 'typing.Never')
331        else:
332            self.assertEqual(repr(Never), 'typing_extensions.Never')
333
334    def test_get_type_hints(self):
335        def some(arg: Never) -> Never: ...
336        def some_str(arg: 'Never') -> 'typing_extensions.Never': ...
337
338        expected = {'arg': Never, 'return': Never}
339        for target in [some, some_str]:
340            with self.subTest(target=target):
341                self.assertEqual(gth(target), expected)
342
343
344class AssertNeverTests(BaseTestCase):
345    def test_exception(self):
346        with self.assertRaises(AssertionError):
347            assert_never(None)
348
349        value = "some value"
350        with self.assertRaisesRegex(AssertionError, value):
351            assert_never(value)
352
353        # Make sure a huge value doesn't get printed in its entirety
354        huge_value = "a" * 10000
355        with self.assertRaises(AssertionError) as cm:
356            assert_never(huge_value)
357        self.assertLess(
358            len(cm.exception.args[0]),
359            typing_extensions._ASSERT_NEVER_REPR_MAX_LENGTH * 2,
360        )
361
362
363class OverrideTests(BaseTestCase):
364    def test_override(self):
365        class Base:
366            def normal_method(self): ...
367            @staticmethod
368            def static_method_good_order(): ...
369            @staticmethod
370            def static_method_bad_order(): ...
371            @staticmethod
372            def decorator_with_slots(): ...
373
374        class Derived(Base):
375            @override
376            def normal_method(self):
377                return 42
378
379            @staticmethod
380            @override
381            def static_method_good_order():
382                return 42
383
384            @override
385            @staticmethod
386            def static_method_bad_order():
387                return 42
388
389        self.assertIsSubclass(Derived, Base)
390        instance = Derived()
391        self.assertEqual(instance.normal_method(), 42)
392        self.assertIs(True, instance.normal_method.__override__)
393        self.assertEqual(Derived.static_method_good_order(), 42)
394        self.assertIs(True, Derived.static_method_good_order.__override__)
395        self.assertEqual(Derived.static_method_bad_order(), 42)
396        self.assertIs(False, hasattr(Derived.static_method_bad_order, "__override__"))
397
398
399class DeprecatedTests(BaseTestCase):
400    def test_dunder_deprecated(self):
401        @deprecated("A will go away soon")
402        class A:
403            pass
404
405        self.assertEqual(A.__deprecated__, "A will go away soon")
406        self.assertIsInstance(A, type)
407
408        @deprecated("b will go away soon")
409        def b():
410            pass
411
412        self.assertEqual(b.__deprecated__, "b will go away soon")
413        self.assertIsInstance(b, types.FunctionType)
414
415        @overload
416        @deprecated("no more ints")
417        def h(x: int) -> int: ...
418        @overload
419        def h(x: str) -> str: ...
420        def h(x):
421            return x
422
423        overloads = get_overloads(h)
424        self.assertEqual(len(overloads), 2)
425        self.assertEqual(overloads[0].__deprecated__, "no more ints")
426
427    def test_class(self):
428        @deprecated("A will go away soon")
429        class A:
430            pass
431
432        with self.assertWarnsRegex(DeprecationWarning, "A will go away soon"):
433            A()
434        with self.assertWarnsRegex(DeprecationWarning, "A will go away soon"):
435            with self.assertRaises(TypeError):
436                A(42)
437
438    def test_class_with_init(self):
439        @deprecated("HasInit will go away soon")
440        class HasInit:
441            def __init__(self, x):
442                self.x = x
443
444        with self.assertWarnsRegex(DeprecationWarning, "HasInit will go away soon"):
445            instance = HasInit(42)
446        self.assertEqual(instance.x, 42)
447
448    def test_class_with_new(self):
449        has_new_called = False
450
451        @deprecated("HasNew will go away soon")
452        class HasNew:
453            def __new__(cls, x):
454                nonlocal has_new_called
455                has_new_called = True
456                return super().__new__(cls)
457
458            def __init__(self, x) -> None:
459                self.x = x
460
461        with self.assertWarnsRegex(DeprecationWarning, "HasNew will go away soon"):
462            instance = HasNew(42)
463        self.assertEqual(instance.x, 42)
464        self.assertTrue(has_new_called)
465
466    def test_class_with_inherited_new(self):
467        new_base_called = False
468
469        class NewBase:
470            def __new__(cls, x):
471                nonlocal new_base_called
472                new_base_called = True
473                return super().__new__(cls)
474
475            def __init__(self, x) -> None:
476                self.x = x
477
478        @deprecated("HasInheritedNew will go away soon")
479        class HasInheritedNew(NewBase):
480            pass
481
482        with self.assertWarnsRegex(DeprecationWarning, "HasInheritedNew will go away soon"):
483            instance = HasInheritedNew(42)
484        self.assertEqual(instance.x, 42)
485        self.assertTrue(new_base_called)
486
487    def test_class_with_new_but_no_init(self):
488        new_called = False
489
490        @deprecated("HasNewNoInit will go away soon")
491        class HasNewNoInit:
492            def __new__(cls, x):
493                nonlocal new_called
494                new_called = True
495                obj = super().__new__(cls)
496                obj.x = x
497                return obj
498
499        with self.assertWarnsRegex(DeprecationWarning, "HasNewNoInit will go away soon"):
500            instance = HasNewNoInit(42)
501        self.assertEqual(instance.x, 42)
502        self.assertTrue(new_called)
503
504    def test_mixin_class(self):
505        @deprecated("Mixin will go away soon")
506        class Mixin:
507            pass
508
509        class Base:
510            def __init__(self, a) -> None:
511                self.a = a
512
513        with self.assertWarnsRegex(DeprecationWarning, "Mixin will go away soon"):
514            class Child(Base, Mixin):
515                pass
516
517        instance = Child(42)
518        self.assertEqual(instance.a, 42)
519
520    def test_existing_init_subclass(self):
521        @deprecated("C will go away soon")
522        class C:
523            def __init_subclass__(cls) -> None:
524                cls.inited = True
525
526        with self.assertWarnsRegex(DeprecationWarning, "C will go away soon"):
527            C()
528
529        with self.assertWarnsRegex(DeprecationWarning, "C will go away soon"):
530            class D(C):
531                pass
532
533        self.assertTrue(D.inited)
534        self.assertIsInstance(D(), D)  # no deprecation
535
536    def test_existing_init_subclass_in_base(self):
537        class Base:
538            def __init_subclass__(cls, x) -> None:
539                cls.inited = x
540
541        @deprecated("C will go away soon")
542        class C(Base, x=42):
543            pass
544
545        self.assertEqual(C.inited, 42)
546
547        with self.assertWarnsRegex(DeprecationWarning, "C will go away soon"):
548            C()
549
550        with self.assertWarnsRegex(DeprecationWarning, "C will go away soon"):
551            class D(C, x=3):
552                pass
553
554        self.assertEqual(D.inited, 3)
555
556    def test_init_subclass_has_correct_cls(self):
557        init_subclass_saw = None
558
559        @deprecated("Base will go away soon")
560        class Base:
561            def __init_subclass__(cls) -> None:
562                nonlocal init_subclass_saw
563                init_subclass_saw = cls
564
565        self.assertIsNone(init_subclass_saw)
566
567        with self.assertWarnsRegex(DeprecationWarning, "Base will go away soon"):
568            class C(Base):
569                pass
570
571        self.assertIs(init_subclass_saw, C)
572
573    def test_init_subclass_with_explicit_classmethod(self):
574        init_subclass_saw = None
575
576        @deprecated("Base will go away soon")
577        class Base:
578            @classmethod
579            def __init_subclass__(cls) -> None:
580                nonlocal init_subclass_saw
581                init_subclass_saw = cls
582
583        self.assertIsNone(init_subclass_saw)
584
585        with self.assertWarnsRegex(DeprecationWarning, "Base will go away soon"):
586            class C(Base):
587                pass
588
589        self.assertIs(init_subclass_saw, C)
590
591    def test_function(self):
592        @deprecated("b will go away soon")
593        def b():
594            pass
595
596        with self.assertWarnsRegex(DeprecationWarning, "b will go away soon"):
597            b()
598
599    def test_method(self):
600        class Capybara:
601            @deprecated("x will go away soon")
602            def x(self):
603                pass
604
605        instance = Capybara()
606        with self.assertWarnsRegex(DeprecationWarning, "x will go away soon"):
607            instance.x()
608
609    def test_property(self):
610        class Capybara:
611            @property
612            @deprecated("x will go away soon")
613            def x(self):
614                pass
615
616            @property
617            def no_more_setting(self):
618                return 42
619
620            @no_more_setting.setter
621            @deprecated("no more setting")
622            def no_more_setting(self, value):
623                pass
624
625        instance = Capybara()
626        with self.assertWarnsRegex(DeprecationWarning, "x will go away soon"):
627            instance.x
628
629        with warnings.catch_warnings():
630            warnings.simplefilter("error")
631            self.assertEqual(instance.no_more_setting, 42)
632
633        with self.assertWarnsRegex(DeprecationWarning, "no more setting"):
634            instance.no_more_setting = 42
635
636    def test_category(self):
637        @deprecated("c will go away soon", category=RuntimeWarning)
638        def c():
639            pass
640
641        with self.assertWarnsRegex(RuntimeWarning, "c will go away soon"):
642            c()
643
644    def test_turn_off_warnings(self):
645        @deprecated("d will go away soon", category=None)
646        def d():
647            pass
648
649        with warnings.catch_warnings():
650            warnings.simplefilter("error")
651            d()
652
653    def test_only_strings_allowed(self):
654        with self.assertRaisesRegex(
655            TypeError,
656            "Expected an object of type str for 'message', not 'type'"
657        ):
658            @deprecated
659            class Foo: ...
660
661        with self.assertRaisesRegex(
662            TypeError,
663            "Expected an object of type str for 'message', not 'function'"
664        ):
665            @deprecated
666            def foo(): ...
667
668    def test_no_retained_references_to_wrapper_instance(self):
669        @deprecated('depr')
670        def d(): pass
671
672        self.assertFalse(any(
673            isinstance(cell.cell_contents, deprecated) for cell in d.__closure__
674        ))
675
676
677class AnyTests(BaseTestCase):
678    def test_can_subclass(self):
679        class Mock(Any): pass
680        self.assertTrue(issubclass(Mock, Any))
681        self.assertIsInstance(Mock(), Mock)
682
683        class Something: pass
684        self.assertFalse(issubclass(Something, Any))
685        self.assertNotIsInstance(Something(), Mock)
686
687        class MockSomething(Something, Mock): pass
688        self.assertTrue(issubclass(MockSomething, Any))
689        ms = MockSomething()
690        self.assertIsInstance(ms, MockSomething)
691        self.assertIsInstance(ms, Something)
692        self.assertIsInstance(ms, Mock)
693
694    class SubclassesAny(Any):
695        ...
696
697    def test_repr(self):
698        if sys.version_info >= (3, 11):
699            mod_name = 'typing'
700        else:
701            mod_name = 'typing_extensions'
702        self.assertEqual(repr(Any), f"{mod_name}.Any")
703
704    @skipIf(sys.version_info[:3] == (3, 11, 0), "A bug was fixed in 3.11.1")
705    def test_repr_on_Any_subclass(self):
706        self.assertEqual(
707            repr(self.SubclassesAny),
708            f"<class '{self.SubclassesAny.__module__}.AnyTests.SubclassesAny'>"
709        )
710
711    def test_instantiation(self):
712        with self.assertRaises(TypeError):
713            Any()
714
715        self.SubclassesAny()
716
717    def test_isinstance(self):
718        with self.assertRaises(TypeError):
719            isinstance(object(), Any)
720
721        isinstance(object(), self.SubclassesAny)
722
723
724class ClassVarTests(BaseTestCase):
725
726    def test_basics(self):
727        if not TYPING_3_11_0:
728            with self.assertRaises(TypeError):
729                ClassVar[1]
730        with self.assertRaises(TypeError):
731            ClassVar[int, str]
732        with self.assertRaises(TypeError):
733            ClassVar[int][str]
734
735    def test_repr(self):
736        if hasattr(typing, 'ClassVar'):
737            mod_name = 'typing'
738        else:
739            mod_name = 'typing_extensions'
740        self.assertEqual(repr(ClassVar), mod_name + '.ClassVar')
741        cv = ClassVar[int]
742        self.assertEqual(repr(cv), mod_name + '.ClassVar[int]')
743        cv = ClassVar[Employee]
744        self.assertEqual(repr(cv), mod_name + f'.ClassVar[{__name__}.Employee]')
745
746    def test_cannot_subclass(self):
747        with self.assertRaises(TypeError):
748            class C(type(ClassVar)):
749                pass
750        with self.assertRaises(TypeError):
751            class D(type(ClassVar[int])):
752                pass
753
754    def test_cannot_init(self):
755        with self.assertRaises(TypeError):
756            ClassVar()
757        with self.assertRaises(TypeError):
758            type(ClassVar)()
759        with self.assertRaises(TypeError):
760            type(ClassVar[Optional[int]])()
761
762    def test_no_isinstance(self):
763        with self.assertRaises(TypeError):
764            isinstance(1, ClassVar[int])
765        with self.assertRaises(TypeError):
766            issubclass(int, ClassVar)
767
768
769class FinalTests(BaseTestCase):
770
771    def test_basics(self):
772        if not TYPING_3_11_0:
773            with self.assertRaises(TypeError):
774                Final[1]
775        with self.assertRaises(TypeError):
776            Final[int, str]
777        with self.assertRaises(TypeError):
778            Final[int][str]
779
780    def test_repr(self):
781        self.assertEqual(repr(Final), 'typing.Final')
782        cv = Final[int]
783        self.assertEqual(repr(cv), 'typing.Final[int]')
784        cv = Final[Employee]
785        self.assertEqual(repr(cv), f'typing.Final[{__name__}.Employee]')
786
787    def test_cannot_subclass(self):
788        with self.assertRaises(TypeError):
789            class C(type(Final)):
790                pass
791        with self.assertRaises(TypeError):
792            class D(type(Final[int])):
793                pass
794
795    def test_cannot_init(self):
796        with self.assertRaises(TypeError):
797            Final()
798        with self.assertRaises(TypeError):
799            type(Final)()
800        with self.assertRaises(TypeError):
801            type(Final[Optional[int]])()
802
803    def test_no_isinstance(self):
804        with self.assertRaises(TypeError):
805            isinstance(1, Final[int])
806        with self.assertRaises(TypeError):
807            issubclass(int, Final)
808
809
810class RequiredTests(BaseTestCase):
811
812    def test_basics(self):
813        if not TYPING_3_11_0:
814            with self.assertRaises(TypeError):
815                Required[1]
816        with self.assertRaises(TypeError):
817            Required[int, str]
818        with self.assertRaises(TypeError):
819            Required[int][str]
820
821    def test_repr(self):
822        if hasattr(typing, 'Required'):
823            mod_name = 'typing'
824        else:
825            mod_name = 'typing_extensions'
826        self.assertEqual(repr(Required), f'{mod_name}.Required')
827        cv = Required[int]
828        self.assertEqual(repr(cv), f'{mod_name}.Required[int]')
829        cv = Required[Employee]
830        self.assertEqual(repr(cv), f'{mod_name}.Required[{__name__}.Employee]')
831
832    def test_cannot_subclass(self):
833        with self.assertRaises(TypeError):
834            class C(type(Required)):
835                pass
836        with self.assertRaises(TypeError):
837            class D(type(Required[int])):
838                pass
839
840    def test_cannot_init(self):
841        with self.assertRaises(TypeError):
842            Required()
843        with self.assertRaises(TypeError):
844            type(Required)()
845        with self.assertRaises(TypeError):
846            type(Required[Optional[int]])()
847
848    def test_no_isinstance(self):
849        with self.assertRaises(TypeError):
850            isinstance(1, Required[int])
851        with self.assertRaises(TypeError):
852            issubclass(int, Required)
853
854
855class NotRequiredTests(BaseTestCase):
856
857    def test_basics(self):
858        if not TYPING_3_11_0:
859            with self.assertRaises(TypeError):
860                NotRequired[1]
861        with self.assertRaises(TypeError):
862            NotRequired[int, str]
863        with self.assertRaises(TypeError):
864            NotRequired[int][str]
865
866    def test_repr(self):
867        if hasattr(typing, 'NotRequired'):
868            mod_name = 'typing'
869        else:
870            mod_name = 'typing_extensions'
871        self.assertEqual(repr(NotRequired), f'{mod_name}.NotRequired')
872        cv = NotRequired[int]
873        self.assertEqual(repr(cv), f'{mod_name}.NotRequired[int]')
874        cv = NotRequired[Employee]
875        self.assertEqual(repr(cv), f'{mod_name}.NotRequired[{ __name__}.Employee]')
876
877    def test_cannot_subclass(self):
878        with self.assertRaises(TypeError):
879            class C(type(NotRequired)):
880                pass
881        with self.assertRaises(TypeError):
882            class D(type(NotRequired[int])):
883                pass
884
885    def test_cannot_init(self):
886        with self.assertRaises(TypeError):
887            NotRequired()
888        with self.assertRaises(TypeError):
889            type(NotRequired)()
890        with self.assertRaises(TypeError):
891            type(NotRequired[Optional[int]])()
892
893    def test_no_isinstance(self):
894        with self.assertRaises(TypeError):
895            isinstance(1, NotRequired[int])
896        with self.assertRaises(TypeError):
897            issubclass(int, NotRequired)
898
899
900class IntVarTests(BaseTestCase):
901    def test_valid(self):
902        IntVar("T_ints")
903
904    def test_invalid(self):
905        with self.assertRaises(TypeError):
906            IntVar("T_ints", int)
907        with self.assertRaises(TypeError):
908            IntVar("T_ints", bound=int)
909        with self.assertRaises(TypeError):
910            IntVar("T_ints", covariant=True)
911
912
913class LiteralTests(BaseTestCase):
914    def test_basics(self):
915        Literal[1]
916        Literal[1, 2, 3]
917        Literal["x", "y", "z"]
918        Literal[None]
919
920    def test_enum(self):
921        import enum
922        class My(enum.Enum):
923            A = 'A'
924
925        self.assertEqual(Literal[My.A].__args__, (My.A,))
926
927    def test_illegal_parameters_do_not_raise_runtime_errors(self):
928        # Type checkers should reject these types, but we do not
929        # raise errors at runtime to maintain maximum flexibility
930        Literal[int]
931        Literal[Literal[1, 2], Literal[4, 5]]
932        Literal[3j + 2, ..., ()]
933        Literal[b"foo", "bar"]
934        Literal[{"foo": 3, "bar": 4}]
935        Literal[T]
936
937    def test_literals_inside_other_types(self):
938        List[Literal[1, 2, 3]]
939        List[Literal[("foo", "bar", "baz")]]
940
941    def test_repr(self):
942        # we backport various bugfixes that were added in 3.10.1 and earlier
943        if sys.version_info >= (3, 10, 1):
944            mod_name = 'typing'
945        else:
946            mod_name = 'typing_extensions'
947        self.assertEqual(repr(Literal[1]), mod_name + ".Literal[1]")
948        self.assertEqual(repr(Literal[1, True, "foo"]), mod_name + ".Literal[1, True, 'foo']")
949        self.assertEqual(repr(Literal[int]), mod_name + ".Literal[int]")
950        self.assertEqual(repr(Literal), mod_name + ".Literal")
951        self.assertEqual(repr(Literal[None]), mod_name + ".Literal[None]")
952        self.assertEqual(repr(Literal[1, 2, 3, 3]), mod_name + ".Literal[1, 2, 3]")
953
954    def test_cannot_init(self):
955        with self.assertRaises(TypeError):
956            Literal()
957        with self.assertRaises(TypeError):
958            Literal[1]()
959        with self.assertRaises(TypeError):
960            type(Literal)()
961        with self.assertRaises(TypeError):
962            type(Literal[1])()
963
964    def test_no_isinstance_or_issubclass(self):
965        with self.assertRaises(TypeError):
966            isinstance(1, Literal[1])
967        with self.assertRaises(TypeError):
968            isinstance(int, Literal[1])
969        with self.assertRaises(TypeError):
970            issubclass(1, Literal[1])
971        with self.assertRaises(TypeError):
972            issubclass(int, Literal[1])
973
974    def test_no_subclassing(self):
975        with self.assertRaises(TypeError):
976            class Foo(Literal[1]): pass
977        with self.assertRaises(TypeError):
978            class Bar(Literal): pass
979
980    def test_no_multiple_subscripts(self):
981        with self.assertRaises(TypeError):
982            Literal[1][1]
983
984    def test_equal(self):
985        self.assertNotEqual(Literal[0], Literal[False])
986        self.assertNotEqual(Literal[True], Literal[1])
987        self.assertNotEqual(Literal[1], Literal[2])
988        self.assertNotEqual(Literal[1, True], Literal[1])
989        self.assertNotEqual(Literal[1, True], Literal[1, 1])
990        self.assertNotEqual(Literal[1, 2], Literal[True, 2])
991        self.assertEqual(Literal[1], Literal[1])
992        self.assertEqual(Literal[1, 2], Literal[2, 1])
993        self.assertEqual(Literal[1, 2, 3], Literal[1, 2, 3, 3])
994
995    def test_hash(self):
996        self.assertEqual(hash(Literal[1]), hash(Literal[1]))
997        self.assertEqual(hash(Literal[1, 2]), hash(Literal[2, 1]))
998        self.assertEqual(hash(Literal[1, 2, 3]), hash(Literal[1, 2, 3, 3]))
999
1000    def test_args(self):
1001        self.assertEqual(Literal[1, 2, 3].__args__, (1, 2, 3))
1002        self.assertEqual(Literal[1, 2, 3, 3].__args__, (1, 2, 3))
1003        self.assertEqual(Literal[1, Literal[2], Literal[3, 4]].__args__, (1, 2, 3, 4))
1004        # Mutable arguments will not be deduplicated
1005        self.assertEqual(Literal[[], []].__args__, ([], []))
1006
1007    def test_union_of_literals(self):
1008        self.assertEqual(Union[Literal[1], Literal[2]].__args__,
1009                         (Literal[1], Literal[2]))
1010        self.assertEqual(Union[Literal[1], Literal[1]],
1011                         Literal[1])
1012
1013        self.assertEqual(Union[Literal[False], Literal[0]].__args__,
1014                         (Literal[False], Literal[0]))
1015        self.assertEqual(Union[Literal[True], Literal[1]].__args__,
1016                         (Literal[True], Literal[1]))
1017
1018        import enum
1019        class Ints(enum.IntEnum):
1020            A = 0
1021            B = 1
1022
1023        self.assertEqual(Union[Literal[Ints.A], Literal[Ints.B]].__args__,
1024                         (Literal[Ints.A], Literal[Ints.B]))
1025
1026        self.assertEqual(Union[Literal[Ints.A], Literal[Ints.A]],
1027                         Literal[Ints.A])
1028        self.assertEqual(Union[Literal[Ints.B], Literal[Ints.B]],
1029                         Literal[Ints.B])
1030
1031        self.assertEqual(Union[Literal[0], Literal[Ints.A], Literal[False]].__args__,
1032                         (Literal[0], Literal[Ints.A], Literal[False]))
1033        self.assertEqual(Union[Literal[1], Literal[Ints.B], Literal[True]].__args__,
1034                         (Literal[1], Literal[Ints.B], Literal[True]))
1035
1036    @skipUnless(TYPING_3_10_0, "Python 3.10+ required")
1037    def test_or_type_operator_with_Literal(self):
1038        self.assertEqual((Literal[1] | Literal[2]).__args__,
1039                         (Literal[1], Literal[2]))
1040
1041        self.assertEqual((Literal[0] | Literal[False]).__args__,
1042                         (Literal[0], Literal[False]))
1043        self.assertEqual((Literal[1] | Literal[True]).__args__,
1044                         (Literal[1], Literal[True]))
1045
1046        self.assertEqual(Literal[1] | Literal[1], Literal[1])
1047        self.assertEqual(Literal['a'] | Literal['a'], Literal['a'])
1048
1049        import enum
1050        class Ints(enum.IntEnum):
1051            A = 0
1052            B = 1
1053
1054        self.assertEqual(Literal[Ints.A] | Literal[Ints.A], Literal[Ints.A])
1055        self.assertEqual(Literal[Ints.B] | Literal[Ints.B], Literal[Ints.B])
1056
1057        self.assertEqual((Literal[Ints.B] | Literal[Ints.A]).__args__,
1058                         (Literal[Ints.B], Literal[Ints.A]))
1059
1060        self.assertEqual((Literal[0] | Literal[Ints.A]).__args__,
1061                         (Literal[0], Literal[Ints.A]))
1062        self.assertEqual((Literal[1] | Literal[Ints.B]).__args__,
1063                         (Literal[1], Literal[Ints.B]))
1064
1065    def test_flatten(self):
1066        l1 = Literal[Literal[1], Literal[2], Literal[3]]
1067        l2 = Literal[Literal[1, 2], 3]
1068        l3 = Literal[Literal[1, 2, 3]]
1069        for lit in l1, l2, l3:
1070            self.assertEqual(lit, Literal[1, 2, 3])
1071            self.assertEqual(lit.__args__, (1, 2, 3))
1072
1073    def test_does_not_flatten_enum(self):
1074        import enum
1075        class Ints(enum.IntEnum):
1076            A = 1
1077            B = 2
1078
1079        literal = Literal[
1080            Literal[Ints.A],
1081            Literal[Ints.B],
1082            Literal[1],
1083            Literal[2],
1084        ]
1085        self.assertEqual(literal.__args__, (Ints.A, Ints.B, 1, 2))
1086
1087    def test_caching_of_Literal_respects_type(self):
1088        self.assertIs(type(Literal[1].__args__[0]), int)
1089        self.assertIs(type(Literal[True].__args__[0]), bool)
1090
1091
1092class MethodHolder:
1093    @classmethod
1094    def clsmethod(cls): ...
1095    @staticmethod
1096    def stmethod(): ...
1097    def method(self): ...
1098
1099
1100if TYPING_3_11_0:
1101    registry_holder = typing
1102else:
1103    registry_holder = typing_extensions
1104
1105
1106class OverloadTests(BaseTestCase):
1107
1108    def test_overload_fails(self):
1109        with self.assertRaises(RuntimeError):
1110
1111            @overload
1112            def blah():
1113                pass
1114
1115            blah()
1116
1117    def test_overload_succeeds(self):
1118        @overload
1119        def blah():
1120            pass
1121
1122        def blah():
1123            pass
1124
1125        blah()
1126
1127    @skipIf(
1128        sys.implementation.name == "pypy",
1129        "sum() and print() are not compiled in pypy"
1130    )
1131    @patch(
1132        f"{registry_holder.__name__}._overload_registry",
1133        defaultdict(lambda: defaultdict(dict))
1134    )
1135    def test_overload_on_compiled_functions(self):
1136        registry = registry_holder._overload_registry
1137        # The registry starts out empty:
1138        self.assertEqual(registry, {})
1139
1140        # This should just not fail:
1141        overload(sum)
1142        overload(print)
1143
1144        # No overloads are recorded:
1145        self.assertEqual(get_overloads(sum), [])
1146        self.assertEqual(get_overloads(print), [])
1147
1148    def set_up_overloads(self):
1149        def blah():
1150            pass
1151
1152        overload1 = blah
1153        overload(blah)
1154
1155        def blah():
1156            pass
1157
1158        overload2 = blah
1159        overload(blah)
1160
1161        def blah():
1162            pass
1163
1164        return blah, [overload1, overload2]
1165
1166    # Make sure we don't clear the global overload registry
1167    @patch(
1168        f"{registry_holder.__name__}._overload_registry",
1169        defaultdict(lambda: defaultdict(dict))
1170    )
1171    def test_overload_registry(self):
1172        registry = registry_holder._overload_registry
1173        # The registry starts out empty
1174        self.assertEqual(registry, {})
1175
1176        impl, overloads = self.set_up_overloads()
1177        self.assertNotEqual(registry, {})
1178        self.assertEqual(list(get_overloads(impl)), overloads)
1179
1180        def some_other_func(): pass
1181        overload(some_other_func)
1182        other_overload = some_other_func
1183        def some_other_func(): pass
1184        self.assertEqual(list(get_overloads(some_other_func)), [other_overload])
1185        # Unrelated function still has no overloads:
1186        def not_overloaded(): pass
1187        self.assertEqual(list(get_overloads(not_overloaded)), [])
1188
1189        # Make sure that after we clear all overloads, the registry is
1190        # completely empty.
1191        clear_overloads()
1192        self.assertEqual(registry, {})
1193        self.assertEqual(get_overloads(impl), [])
1194
1195        # Querying a function with no overloads shouldn't change the registry.
1196        def the_only_one(): pass
1197        self.assertEqual(get_overloads(the_only_one), [])
1198        self.assertEqual(registry, {})
1199
1200    def test_overload_registry_repeated(self):
1201        for _ in range(2):
1202            impl, overloads = self.set_up_overloads()
1203
1204            self.assertEqual(list(get_overloads(impl)), overloads)
1205
1206
1207class AssertTypeTests(BaseTestCase):
1208
1209    def test_basics(self):
1210        arg = 42
1211        self.assertIs(assert_type(arg, int), arg)
1212        self.assertIs(assert_type(arg, Union[str, float]), arg)
1213        self.assertIs(assert_type(arg, AnyStr), arg)
1214        self.assertIs(assert_type(arg, None), arg)
1215
1216    def test_errors(self):
1217        # Bogus calls are not expected to fail.
1218        arg = 42
1219        self.assertIs(assert_type(arg, 42), arg)
1220        self.assertIs(assert_type(arg, 'hello'), arg)
1221
1222
1223T_a = TypeVar('T_a')
1224
1225class AwaitableWrapper(Awaitable[T_a]):
1226
1227    def __init__(self, value):
1228        self.value = value
1229
1230    def __await__(self) -> typing.Iterator[T_a]:
1231        yield
1232        return self.value
1233
1234class AsyncIteratorWrapper(AsyncIterator[T_a]):
1235
1236    def __init__(self, value: Iterable[T_a]):
1237        self.value = value
1238
1239    def __aiter__(self) -> AsyncIterator[T_a]:
1240        return self
1241
1242    async def __anext__(self) -> T_a:
1243        data = await self.value
1244        if data:
1245            return data
1246        else:
1247            raise StopAsyncIteration
1248
1249class ACM:
1250    async def __aenter__(self) -> int:
1251        return 42
1252
1253    async def __aexit__(self, etype, eval, tb):
1254        return None
1255
1256
1257class A:
1258    y: float
1259class B(A):
1260    x: ClassVar[Optional['B']] = None
1261    y: int
1262    b: int
1263class CSub(B):
1264    z: ClassVar['CSub'] = B()
1265class G(Generic[T]):
1266    lst: ClassVar[List[T]] = []
1267
1268class Loop:
1269    attr: Final['Loop']
1270
1271class NoneAndForward:
1272    parent: 'NoneAndForward'
1273    meaning: None
1274
1275class XRepr(NamedTuple):
1276    x: int
1277    y: int = 1
1278
1279    def __str__(self):
1280        return f'{self.x} -> {self.y}'
1281
1282    def __add__(self, other):
1283        return 0
1284
1285@runtime_checkable
1286class HasCallProtocol(Protocol):
1287    __call__: typing.Callable
1288
1289
1290async def g_with(am: AsyncContextManager[int]):
1291    x: int
1292    async with am as x:
1293        return x
1294
1295try:
1296    g_with(ACM()).send(None)
1297except StopIteration as e:
1298    assert e.args[0] == 42
1299
1300Label = TypedDict('Label', [('label', str)])
1301
1302class Point2D(TypedDict):
1303    x: int
1304    y: int
1305
1306class Point2Dor3D(Point2D, total=False):
1307    z: int
1308
1309class LabelPoint2D(Point2D, Label): ...
1310
1311class Options(TypedDict, total=False):
1312    log_level: int
1313    log_path: str
1314
1315class BaseAnimal(TypedDict):
1316    name: str
1317
1318class Animal(BaseAnimal, total=False):
1319    voice: str
1320    tail: bool
1321
1322class Cat(Animal):
1323    fur_color: str
1324
1325class TotalMovie(TypedDict):
1326    title: str
1327    year: NotRequired[int]
1328
1329class NontotalMovie(TypedDict, total=False):
1330    title: Required[str]
1331    year: int
1332
1333class ParentNontotalMovie(TypedDict, total=False):
1334    title: Required[str]
1335
1336class ChildTotalMovie(ParentNontotalMovie):
1337    year: NotRequired[int]
1338
1339class ParentDeeplyAnnotatedMovie(TypedDict):
1340    title: Annotated[Annotated[Required[str], "foobar"], "another level"]
1341
1342class ChildDeeplyAnnotatedMovie(ParentDeeplyAnnotatedMovie):
1343    year: NotRequired[Annotated[int, 2000]]
1344
1345class AnnotatedMovie(TypedDict):
1346    title: Annotated[Required[str], "foobar"]
1347    year: NotRequired[Annotated[int, 2000]]
1348
1349class WeirdlyQuotedMovie(TypedDict):
1350    title: Annotated['Annotated[Required[str], "foobar"]', "another level"]
1351    year: NotRequired['Annotated[int, 2000]']
1352
1353
1354gth = get_type_hints
1355
1356
1357class GetTypeHintTests(BaseTestCase):
1358    @classmethod
1359    def setUpClass(cls):
1360        with tempfile.TemporaryDirectory() as tempdir:
1361            sys.path.append(tempdir)
1362            Path(tempdir, "ann_module.py").write_text(ANN_MODULE_SOURCE)
1363            Path(tempdir, "ann_module2.py").write_text(ANN_MODULE_2_SOURCE)
1364            Path(tempdir, "ann_module3.py").write_text(ANN_MODULE_3_SOURCE)
1365            cls.ann_module = importlib.import_module("ann_module")
1366            cls.ann_module2 = importlib.import_module("ann_module2")
1367            cls.ann_module3 = importlib.import_module("ann_module3")
1368        sys.path.pop()
1369
1370    @classmethod
1371    def tearDownClass(cls):
1372        for modname in "ann_module", "ann_module2", "ann_module3":
1373            delattr(cls, modname)
1374            del sys.modules[modname]
1375
1376    def test_get_type_hints_modules(self):
1377        if sys.version_info >= (3, 14):
1378            ann_module_type_hints = {'f': Tuple[int, int], 'x': int, 'y': str}
1379        else:
1380            ann_module_type_hints = {1: 2, 'f': Tuple[int, int], 'x': int, 'y': str}
1381        self.assertEqual(gth(self.ann_module), ann_module_type_hints)
1382        self.assertEqual(gth(self.ann_module2), {})
1383        self.assertEqual(gth(self.ann_module3), {})
1384
1385    def test_get_type_hints_classes(self):
1386        self.assertEqual(gth(self.ann_module.C, self.ann_module.__dict__),
1387                         {'y': Optional[self.ann_module.C]})
1388        self.assertIsInstance(gth(self.ann_module.j_class), dict)
1389        if sys.version_info >= (3, 14):
1390            self.assertEqual(gth(self.ann_module.M), {'o': type})
1391        else:
1392            self.assertEqual(gth(self.ann_module.M), {'123': 123, 'o': type})
1393        self.assertEqual(gth(self.ann_module.D),
1394                         {'j': str, 'k': str, 'y': Optional[self.ann_module.C]})
1395        self.assertEqual(gth(self.ann_module.Y), {'z': int})
1396        self.assertEqual(gth(self.ann_module.h_class),
1397                         {'y': Optional[self.ann_module.C]})
1398        self.assertEqual(gth(self.ann_module.S), {'x': str, 'y': str})
1399        self.assertEqual(gth(self.ann_module.foo), {'x': int})
1400        self.assertEqual(gth(NoneAndForward, globals()),
1401                         {'parent': NoneAndForward, 'meaning': type(None)})
1402
1403    def test_respect_no_type_check(self):
1404        @no_type_check
1405        class NoTpCheck:
1406            class Inn:
1407                def __init__(self, x: 'not a type'): ...  # noqa: F722  # (yes, there's a syntax error in this annotation, that's the point)
1408        self.assertTrue(NoTpCheck.__no_type_check__)
1409        self.assertTrue(NoTpCheck.Inn.__init__.__no_type_check__)
1410        self.assertEqual(gth(self.ann_module2.NTC.meth), {})
1411        class ABase(Generic[T]):
1412            def meth(x: int): ...
1413        @no_type_check
1414        class Der(ABase): ...
1415        self.assertEqual(gth(ABase.meth), {'x': int})
1416
1417    def test_get_type_hints_ClassVar(self):
1418        self.assertEqual(gth(self.ann_module2.CV, self.ann_module2.__dict__),
1419                         {'var': ClassVar[self.ann_module2.CV]})
1420        self.assertEqual(gth(B, globals()),
1421                         {'y': int, 'x': ClassVar[Optional[B]], 'b': int})
1422        self.assertEqual(gth(CSub, globals()),
1423                         {'z': ClassVar[CSub], 'y': int, 'b': int,
1424                          'x': ClassVar[Optional[B]]})
1425        self.assertEqual(gth(G), {'lst': ClassVar[List[T]]})
1426
1427    def test_final_forward_ref(self):
1428        self.assertEqual(gth(Loop, globals())['attr'], Final[Loop])
1429        self.assertNotEqual(gth(Loop, globals())['attr'], Final[int])
1430        self.assertNotEqual(gth(Loop, globals())['attr'], Final)
1431
1432
1433class GetUtilitiesTestCase(TestCase):
1434    def test_get_origin(self):
1435        T = TypeVar('T')
1436        P = ParamSpec('P')
1437        Ts = TypeVarTuple('Ts')
1438        class C(Generic[T]): pass
1439        self.assertIs(get_origin(C[int]), C)
1440        self.assertIs(get_origin(C[T]), C)
1441        self.assertIs(get_origin(int), None)
1442        self.assertIs(get_origin(ClassVar[int]), ClassVar)
1443        self.assertIs(get_origin(Union[int, str]), Union)
1444        self.assertIs(get_origin(Literal[42, 43]), Literal)
1445        self.assertIs(get_origin(Final[List[int]]), Final)
1446        self.assertIs(get_origin(Generic), Generic)
1447        self.assertIs(get_origin(Generic[T]), Generic)
1448        self.assertIs(get_origin(List[Tuple[T, T]][int]), list)
1449        self.assertIs(get_origin(Annotated[T, 'thing']), Annotated)
1450        self.assertIs(get_origin(List), list)
1451        self.assertIs(get_origin(Tuple), tuple)
1452        self.assertIs(get_origin(Callable), collections.abc.Callable)
1453        if sys.version_info >= (3, 9):
1454            self.assertIs(get_origin(list[int]), list)
1455        self.assertIs(get_origin(list), None)
1456        self.assertIs(get_origin(P.args), P)
1457        self.assertIs(get_origin(P.kwargs), P)
1458        self.assertIs(get_origin(Required[int]), Required)
1459        self.assertIs(get_origin(NotRequired[int]), NotRequired)
1460        self.assertIs(get_origin(Unpack[Ts]), Unpack)
1461        self.assertIs(get_origin(Unpack), None)
1462
1463    def test_get_args(self):
1464        T = TypeVar('T')
1465        Ts = TypeVarTuple('Ts')
1466        class C(Generic[T]): pass
1467        self.assertEqual(get_args(C[int]), (int,))
1468        self.assertEqual(get_args(C[T]), (T,))
1469        self.assertEqual(get_args(int), ())
1470        self.assertEqual(get_args(ClassVar[int]), (int,))
1471        self.assertEqual(get_args(Union[int, str]), (int, str))
1472        self.assertEqual(get_args(Literal[42, 43]), (42, 43))
1473        self.assertEqual(get_args(Final[List[int]]), (List[int],))
1474        self.assertEqual(get_args(Union[int, Tuple[T, int]][str]),
1475                         (int, Tuple[str, int]))
1476        self.assertEqual(get_args(typing.Dict[int, Tuple[T, T]][Optional[int]]),
1477                         (int, Tuple[Optional[int], Optional[int]]))
1478        self.assertEqual(get_args(Callable[[], T][int]), ([], int))
1479        self.assertEqual(get_args(Callable[..., int]), (..., int))
1480        self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]),
1481                         (int, Callable[[Tuple[T, ...]], str]))
1482        self.assertEqual(get_args(Tuple[int, ...]), (int, ...))
1483        if TYPING_3_11_0:
1484            self.assertEqual(get_args(Tuple[()]), ())
1485        else:
1486            self.assertEqual(get_args(Tuple[()]), ((),))
1487        self.assertEqual(get_args(Annotated[T, 'one', 2, ['three']]), (T, 'one', 2, ['three']))
1488        self.assertEqual(get_args(List), ())
1489        self.assertEqual(get_args(Tuple), ())
1490        self.assertEqual(get_args(Callable), ())
1491        if sys.version_info >= (3, 9):
1492            self.assertEqual(get_args(list[int]), (int,))
1493        self.assertEqual(get_args(list), ())
1494        if sys.version_info >= (3, 9):
1495            # Support Python versions with and without the fix for
1496            # https://bugs.python.org/issue42195
1497            # The first variant is for 3.9.2+, the second for 3.9.0 and 1
1498            self.assertIn(get_args(collections.abc.Callable[[int], str]),
1499                          (([int], str), ([[int]], str)))
1500            self.assertIn(get_args(collections.abc.Callable[[], str]),
1501                          (([], str), ([[]], str)))
1502            self.assertEqual(get_args(collections.abc.Callable[..., str]), (..., str))
1503        P = ParamSpec('P')
1504        # In 3.9 and lower we use typing_extensions's hacky implementation
1505        # of ParamSpec, which gets incorrectly wrapped in a list
1506        self.assertIn(get_args(Callable[P, int]), [(P, int), ([P], int)])
1507        self.assertEqual(get_args(Callable[Concatenate[int, P], int]),
1508                         (Concatenate[int, P], int))
1509        self.assertEqual(get_args(Required[int]), (int,))
1510        self.assertEqual(get_args(NotRequired[int]), (int,))
1511        self.assertEqual(get_args(Unpack[Ts]), (Ts,))
1512        self.assertEqual(get_args(Unpack), ())
1513
1514
1515class CollectionsAbcTests(BaseTestCase):
1516
1517    def test_isinstance_collections(self):
1518        self.assertNotIsInstance(1, collections.abc.Mapping)
1519        self.assertNotIsInstance(1, collections.abc.Iterable)
1520        self.assertNotIsInstance(1, collections.abc.Container)
1521        self.assertNotIsInstance(1, collections.abc.Sized)
1522        with self.assertRaises(TypeError):
1523            isinstance(collections.deque(), typing_extensions.Deque[int])
1524        with self.assertRaises(TypeError):
1525            issubclass(collections.Counter, typing_extensions.Counter[str])
1526
1527    def test_awaitable(self):
1528        async def foo() -> typing_extensions.Awaitable[int]:
1529            return await AwaitableWrapper(42)
1530
1531        g = foo()
1532        self.assertIsInstance(g, typing_extensions.Awaitable)
1533        self.assertNotIsInstance(foo, typing_extensions.Awaitable)
1534        g.send(None)  # Run foo() till completion, to avoid warning.
1535
1536    def test_coroutine(self):
1537        async def foo():
1538            return
1539
1540        g = foo()
1541        self.assertIsInstance(g, typing_extensions.Coroutine)
1542        with self.assertRaises(TypeError):
1543            isinstance(g, typing_extensions.Coroutine[int])
1544        self.assertNotIsInstance(foo, typing_extensions.Coroutine)
1545        try:
1546            g.send(None)
1547        except StopIteration:
1548            pass
1549
1550    def test_async_iterable(self):
1551        base_it: Iterator[int] = range(10)
1552        it = AsyncIteratorWrapper(base_it)
1553        self.assertIsInstance(it, typing_extensions.AsyncIterable)
1554        self.assertIsInstance(it, typing_extensions.AsyncIterable)
1555        self.assertNotIsInstance(42, typing_extensions.AsyncIterable)
1556
1557    def test_async_iterator(self):
1558        base_it: Iterator[int] = range(10)
1559        it = AsyncIteratorWrapper(base_it)
1560        self.assertIsInstance(it, typing_extensions.AsyncIterator)
1561        self.assertNotIsInstance(42, typing_extensions.AsyncIterator)
1562
1563    def test_deque(self):
1564        self.assertIsSubclass(collections.deque, typing_extensions.Deque)
1565        class MyDeque(typing_extensions.Deque[int]): ...
1566        self.assertIsInstance(MyDeque(), collections.deque)
1567
1568    def test_counter(self):
1569        self.assertIsSubclass(collections.Counter, typing_extensions.Counter)
1570
1571    def test_defaultdict_instantiation(self):
1572        self.assertIs(
1573            type(typing_extensions.DefaultDict()),
1574            collections.defaultdict)
1575        self.assertIs(
1576            type(typing_extensions.DefaultDict[KT, VT]()),
1577            collections.defaultdict)
1578        self.assertIs(
1579            type(typing_extensions.DefaultDict[str, int]()),
1580            collections.defaultdict)
1581
1582    def test_defaultdict_subclass(self):
1583
1584        class MyDefDict(typing_extensions.DefaultDict[str, int]):
1585            pass
1586
1587        dd = MyDefDict()
1588        self.assertIsInstance(dd, MyDefDict)
1589
1590        self.assertIsSubclass(MyDefDict, collections.defaultdict)
1591        self.assertNotIsSubclass(collections.defaultdict, MyDefDict)
1592
1593    def test_ordereddict_instantiation(self):
1594        self.assertIs(
1595            type(typing_extensions.OrderedDict()),
1596            collections.OrderedDict)
1597        self.assertIs(
1598            type(typing_extensions.OrderedDict[KT, VT]()),
1599            collections.OrderedDict)
1600        self.assertIs(
1601            type(typing_extensions.OrderedDict[str, int]()),
1602            collections.OrderedDict)
1603
1604    def test_ordereddict_subclass(self):
1605
1606        class MyOrdDict(typing_extensions.OrderedDict[str, int]):
1607            pass
1608
1609        od = MyOrdDict()
1610        self.assertIsInstance(od, MyOrdDict)
1611
1612        self.assertIsSubclass(MyOrdDict, collections.OrderedDict)
1613        self.assertNotIsSubclass(collections.OrderedDict, MyOrdDict)
1614
1615    def test_chainmap_instantiation(self):
1616        self.assertIs(type(typing_extensions.ChainMap()), collections.ChainMap)
1617        self.assertIs(type(typing_extensions.ChainMap[KT, VT]()), collections.ChainMap)
1618        self.assertIs(type(typing_extensions.ChainMap[str, int]()), collections.ChainMap)
1619        class CM(typing_extensions.ChainMap[KT, VT]): ...
1620        self.assertIs(type(CM[int, str]()), CM)
1621
1622    def test_chainmap_subclass(self):
1623
1624        class MyChainMap(typing_extensions.ChainMap[str, int]):
1625            pass
1626
1627        cm = MyChainMap()
1628        self.assertIsInstance(cm, MyChainMap)
1629
1630        self.assertIsSubclass(MyChainMap, collections.ChainMap)
1631        self.assertNotIsSubclass(collections.ChainMap, MyChainMap)
1632
1633    def test_deque_instantiation(self):
1634        self.assertIs(type(typing_extensions.Deque()), collections.deque)
1635        self.assertIs(type(typing_extensions.Deque[T]()), collections.deque)
1636        self.assertIs(type(typing_extensions.Deque[int]()), collections.deque)
1637        class D(typing_extensions.Deque[T]): ...
1638        self.assertIs(type(D[int]()), D)
1639
1640    def test_counter_instantiation(self):
1641        self.assertIs(type(typing_extensions.Counter()), collections.Counter)
1642        self.assertIs(type(typing_extensions.Counter[T]()), collections.Counter)
1643        self.assertIs(type(typing_extensions.Counter[int]()), collections.Counter)
1644        class C(typing_extensions.Counter[T]): ...
1645        self.assertIs(type(C[int]()), C)
1646        self.assertEqual(C.__bases__, (collections.Counter, typing.Generic))
1647
1648    def test_counter_subclass_instantiation(self):
1649
1650        class MyCounter(typing_extensions.Counter[int]):
1651            pass
1652
1653        d = MyCounter()
1654        self.assertIsInstance(d, MyCounter)
1655        self.assertIsInstance(d, collections.Counter)
1656        self.assertIsInstance(d, typing_extensions.Counter)
1657
1658
1659# These are a separate TestCase class,
1660# as (unlike most collections.abc aliases in typing_extensions),
1661# these are reimplemented on Python <=3.12 so that we can provide
1662# default values for the second and third parameters
1663class GeneratorTests(BaseTestCase):
1664
1665    def test_generator_basics(self):
1666        def foo():
1667            yield 42
1668        g = foo()
1669
1670        self.assertIsInstance(g, typing_extensions.Generator)
1671        self.assertNotIsInstance(foo, typing_extensions.Generator)
1672        self.assertIsSubclass(type(g), typing_extensions.Generator)
1673        self.assertNotIsSubclass(type(foo), typing_extensions.Generator)
1674
1675        parameterized = typing_extensions.Generator[int, str, None]
1676        with self.assertRaises(TypeError):
1677            isinstance(g, parameterized)
1678        with self.assertRaises(TypeError):
1679            issubclass(type(g), parameterized)
1680
1681    def test_generator_default(self):
1682        g1 = typing_extensions.Generator[int]
1683        g2 = typing_extensions.Generator[int, None, None]
1684        self.assertEqual(get_args(g1), (int, type(None), type(None)))
1685        self.assertEqual(get_args(g1), get_args(g2))
1686
1687        g3 = typing_extensions.Generator[int, float]
1688        g4 = typing_extensions.Generator[int, float, None]
1689        self.assertEqual(get_args(g3), (int, float, type(None)))
1690        self.assertEqual(get_args(g3), get_args(g4))
1691
1692    def test_no_generator_instantiation(self):
1693        with self.assertRaises(TypeError):
1694            typing_extensions.Generator()
1695        with self.assertRaises(TypeError):
1696            typing_extensions.Generator[T, T, T]()
1697        with self.assertRaises(TypeError):
1698            typing_extensions.Generator[int, int, int]()
1699
1700    def test_subclassing_generator(self):
1701        class G(typing_extensions.Generator[int, int, None]):
1702            def send(self, value):
1703                pass
1704            def throw(self, typ, val=None, tb=None):
1705                pass
1706
1707        def g(): yield 0
1708
1709        self.assertIsSubclass(G, typing_extensions.Generator)
1710        self.assertIsSubclass(G, typing_extensions.Iterable)
1711        self.assertIsSubclass(G, collections.abc.Generator)
1712        self.assertIsSubclass(G, collections.abc.Iterable)
1713        self.assertNotIsSubclass(type(g), G)
1714
1715        instance = G()
1716        self.assertIsInstance(instance, typing_extensions.Generator)
1717        self.assertIsInstance(instance, typing_extensions.Iterable)
1718        self.assertIsInstance(instance, collections.abc.Generator)
1719        self.assertIsInstance(instance, collections.abc.Iterable)
1720        self.assertNotIsInstance(type(g), G)
1721        self.assertNotIsInstance(g, G)
1722
1723    def test_async_generator_basics(self):
1724        async def f():
1725            yield 42
1726        g = f()
1727
1728        self.assertIsInstance(g, typing_extensions.AsyncGenerator)
1729        self.assertIsSubclass(type(g), typing_extensions.AsyncGenerator)
1730        self.assertNotIsInstance(f, typing_extensions.AsyncGenerator)
1731        self.assertNotIsSubclass(type(f), typing_extensions.AsyncGenerator)
1732
1733        parameterized = typing_extensions.AsyncGenerator[int, str]
1734        with self.assertRaises(TypeError):
1735            isinstance(g, parameterized)
1736        with self.assertRaises(TypeError):
1737            issubclass(type(g), parameterized)
1738
1739    def test_async_generator_default(self):
1740        ag1 = typing_extensions.AsyncGenerator[int]
1741        ag2 = typing_extensions.AsyncGenerator[int, None]
1742        self.assertEqual(get_args(ag1), (int, type(None)))
1743        self.assertEqual(get_args(ag1), get_args(ag2))
1744
1745    def test_no_async_generator_instantiation(self):
1746        with self.assertRaises(TypeError):
1747            typing_extensions.AsyncGenerator()
1748        with self.assertRaises(TypeError):
1749            typing_extensions.AsyncGenerator[T, T]()
1750        with self.assertRaises(TypeError):
1751            typing_extensions.AsyncGenerator[int, int]()
1752
1753    def test_subclassing_async_generator(self):
1754        class G(typing_extensions.AsyncGenerator[int, int]):
1755            def asend(self, value):
1756                pass
1757            def athrow(self, typ, val=None, tb=None):
1758                pass
1759
1760        async def g(): yield 0
1761
1762        self.assertIsSubclass(G, typing_extensions.AsyncGenerator)
1763        self.assertIsSubclass(G, typing_extensions.AsyncIterable)
1764        self.assertIsSubclass(G, collections.abc.AsyncGenerator)
1765        self.assertIsSubclass(G, collections.abc.AsyncIterable)
1766        self.assertNotIsSubclass(type(g), G)
1767
1768        instance = G()
1769        self.assertIsInstance(instance, typing_extensions.AsyncGenerator)
1770        self.assertIsInstance(instance, typing_extensions.AsyncIterable)
1771        self.assertIsInstance(instance, collections.abc.AsyncGenerator)
1772        self.assertIsInstance(instance, collections.abc.AsyncIterable)
1773        self.assertNotIsInstance(type(g), G)
1774        self.assertNotIsInstance(g, G)
1775
1776    def test_subclassing_subclasshook(self):
1777
1778        class Base(typing_extensions.Generator):
1779            @classmethod
1780            def __subclasshook__(cls, other):
1781                if other.__name__ == 'Foo':
1782                    return True
1783                else:
1784                    return False
1785
1786        class C(Base): ...
1787        class Foo: ...
1788        class Bar: ...
1789        self.assertIsSubclass(Foo, Base)
1790        self.assertIsSubclass(Foo, C)
1791        self.assertNotIsSubclass(Bar, C)
1792
1793    def test_subclassing_register(self):
1794
1795        class A(typing_extensions.Generator): ...
1796        class B(A): ...
1797
1798        class C: ...
1799        A.register(C)
1800        self.assertIsSubclass(C, A)
1801        self.assertNotIsSubclass(C, B)
1802
1803        class D: ...
1804        B.register(D)
1805        self.assertIsSubclass(D, A)
1806        self.assertIsSubclass(D, B)
1807
1808        class M: ...
1809        collections.abc.Generator.register(M)
1810        self.assertIsSubclass(M, typing_extensions.Generator)
1811
1812    def test_collections_as_base(self):
1813
1814        class M(collections.abc.Generator): ...
1815        self.assertIsSubclass(M, typing_extensions.Generator)
1816        self.assertIsSubclass(M, typing_extensions.Iterable)
1817
1818        class S(collections.abc.AsyncGenerator): ...
1819        self.assertIsSubclass(S, typing_extensions.AsyncGenerator)
1820        self.assertIsSubclass(S, typing_extensions.AsyncIterator)
1821
1822        class A(collections.abc.Generator, metaclass=abc.ABCMeta): ...
1823        class B: ...
1824        A.register(B)
1825        self.assertIsSubclass(B, typing_extensions.Generator)
1826
1827    @skipIf(sys.version_info < (3, 10), "PEP 604 has yet to be")
1828    def test_or_and_ror(self):
1829        self.assertEqual(
1830            typing_extensions.Generator | typing_extensions.AsyncGenerator,
1831            Union[typing_extensions.Generator, typing_extensions.AsyncGenerator]
1832        )
1833        self.assertEqual(
1834            typing_extensions.Generator | typing.Deque,
1835            Union[typing_extensions.Generator, typing.Deque]
1836        )
1837
1838
1839class OtherABCTests(BaseTestCase):
1840
1841    def test_contextmanager(self):
1842        @contextlib.contextmanager
1843        def manager():
1844            yield 42
1845
1846        cm = manager()
1847        self.assertIsInstance(cm, typing_extensions.ContextManager)
1848        self.assertNotIsInstance(42, typing_extensions.ContextManager)
1849
1850    def test_contextmanager_type_params(self):
1851        cm1 = typing_extensions.ContextManager[int]
1852        self.assertEqual(get_args(cm1), (int, typing.Optional[bool]))
1853        cm2 = typing_extensions.ContextManager[int, None]
1854        self.assertEqual(get_args(cm2), (int, NoneType))
1855
1856    def test_async_contextmanager(self):
1857        class NotACM:
1858            pass
1859        self.assertIsInstance(ACM(), typing_extensions.AsyncContextManager)
1860        self.assertNotIsInstance(NotACM(), typing_extensions.AsyncContextManager)
1861        @contextlib.contextmanager
1862        def manager():
1863            yield 42
1864
1865        cm = manager()
1866        self.assertNotIsInstance(cm, typing_extensions.AsyncContextManager)
1867        self.assertEqual(
1868            typing_extensions.AsyncContextManager[int].__args__,
1869            (int, typing.Optional[bool])
1870        )
1871        with self.assertRaises(TypeError):
1872            isinstance(42, typing_extensions.AsyncContextManager[int])
1873        with self.assertRaises(TypeError):
1874            typing_extensions.AsyncContextManager[int, str, float]
1875
1876    def test_asynccontextmanager_type_params(self):
1877        cm1 = typing_extensions.AsyncContextManager[int]
1878        self.assertEqual(get_args(cm1), (int, typing.Optional[bool]))
1879        cm2 = typing_extensions.AsyncContextManager[int, None]
1880        self.assertEqual(get_args(cm2), (int, NoneType))
1881
1882
1883class TypeTests(BaseTestCase):
1884
1885    def test_type_basic(self):
1886
1887        class User: pass
1888        class BasicUser(User): pass
1889        class ProUser(User): pass
1890
1891        def new_user(user_class: Type[User]) -> User:
1892            return user_class()
1893
1894        new_user(BasicUser)
1895
1896    def test_type_typevar(self):
1897
1898        class User: pass
1899        class BasicUser(User): pass
1900        class ProUser(User): pass
1901
1902        U = TypeVar('U', bound=User)
1903
1904        def new_user(user_class: Type[U]) -> U:
1905            return user_class()
1906
1907        new_user(BasicUser)
1908
1909    def test_type_optional(self):
1910        A = Optional[Type[BaseException]]
1911
1912        def foo(a: A) -> Optional[BaseException]:
1913            if a is None:
1914                return None
1915            else:
1916                return a()
1917
1918        assert isinstance(foo(KeyboardInterrupt), KeyboardInterrupt)
1919        assert foo(None) is None
1920
1921
1922class NewTypeTests(BaseTestCase):
1923    @classmethod
1924    def setUpClass(cls):
1925        global UserId
1926        UserId = NewType('UserId', int)
1927        cls.UserName = NewType(cls.__qualname__ + '.UserName', str)
1928
1929    @classmethod
1930    def tearDownClass(cls):
1931        global UserId
1932        del UserId
1933        del cls.UserName
1934
1935    def test_basic(self):
1936        self.assertIsInstance(UserId(5), int)
1937        self.assertIsInstance(self.UserName('Joe'), str)
1938        self.assertEqual(UserId(5) + 1, 6)
1939
1940    def test_errors(self):
1941        with self.assertRaises(TypeError):
1942            issubclass(UserId, int)
1943        with self.assertRaises(TypeError):
1944            class D(UserId):
1945                pass
1946
1947    @skipUnless(TYPING_3_10_0, "PEP 604 has yet to be")
1948    def test_or(self):
1949        for cls in (int, self.UserName):
1950            with self.subTest(cls=cls):
1951                self.assertEqual(UserId | cls, Union[UserId, cls])
1952                self.assertEqual(cls | UserId, Union[cls, UserId])
1953
1954                self.assertEqual(get_args(UserId | cls), (UserId, cls))
1955                self.assertEqual(get_args(cls | UserId), (cls, UserId))
1956
1957    def test_special_attrs(self):
1958        self.assertEqual(UserId.__name__, 'UserId')
1959        self.assertEqual(UserId.__qualname__, 'UserId')
1960        self.assertEqual(UserId.__module__, __name__)
1961        self.assertEqual(UserId.__supertype__, int)
1962
1963        UserName = self.UserName
1964        self.assertEqual(UserName.__name__, 'UserName')
1965        self.assertEqual(UserName.__qualname__,
1966                         self.__class__.__qualname__ + '.UserName')
1967        self.assertEqual(UserName.__module__, __name__)
1968        self.assertEqual(UserName.__supertype__, str)
1969
1970    def test_repr(self):
1971        self.assertEqual(repr(UserId), f'{__name__}.UserId')
1972        self.assertEqual(repr(self.UserName),
1973                         f'{__name__}.{self.__class__.__qualname__}.UserName')
1974
1975    def test_pickle(self):
1976        UserAge = NewType('UserAge', float)
1977        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1978            with self.subTest(proto=proto):
1979                pickled = pickle.dumps(UserId, proto)
1980                loaded = pickle.loads(pickled)
1981                self.assertIs(loaded, UserId)
1982
1983                pickled = pickle.dumps(self.UserName, proto)
1984                loaded = pickle.loads(pickled)
1985                self.assertIs(loaded, self.UserName)
1986
1987                with self.assertRaises(pickle.PicklingError):
1988                    pickle.dumps(UserAge, proto)
1989
1990    def test_missing__name__(self):
1991        code = ("import typing_extensions\n"
1992                "NT = typing_extensions.NewType('NT', int)\n"
1993                )
1994        exec(code, {})
1995
1996    def test_error_message_when_subclassing(self):
1997        with self.assertRaisesRegex(
1998            TypeError,
1999            re.escape(
2000                "Cannot subclass an instance of NewType. Perhaps you were looking for: "
2001                "`ProUserId = NewType('ProUserId', UserId)`"
2002            )
2003        ):
2004            class ProUserId(UserId):
2005                ...
2006
2007
2008class Coordinate(Protocol):
2009    x: int
2010    y: int
2011
2012@runtime_checkable
2013class Point(Coordinate, Protocol):
2014    label: str
2015
2016class MyPoint:
2017    x: int
2018    y: int
2019    label: str
2020
2021class XAxis(Protocol):
2022    x: int
2023
2024class YAxis(Protocol):
2025    y: int
2026
2027@runtime_checkable
2028class Position(XAxis, YAxis, Protocol):
2029    pass
2030
2031@runtime_checkable
2032class Proto(Protocol):
2033    attr: int
2034
2035    def meth(self, arg: str) -> int:
2036        ...
2037
2038class Concrete(Proto):
2039    pass
2040
2041class Other:
2042    attr: int = 1
2043
2044    def meth(self, arg: str) -> int:
2045        if arg == 'this':
2046            return 1
2047        return 0
2048
2049class NT(NamedTuple):
2050    x: int
2051    y: int
2052
2053
2054skip_if_py312b1 = skipIf(
2055    sys.version_info == (3, 12, 0, 'beta', 1),
2056    "CPython had bugs in 3.12.0b1"
2057)
2058
2059
2060class ProtocolTests(BaseTestCase):
2061    def test_runtime_alias(self):
2062        self.assertIs(runtime, runtime_checkable)
2063
2064    def test_basic_protocol(self):
2065        @runtime_checkable
2066        class P(Protocol):
2067            def meth(self):
2068                pass
2069        class C: pass
2070        class D:
2071            def meth(self):
2072                pass
2073        def f():
2074            pass
2075        self.assertIsSubclass(D, P)
2076        self.assertIsInstance(D(), P)
2077        self.assertNotIsSubclass(C, P)
2078        self.assertNotIsInstance(C(), P)
2079        self.assertNotIsSubclass(types.FunctionType, P)
2080        self.assertNotIsInstance(f, P)
2081
2082    def test_everything_implements_empty_protocol(self):
2083        @runtime_checkable
2084        class Empty(Protocol): pass
2085        class C: pass
2086        def f():
2087            pass
2088        for thing in (object, type, tuple, C, types.FunctionType):
2089            self.assertIsSubclass(thing, Empty)
2090        for thing in (object(), 1, (), typing, f):
2091            self.assertIsInstance(thing, Empty)
2092
2093    def test_function_implements_protocol(self):
2094        def f():
2095            pass
2096        self.assertIsInstance(f, HasCallProtocol)
2097
2098    def test_no_inheritance_from_nominal(self):
2099        class C: pass
2100        class BP(Protocol): pass
2101        with self.assertRaises(TypeError):
2102            class P(C, Protocol):
2103                pass
2104        with self.assertRaises(TypeError):
2105            class Q(Protocol, C):
2106                pass
2107        with self.assertRaises(TypeError):
2108            class R(BP, C, Protocol):
2109                pass
2110        class D(BP, C): pass
2111        class E(C, BP): pass
2112        self.assertNotIsInstance(D(), E)
2113        self.assertNotIsInstance(E(), D)
2114
2115    def test_runtimecheckable_on_typing_dot_Protocol(self):
2116        @runtime_checkable
2117        class Foo(typing.Protocol):
2118            x: int
2119
2120        class Bar:
2121            def __init__(self):
2122                self.x = 42
2123
2124        self.assertIsInstance(Bar(), Foo)
2125        self.assertNotIsInstance(object(), Foo)
2126
2127    def test_typing_dot_runtimecheckable_on_Protocol(self):
2128        @typing.runtime_checkable
2129        class Foo(Protocol):
2130            x: int
2131
2132        class Bar:
2133            def __init__(self):
2134                self.x = 42
2135
2136        self.assertIsInstance(Bar(), Foo)
2137        self.assertNotIsInstance(object(), Foo)
2138
2139    def test_typing_Protocol_and_extensions_Protocol_can_mix(self):
2140        class TypingProto(typing.Protocol):
2141            x: int
2142
2143        class ExtensionsProto(Protocol):
2144            y: int
2145
2146        class SubProto(TypingProto, ExtensionsProto, typing.Protocol):
2147            z: int
2148
2149        class SubProto2(TypingProto, ExtensionsProto, Protocol):
2150            z: int
2151
2152        class SubProto3(ExtensionsProto, TypingProto, typing.Protocol):
2153            z: int
2154
2155        class SubProto4(ExtensionsProto, TypingProto, Protocol):
2156            z: int
2157
2158        for proto in (
2159            ExtensionsProto, SubProto, SubProto2, SubProto3, SubProto4
2160        ):
2161            with self.subTest(proto=proto.__name__):
2162                self.assertTrue(is_protocol(proto))
2163                if Protocol is not typing.Protocol:
2164                    self.assertIsInstance(proto, typing_extensions._ProtocolMeta)
2165                self.assertIsInstance(proto.__protocol_attrs__, set)
2166                with self.assertRaisesRegex(
2167                    TypeError, "Protocols cannot be instantiated"
2168                ):
2169                    proto()
2170                # check these don't raise
2171                runtime_checkable(proto)
2172                typing.runtime_checkable(proto)
2173
2174        class Concrete(SubProto): pass
2175        class Concrete2(SubProto2): pass
2176        class Concrete3(SubProto3): pass
2177        class Concrete4(SubProto4): pass
2178
2179        for cls in Concrete, Concrete2, Concrete3, Concrete4:
2180            with self.subTest(cls=cls.__name__):
2181                self.assertFalse(is_protocol(cls))
2182                # Check that this doesn't raise:
2183                self.assertIsInstance(cls(), cls)
2184                with self.assertRaises(TypeError):
2185                    runtime_checkable(cls)
2186                with self.assertRaises(TypeError):
2187                    typing.runtime_checkable(cls)
2188
2189    def test_no_instantiation(self):
2190        class P(Protocol): pass
2191        with self.assertRaises(TypeError):
2192            P()
2193        class C(P): pass
2194        self.assertIsInstance(C(), C)
2195        T = TypeVar('T')
2196        class PG(Protocol[T]): pass
2197        with self.assertRaises(TypeError):
2198            PG()
2199        with self.assertRaises(TypeError):
2200            PG[int]()
2201        with self.assertRaises(TypeError):
2202            PG[T]()
2203        class CG(PG[T]): pass
2204        self.assertIsInstance(CG[int](), CG)
2205
2206    def test_protocol_defining_init_does_not_get_overridden(self):
2207        # check that P.__init__ doesn't get clobbered
2208        # see https://bugs.python.org/issue44807
2209
2210        class P(Protocol):
2211            x: int
2212            def __init__(self, x: int) -> None:
2213                self.x = x
2214        class C: pass
2215
2216        c = C()
2217        P.__init__(c, 1)
2218        self.assertEqual(c.x, 1)
2219
2220    def test_concrete_class_inheriting_init_from_protocol(self):
2221        class P(Protocol):
2222            x: int
2223            def __init__(self, x: int) -> None:
2224                self.x = x
2225
2226        class C(P): pass
2227
2228        c = C(1)
2229        self.assertIsInstance(c, C)
2230        self.assertEqual(c.x, 1)
2231
2232    def test_cannot_instantiate_abstract(self):
2233        @runtime_checkable
2234        class P(Protocol):
2235            @abc.abstractmethod
2236            def ameth(self) -> int:
2237                raise NotImplementedError
2238        class B(P):
2239            pass
2240        class C(B):
2241            def ameth(self) -> int:
2242                return 26
2243        with self.assertRaises(TypeError):
2244            B()
2245        self.assertIsInstance(C(), P)
2246
2247    def test_subprotocols_extending(self):
2248        class P1(Protocol):
2249            def meth1(self):
2250                pass
2251        @runtime_checkable
2252        class P2(P1, Protocol):
2253            def meth2(self):
2254                pass
2255        class C:
2256            def meth1(self):
2257                pass
2258            def meth2(self):
2259                pass
2260        class C1:
2261            def meth1(self):
2262                pass
2263        class C2:
2264            def meth2(self):
2265                pass
2266        self.assertNotIsInstance(C1(), P2)
2267        self.assertNotIsInstance(C2(), P2)
2268        self.assertNotIsSubclass(C1, P2)
2269        self.assertNotIsSubclass(C2, P2)
2270        self.assertIsInstance(C(), P2)
2271        self.assertIsSubclass(C, P2)
2272
2273    def test_subprotocols_merging(self):
2274        class P1(Protocol):
2275            def meth1(self):
2276                pass
2277        class P2(Protocol):
2278            def meth2(self):
2279                pass
2280        @runtime_checkable
2281        class P(P1, P2, Protocol):
2282            pass
2283        class C:
2284            def meth1(self):
2285                pass
2286            def meth2(self):
2287                pass
2288        class C1:
2289            def meth1(self):
2290                pass
2291        class C2:
2292            def meth2(self):
2293                pass
2294        self.assertNotIsInstance(C1(), P)
2295        self.assertNotIsInstance(C2(), P)
2296        self.assertNotIsSubclass(C1, P)
2297        self.assertNotIsSubclass(C2, P)
2298        self.assertIsInstance(C(), P)
2299        self.assertIsSubclass(C, P)
2300
2301    def test_protocols_issubclass(self):
2302        T = TypeVar('T')
2303        @runtime_checkable
2304        class P(Protocol):
2305            def x(self): ...
2306        @runtime_checkable
2307        class PG(Protocol[T]):
2308            def x(self): ...
2309        class BadP(Protocol):
2310            def x(self): ...
2311        class BadPG(Protocol[T]):
2312            def x(self): ...
2313        class C:
2314            def x(self): ...
2315        self.assertIsSubclass(C, P)
2316        self.assertIsSubclass(C, PG)
2317        self.assertIsSubclass(BadP, PG)
2318
2319        no_subscripted_generics = (
2320            "Subscripted generics cannot be used with class and instance checks"
2321        )
2322
2323        with self.assertRaisesRegex(TypeError, no_subscripted_generics):
2324            issubclass(C, PG[T])
2325        with self.assertRaisesRegex(TypeError, no_subscripted_generics):
2326            issubclass(C, PG[C])
2327
2328        only_runtime_checkable_protocols = (
2329            "Instance and class checks can only be used with "
2330            "@runtime_checkable protocols"
2331        )
2332
2333        with self.assertRaisesRegex(TypeError, only_runtime_checkable_protocols):
2334            issubclass(C, BadP)
2335        with self.assertRaisesRegex(TypeError, only_runtime_checkable_protocols):
2336            issubclass(C, BadPG)
2337
2338        with self.assertRaisesRegex(TypeError, no_subscripted_generics):
2339            issubclass(P, PG[T])
2340        with self.assertRaisesRegex(TypeError, no_subscripted_generics):
2341            issubclass(PG, PG[int])
2342
2343        only_classes_allowed = r"issubclass\(\) arg 1 must be a class"
2344
2345        with self.assertRaisesRegex(TypeError, only_classes_allowed):
2346            issubclass(1, P)
2347        with self.assertRaisesRegex(TypeError, only_classes_allowed):
2348            issubclass(1, PG)
2349        with self.assertRaisesRegex(TypeError, only_classes_allowed):
2350            issubclass(1, BadP)
2351        with self.assertRaisesRegex(TypeError, only_classes_allowed):
2352            issubclass(1, BadPG)
2353
2354    def test_implicit_issubclass_between_two_protocols(self):
2355        @runtime_checkable
2356        class CallableMembersProto(Protocol):
2357            def meth(self): ...
2358
2359        # All the below protocols should be considered "subclasses"
2360        # of CallableMembersProto at runtime,
2361        # even though none of them explicitly subclass CallableMembersProto
2362
2363        class IdenticalProto(Protocol):
2364            def meth(self): ...
2365
2366        class SupersetProto(Protocol):
2367            def meth(self): ...
2368            def meth2(self): ...
2369
2370        class NonCallableMembersProto(Protocol):
2371            meth: Callable[[], None]
2372
2373        class NonCallableMembersSupersetProto(Protocol):
2374            meth: Callable[[], None]
2375            meth2: Callable[[str, int], bool]
2376
2377        class MixedMembersProto1(Protocol):
2378            meth: Callable[[], None]
2379            def meth2(self): ...
2380
2381        class MixedMembersProto2(Protocol):
2382            def meth(self): ...
2383            meth2: Callable[[str, int], bool]
2384
2385        for proto in (
2386            IdenticalProto, SupersetProto, NonCallableMembersProto,
2387            NonCallableMembersSupersetProto, MixedMembersProto1, MixedMembersProto2
2388        ):
2389            with self.subTest(proto=proto.__name__):
2390                self.assertIsSubclass(proto, CallableMembersProto)
2391
2392        # These two shouldn't be considered subclasses of CallableMembersProto, however,
2393        # since they don't have the `meth` protocol member
2394
2395        class EmptyProtocol(Protocol): ...
2396        class UnrelatedProtocol(Protocol):
2397            def wut(self): ...
2398
2399        self.assertNotIsSubclass(EmptyProtocol, CallableMembersProto)
2400        self.assertNotIsSubclass(UnrelatedProtocol, CallableMembersProto)
2401
2402        # These aren't protocols at all (despite having annotations),
2403        # so they should only be considered subclasses of CallableMembersProto
2404        # if they *actually have an attribute* matching the `meth` member
2405        # (just having an annotation is insufficient)
2406
2407        class AnnotatedButNotAProtocol:
2408            meth: Callable[[], None]
2409
2410        class NotAProtocolButAnImplicitSubclass:
2411            def meth(self): pass
2412
2413        class NotAProtocolButAnImplicitSubclass2:
2414            meth: Callable[[], None]
2415            def meth(self): pass
2416
2417        class NotAProtocolButAnImplicitSubclass3:
2418            meth: Callable[[], None]
2419            meth2: Callable[[int, str], bool]
2420            def meth(self): pass
2421            def meth2(self, x, y): return True
2422
2423        self.assertNotIsSubclass(AnnotatedButNotAProtocol, CallableMembersProto)
2424        self.assertIsSubclass(NotAProtocolButAnImplicitSubclass, CallableMembersProto)
2425        self.assertIsSubclass(NotAProtocolButAnImplicitSubclass2, CallableMembersProto)
2426        self.assertIsSubclass(NotAProtocolButAnImplicitSubclass3, CallableMembersProto)
2427
2428    @skip_if_py312b1
2429    def test_issubclass_and_isinstance_on_Protocol_itself(self):
2430        class C:
2431            def x(self): pass
2432
2433        self.assertNotIsSubclass(object, Protocol)
2434        self.assertNotIsInstance(object(), Protocol)
2435
2436        self.assertNotIsSubclass(str, Protocol)
2437        self.assertNotIsInstance('foo', Protocol)
2438
2439        self.assertNotIsSubclass(C, Protocol)
2440        self.assertNotIsInstance(C(), Protocol)
2441
2442        only_classes_allowed = r"issubclass\(\) arg 1 must be a class"
2443
2444        with self.assertRaisesRegex(TypeError, only_classes_allowed):
2445            issubclass(1, Protocol)
2446        with self.assertRaisesRegex(TypeError, only_classes_allowed):
2447            issubclass('foo', Protocol)
2448        with self.assertRaisesRegex(TypeError, only_classes_allowed):
2449            issubclass(C(), Protocol)
2450
2451        T = TypeVar('T')
2452
2453        @runtime_checkable
2454        class EmptyProtocol(Protocol): pass
2455
2456        @runtime_checkable
2457        class SupportsStartsWith(Protocol):
2458            def startswith(self, x: str) -> bool: ...
2459
2460        @runtime_checkable
2461        class SupportsX(Protocol[T]):
2462            def x(self): ...
2463
2464        for proto in EmptyProtocol, SupportsStartsWith, SupportsX:
2465            with self.subTest(proto=proto.__name__):
2466                self.assertIsSubclass(proto, Protocol)
2467
2468        # gh-105237 / PR #105239:
2469        # check that the presence of Protocol subclasses
2470        # where `issubclass(X, <subclass>)` evaluates to True
2471        # doesn't influence the result of `issubclass(X, Protocol)`
2472
2473        self.assertIsSubclass(object, EmptyProtocol)
2474        self.assertIsInstance(object(), EmptyProtocol)
2475        self.assertNotIsSubclass(object, Protocol)
2476        self.assertNotIsInstance(object(), Protocol)
2477
2478        self.assertIsSubclass(str, SupportsStartsWith)
2479        self.assertIsInstance('foo', SupportsStartsWith)
2480        self.assertNotIsSubclass(str, Protocol)
2481        self.assertNotIsInstance('foo', Protocol)
2482
2483        self.assertIsSubclass(C, SupportsX)
2484        self.assertIsInstance(C(), SupportsX)
2485        self.assertNotIsSubclass(C, Protocol)
2486        self.assertNotIsInstance(C(), Protocol)
2487
2488    @skip_if_py312b1
2489    def test_isinstance_checks_not_at_whim_of_gc(self):
2490        self.addCleanup(gc.enable)
2491        gc.disable()
2492
2493        with self.assertRaisesRegex(
2494            TypeError,
2495            "Protocols can only inherit from other protocols"
2496        ):
2497            class Foo(collections.abc.Mapping, Protocol):
2498                pass
2499
2500        self.assertNotIsInstance([], collections.abc.Mapping)
2501
2502    def test_protocols_issubclass_non_callable(self):
2503        class C:
2504            x = 1
2505
2506        @runtime_checkable
2507        class PNonCall(Protocol):
2508            x = 1
2509
2510        non_callable_members_illegal = (
2511            "Protocols with non-method members don't support issubclass()"
2512        )
2513
2514        with self.assertRaisesRegex(TypeError, non_callable_members_illegal):
2515            issubclass(C, PNonCall)
2516
2517        self.assertIsInstance(C(), PNonCall)
2518        PNonCall.register(C)
2519
2520        with self.assertRaisesRegex(TypeError, non_callable_members_illegal):
2521            issubclass(C, PNonCall)
2522
2523        self.assertIsInstance(C(), PNonCall)
2524
2525        # check that non-protocol subclasses are not affected
2526        class D(PNonCall): ...
2527
2528        self.assertNotIsSubclass(C, D)
2529        self.assertNotIsInstance(C(), D)
2530        D.register(C)
2531        self.assertIsSubclass(C, D)
2532        self.assertIsInstance(C(), D)
2533
2534        with self.assertRaisesRegex(TypeError, non_callable_members_illegal):
2535            issubclass(D, PNonCall)
2536
2537    def test_no_weird_caching_with_issubclass_after_isinstance(self):
2538        @runtime_checkable
2539        class Spam(Protocol):
2540            x: int
2541
2542        class Eggs:
2543            def __init__(self) -> None:
2544                self.x = 42
2545
2546        self.assertIsInstance(Eggs(), Spam)
2547
2548        # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
2549        # TypeError wouldn't be raised here,
2550        # as the cached result of the isinstance() check immediately above
2551        # would mean the issubclass() call would short-circuit
2552        # before we got to the "raise TypeError" line
2553        with self.assertRaisesRegex(
2554            TypeError,
2555            "Protocols with non-method members don't support issubclass()"
2556        ):
2557            issubclass(Eggs, Spam)
2558
2559    def test_no_weird_caching_with_issubclass_after_isinstance_2(self):
2560        @runtime_checkable
2561        class Spam(Protocol):
2562            x: int
2563
2564        class Eggs: ...
2565
2566        self.assertNotIsInstance(Eggs(), Spam)
2567
2568        # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
2569        # TypeError wouldn't be raised here,
2570        # as the cached result of the isinstance() check immediately above
2571        # would mean the issubclass() call would short-circuit
2572        # before we got to the "raise TypeError" line
2573        with self.assertRaisesRegex(
2574            TypeError,
2575            "Protocols with non-method members don't support issubclass()"
2576        ):
2577            issubclass(Eggs, Spam)
2578
2579    def test_no_weird_caching_with_issubclass_after_isinstance_3(self):
2580        @runtime_checkable
2581        class Spam(Protocol):
2582            x: int
2583
2584        class Eggs:
2585            def __getattr__(self, attr):
2586                if attr == "x":
2587                    return 42
2588                raise AttributeError(attr)
2589
2590        self.assertNotIsInstance(Eggs(), Spam)
2591
2592        # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
2593        # TypeError wouldn't be raised here,
2594        # as the cached result of the isinstance() check immediately above
2595        # would mean the issubclass() call would short-circuit
2596        # before we got to the "raise TypeError" line
2597        with self.assertRaisesRegex(
2598            TypeError,
2599            "Protocols with non-method members don't support issubclass()"
2600        ):
2601            issubclass(Eggs, Spam)
2602
2603    def test_protocols_isinstance(self):
2604        T = TypeVar('T')
2605        @runtime_checkable
2606        class P(Protocol):
2607            def meth(x): ...
2608        @runtime_checkable
2609        class PG(Protocol[T]):
2610            def meth(x): ...
2611        @runtime_checkable
2612        class WeirdProto(Protocol):
2613            meth = str.maketrans
2614        @runtime_checkable
2615        class WeirdProto2(Protocol):
2616            meth = lambda *args, **kwargs: None  # noqa: E731
2617        class CustomCallable:
2618            def __call__(self, *args, **kwargs):
2619                pass
2620        @runtime_checkable
2621        class WeirderProto(Protocol):
2622            meth = CustomCallable()
2623        class BadP(Protocol):
2624            def meth(x): ...
2625        class BadPG(Protocol[T]):
2626            def meth(x): ...
2627        class C:
2628            def meth(x): ...
2629        class C2:
2630            def __init__(self):
2631                self.meth = lambda: None
2632        for klass in C, C2:
2633            for proto in P, PG, WeirdProto, WeirdProto2, WeirderProto:
2634                with self.subTest(klass=klass.__name__, proto=proto.__name__):
2635                    self.assertIsInstance(klass(), proto)
2636
2637        no_subscripted_generics = (
2638            "Subscripted generics cannot be used with class and instance checks"
2639        )
2640
2641        with self.assertRaisesRegex(TypeError, no_subscripted_generics):
2642            isinstance(C(), PG[T])
2643        with self.assertRaisesRegex(TypeError, no_subscripted_generics):
2644            isinstance(C(), PG[C])
2645
2646        only_runtime_checkable_msg = (
2647            "Instance and class checks can only be used "
2648            "with @runtime_checkable protocols"
2649        )
2650
2651        with self.assertRaisesRegex(TypeError, only_runtime_checkable_msg):
2652            isinstance(C(), BadP)
2653        with self.assertRaisesRegex(TypeError, only_runtime_checkable_msg):
2654            isinstance(C(), BadPG)
2655
2656    def test_protocols_isinstance_properties_and_descriptors(self):
2657        class C:
2658            @property
2659            def attr(self):
2660                return 42
2661
2662        class CustomDescriptor:
2663            def __get__(self, obj, objtype=None):
2664                return 42
2665
2666        class D:
2667            attr = CustomDescriptor()
2668
2669        # Check that properties set on superclasses
2670        # are still found by the isinstance() logic
2671        class E(C): ...
2672        class F(D): ...
2673
2674        class Empty: ...
2675
2676        T = TypeVar('T')
2677
2678        @runtime_checkable
2679        class P(Protocol):
2680            @property
2681            def attr(self): ...
2682
2683        @runtime_checkable
2684        class P1(Protocol):
2685            attr: int
2686
2687        @runtime_checkable
2688        class PG(Protocol[T]):
2689            @property
2690            def attr(self): ...
2691
2692        @runtime_checkable
2693        class PG1(Protocol[T]):
2694            attr: T
2695
2696        @runtime_checkable
2697        class MethodP(Protocol):
2698            def attr(self): ...
2699
2700        @runtime_checkable
2701        class MethodPG(Protocol[T]):
2702            def attr(self) -> T: ...
2703
2704        for protocol_class in P, P1, PG, PG1, MethodP, MethodPG:
2705            for klass in C, D, E, F:
2706                with self.subTest(
2707                    klass=klass.__name__,
2708                    protocol_class=protocol_class.__name__
2709                ):
2710                    self.assertIsInstance(klass(), protocol_class)
2711
2712            with self.subTest(klass="Empty", protocol_class=protocol_class.__name__):
2713                self.assertNotIsInstance(Empty(), protocol_class)
2714
2715        class BadP(Protocol):
2716            @property
2717            def attr(self): ...
2718
2719        class BadP1(Protocol):
2720            attr: int
2721
2722        class BadPG(Protocol[T]):
2723            @property
2724            def attr(self): ...
2725
2726        class BadPG1(Protocol[T]):
2727            attr: T
2728
2729        cases = (
2730            PG[T], PG[C], PG1[T], PG1[C], MethodPG[T],
2731            MethodPG[C], BadP, BadP1, BadPG, BadPG1
2732        )
2733
2734        for obj in cases:
2735            for klass in C, D, E, F, Empty:
2736                with self.subTest(klass=klass.__name__, obj=obj):
2737                    with self.assertRaises(TypeError):
2738                        isinstance(klass(), obj)
2739
2740    def test_protocols_isinstance_not_fooled_by_custom_dir(self):
2741        @runtime_checkable
2742        class HasX(Protocol):
2743            x: int
2744
2745        class CustomDirWithX:
2746            x = 10
2747            def __dir__(self):
2748                return []
2749
2750        class CustomDirWithoutX:
2751            def __dir__(self):
2752                return ["x"]
2753
2754        self.assertIsInstance(CustomDirWithX(), HasX)
2755        self.assertNotIsInstance(CustomDirWithoutX(), HasX)
2756
2757    def test_protocols_isinstance_attribute_access_with_side_effects(self):
2758        class C:
2759            @property
2760            def attr(self):
2761                raise AttributeError('no')
2762
2763        class CustomDescriptor:
2764            def __get__(self, obj, objtype=None):
2765                raise RuntimeError("NO")
2766
2767        class D:
2768            attr = CustomDescriptor()
2769
2770        # Check that properties set on superclasses
2771        # are still found by the isinstance() logic
2772        class E(C): ...
2773        class F(D): ...
2774
2775        class WhyWouldYouDoThis:
2776            def __getattr__(self, name):
2777                raise RuntimeError("wut")
2778
2779        T = TypeVar('T')
2780
2781        @runtime_checkable
2782        class P(Protocol):
2783            @property
2784            def attr(self): ...
2785
2786        @runtime_checkable
2787        class P1(Protocol):
2788            attr: int
2789
2790        @runtime_checkable
2791        class PG(Protocol[T]):
2792            @property
2793            def attr(self): ...
2794
2795        @runtime_checkable
2796        class PG1(Protocol[T]):
2797            attr: T
2798
2799        @runtime_checkable
2800        class MethodP(Protocol):
2801            def attr(self): ...
2802
2803        @runtime_checkable
2804        class MethodPG(Protocol[T]):
2805            def attr(self) -> T: ...
2806
2807        for protocol_class in P, P1, PG, PG1, MethodP, MethodPG:
2808            for klass in C, D, E, F:
2809                with self.subTest(
2810                    klass=klass.__name__,
2811                    protocol_class=protocol_class.__name__
2812                ):
2813                    self.assertIsInstance(klass(), protocol_class)
2814
2815            with self.subTest(
2816                klass="WhyWouldYouDoThis",
2817                protocol_class=protocol_class.__name__
2818            ):
2819                self.assertNotIsInstance(WhyWouldYouDoThis(), protocol_class)
2820
2821    def test_protocols_isinstance___slots__(self):
2822        # As per the consensus in https://github.com/python/typing/issues/1367,
2823        # this is desirable behaviour
2824        @runtime_checkable
2825        class HasX(Protocol):
2826            x: int
2827
2828        class HasNothingButSlots:
2829            __slots__ = ("x",)
2830
2831        self.assertIsInstance(HasNothingButSlots(), HasX)
2832
2833    def test_protocols_isinstance_py36(self):
2834        class APoint:
2835            def __init__(self, x, y, label):
2836                self.x = x
2837                self.y = y
2838                self.label = label
2839        class BPoint:
2840            label = 'B'
2841            def __init__(self, x, y):
2842                self.x = x
2843                self.y = y
2844        class C:
2845            def __init__(self, attr):
2846                self.attr = attr
2847            def meth(self, arg):
2848                return 0
2849        class Bad: pass
2850        self.assertIsInstance(APoint(1, 2, 'A'), Point)
2851        self.assertIsInstance(BPoint(1, 2), Point)
2852        self.assertNotIsInstance(MyPoint(), Point)
2853        self.assertIsInstance(BPoint(1, 2), Position)
2854        self.assertIsInstance(Other(), Proto)
2855        self.assertIsInstance(Concrete(), Proto)
2856        self.assertIsInstance(C(42), Proto)
2857        self.assertNotIsInstance(Bad(), Proto)
2858        self.assertNotIsInstance(Bad(), Point)
2859        self.assertNotIsInstance(Bad(), Position)
2860        self.assertNotIsInstance(Bad(), Concrete)
2861        self.assertNotIsInstance(Other(), Concrete)
2862        self.assertIsInstance(NT(1, 2), Position)
2863
2864    def test_runtime_checkable_with_match_args(self):
2865        @runtime_checkable
2866        class P_regular(Protocol):
2867            x: int
2868            y: int
2869
2870        @runtime_checkable
2871        class P_match(Protocol):
2872            __match_args__ = ("x", "y")
2873            x: int
2874            y: int
2875
2876        class Regular:
2877            def __init__(self, x: int, y: int):
2878                self.x = x
2879                self.y = y
2880
2881        class WithMatch:
2882            __match_args__ = ("x", "y", "z")
2883            def __init__(self, x: int, y: int, z: int):
2884                self.x = x
2885                self.y = y
2886                self.z = z
2887
2888        class Nope: ...
2889
2890        self.assertIsInstance(Regular(1, 2), P_regular)
2891        self.assertIsInstance(Regular(1, 2), P_match)
2892        self.assertIsInstance(WithMatch(1, 2, 3), P_regular)
2893        self.assertIsInstance(WithMatch(1, 2, 3), P_match)
2894        self.assertNotIsInstance(Nope(), P_regular)
2895        self.assertNotIsInstance(Nope(), P_match)
2896
2897    def test_protocols_isinstance_init(self):
2898        T = TypeVar('T')
2899        @runtime_checkable
2900        class P(Protocol):
2901            x = 1
2902        @runtime_checkable
2903        class PG(Protocol[T]):
2904            x = 1
2905        class C:
2906            def __init__(self, x):
2907                self.x = x
2908        self.assertIsInstance(C(1), P)
2909        self.assertIsInstance(C(1), PG)
2910
2911    def test_protocols_isinstance_monkeypatching(self):
2912        @runtime_checkable
2913        class HasX(Protocol):
2914            x: int
2915
2916        class Foo: ...
2917
2918        f = Foo()
2919        self.assertNotIsInstance(f, HasX)
2920        f.x = 42
2921        self.assertIsInstance(f, HasX)
2922        del f.x
2923        self.assertNotIsInstance(f, HasX)
2924
2925    @skip_if_py312b1
2926    def test_runtime_checkable_generic_non_protocol(self):
2927        # Make sure this doesn't raise AttributeError
2928        with self.assertRaisesRegex(
2929            TypeError,
2930            "@runtime_checkable can be only applied to protocol classes",
2931        ):
2932            @runtime_checkable
2933            class Foo(Generic[T]): ...
2934
2935    def test_runtime_checkable_generic(self):
2936        @runtime_checkable
2937        class Foo(Protocol[T]):
2938            def meth(self) -> T: ...
2939
2940        class Impl:
2941            def meth(self) -> int: ...
2942
2943        self.assertIsSubclass(Impl, Foo)
2944
2945        class NotImpl:
2946            def method(self) -> int: ...
2947
2948        self.assertNotIsSubclass(NotImpl, Foo)
2949
2950    if sys.version_info >= (3, 12):
2951        exec(textwrap.dedent(
2952            """
2953            @skip_if_py312b1
2954            def test_pep695_generics_can_be_runtime_checkable(self):
2955                @runtime_checkable
2956                class HasX(Protocol):
2957                    x: int
2958
2959                class Bar[T]:
2960                    x: T
2961                    def __init__(self, x):
2962                        self.x = x
2963
2964                class Capybara[T]:
2965                    y: str
2966                    def __init__(self, y):
2967                        self.y = y
2968
2969                self.assertIsInstance(Bar(1), HasX)
2970                self.assertNotIsInstance(Capybara('a'), HasX)
2971                """
2972        ))
2973
2974    @skip_if_py312b1
2975    def test_protocols_isinstance_generic_classes(self):
2976        T = TypeVar("T")
2977
2978        class Foo(Generic[T]):
2979            x: T
2980
2981            def __init__(self, x):
2982                self.x = x
2983
2984        class Bar(Foo[int]):
2985            ...
2986
2987        @runtime_checkable
2988        class HasX(Protocol):
2989            x: int
2990
2991        foo = Foo(1)
2992        self.assertIsInstance(foo, HasX)
2993
2994        bar = Bar(2)
2995        self.assertIsInstance(bar, HasX)
2996
2997    def test_protocols_support_register(self):
2998        @runtime_checkable
2999        class P(Protocol):
3000            x = 1
3001        class PM(Protocol):
3002            def meth(self): pass
3003        class D(PM): pass
3004        class C: pass
3005        D.register(C)
3006        P.register(C)
3007        self.assertIsInstance(C(), P)
3008        self.assertIsInstance(C(), D)
3009
3010    def test_none_on_non_callable_doesnt_block_implementation(self):
3011        @runtime_checkable
3012        class P(Protocol):
3013            x = 1
3014        class A:
3015            x = 1
3016        class B(A):
3017            x = None
3018        class C:
3019            def __init__(self):
3020                self.x = None
3021        self.assertIsInstance(B(), P)
3022        self.assertIsInstance(C(), P)
3023
3024    def test_none_on_callable_blocks_implementation(self):
3025        @runtime_checkable
3026        class P(Protocol):
3027            def x(self): ...
3028        class A:
3029            def x(self): ...
3030        class B(A):
3031            x = None
3032        class C:
3033            def __init__(self):
3034                self.x = None
3035        self.assertNotIsInstance(B(), P)
3036        self.assertNotIsInstance(C(), P)
3037
3038    def test_non_protocol_subclasses(self):
3039        class P(Protocol):
3040            x = 1
3041        @runtime_checkable
3042        class PR(Protocol):
3043            def meth(self): pass
3044        class NonP(P):
3045            x = 1
3046        class NonPR(PR): pass
3047        class C(metaclass=abc.ABCMeta):
3048            x = 1
3049        class D(metaclass=abc.ABCMeta):
3050            def meth(self): pass  # noqa: B027
3051        self.assertNotIsInstance(C(), NonP)
3052        self.assertNotIsInstance(D(), NonPR)
3053        self.assertNotIsSubclass(C, NonP)
3054        self.assertNotIsSubclass(D, NonPR)
3055        self.assertIsInstance(NonPR(), PR)
3056        self.assertIsSubclass(NonPR, PR)
3057
3058        self.assertNotIn("__protocol_attrs__", vars(NonP))
3059        self.assertNotIn("__protocol_attrs__", vars(NonPR))
3060        self.assertNotIn("__non_callable_proto_members__", vars(NonP))
3061        self.assertNotIn("__non_callable_proto_members__", vars(NonPR))
3062
3063        acceptable_extra_attrs = {
3064            '_is_protocol', '_is_runtime_protocol', '__parameters__',
3065            '__init__', '__annotations__', '__subclasshook__', '__annotate__'
3066        }
3067        self.assertLessEqual(vars(NonP).keys(), vars(C).keys() | acceptable_extra_attrs)
3068        self.assertLessEqual(
3069            vars(NonPR).keys(), vars(D).keys() | acceptable_extra_attrs
3070        )
3071
3072    def test_custom_subclasshook(self):
3073        class P(Protocol):
3074            x = 1
3075        class OKClass: pass
3076        class BadClass:
3077            x = 1
3078        class C(P):
3079            @classmethod
3080            def __subclasshook__(cls, other):
3081                return other.__name__.startswith("OK")
3082        self.assertIsInstance(OKClass(), C)
3083        self.assertNotIsInstance(BadClass(), C)
3084        self.assertIsSubclass(OKClass, C)
3085        self.assertNotIsSubclass(BadClass, C)
3086
3087    @skipIf(
3088        sys.version_info[:4] == (3, 12, 0, 'beta') and sys.version_info[4] < 4,
3089        "Early betas of Python 3.12 had a bug"
3090    )
3091    def test_custom_subclasshook_2(self):
3092        @runtime_checkable
3093        class HasX(Protocol):
3094            # The presence of a non-callable member
3095            # would mean issubclass() checks would fail with TypeError
3096            # if it weren't for the custom `__subclasshook__` method
3097            x = 1
3098
3099            @classmethod
3100            def __subclasshook__(cls, other):
3101                return hasattr(other, 'x')
3102
3103        class Empty: pass
3104
3105        class ImplementsHasX:
3106            x = 1
3107
3108        self.assertIsInstance(ImplementsHasX(), HasX)
3109        self.assertNotIsInstance(Empty(), HasX)
3110        self.assertIsSubclass(ImplementsHasX, HasX)
3111        self.assertNotIsSubclass(Empty, HasX)
3112
3113        # isinstance() and issubclass() checks against this still raise TypeError,
3114        # despite the presence of the custom __subclasshook__ method,
3115        # as it's not decorated with @runtime_checkable
3116        class NotRuntimeCheckable(Protocol):
3117            @classmethod
3118            def __subclasshook__(cls, other):
3119                return hasattr(other, 'x')
3120
3121        must_be_runtime_checkable = (
3122            "Instance and class checks can only be used "
3123            "with @runtime_checkable protocols"
3124        )
3125
3126        with self.assertRaisesRegex(TypeError, must_be_runtime_checkable):
3127            issubclass(object, NotRuntimeCheckable)
3128        with self.assertRaisesRegex(TypeError, must_be_runtime_checkable):
3129            isinstance(object(), NotRuntimeCheckable)
3130
3131    @skip_if_py312b1
3132    def test_issubclass_fails_correctly(self):
3133        @runtime_checkable
3134        class NonCallableMembers(Protocol):
3135            x = 1
3136
3137        class NotRuntimeCheckable(Protocol):
3138            def callable_member(self) -> int: ...
3139
3140        @runtime_checkable
3141        class RuntimeCheckable(Protocol):
3142            def callable_member(self) -> int: ...
3143
3144        class C: pass
3145
3146        # These three all exercise different code paths,
3147        # but should result in the same error message:
3148        for protocol in NonCallableMembers, NotRuntimeCheckable, RuntimeCheckable:
3149            with self.subTest(proto_name=protocol.__name__):
3150                with self.assertRaisesRegex(
3151                    TypeError, r"issubclass\(\) arg 1 must be a class"
3152                ):
3153                    issubclass(C(), protocol)
3154
3155    def test_defining_generic_protocols(self):
3156        T = TypeVar('T')
3157        S = TypeVar('S')
3158        @runtime_checkable
3159        class PR(Protocol[T, S]):
3160            def meth(self): pass
3161        class P(PR[int, T], Protocol[T]):
3162            y = 1
3163        with self.assertRaises(TypeError):
3164            issubclass(PR[int, T], PR)
3165        with self.assertRaises(TypeError):
3166            issubclass(P[str], PR)
3167        with self.assertRaises(TypeError):
3168            PR[int]
3169        with self.assertRaises(TypeError):
3170            P[int, str]
3171        if not TYPING_3_10_0:
3172            with self.assertRaises(TypeError):
3173                PR[int, 1]
3174            with self.assertRaises(TypeError):
3175                PR[int, ClassVar]
3176        class C(PR[int, T]): pass
3177        self.assertIsInstance(C[str](), C)
3178
3179    def test_defining_generic_protocols_old_style(self):
3180        T = TypeVar('T')
3181        S = TypeVar('S')
3182        @runtime_checkable
3183        class PR(Protocol, Generic[T, S]):
3184            def meth(self): pass
3185        class P(PR[int, str], Protocol):
3186            y = 1
3187        with self.assertRaises(TypeError):
3188            self.assertIsSubclass(PR[int, str], PR)
3189        self.assertIsSubclass(P, PR)
3190        with self.assertRaises(TypeError):
3191            PR[int]
3192        if not TYPING_3_10_0:
3193            with self.assertRaises(TypeError):
3194                PR[int, 1]
3195        class P1(Protocol, Generic[T]):
3196            def bar(self, x: T) -> str: ...
3197        class P2(Generic[T], Protocol):
3198            def bar(self, x: T) -> str: ...
3199        @runtime_checkable
3200        class PSub(P1[str], Protocol):
3201            x = 1
3202        class Test:
3203            x = 1
3204            def bar(self, x: str) -> str:
3205                return x
3206        self.assertIsInstance(Test(), PSub)
3207        if not TYPING_3_10_0:
3208            with self.assertRaises(TypeError):
3209                PR[int, ClassVar]
3210
3211    if hasattr(typing, "TypeAliasType"):
3212        exec(textwrap.dedent(
3213            """
3214            def test_pep695_generic_protocol_callable_members(self):
3215                @runtime_checkable
3216                class Foo[T](Protocol):
3217                    def meth(self, x: T) -> None: ...
3218
3219                class Bar[T]:
3220                    def meth(self, x: T) -> None: ...
3221
3222                self.assertIsInstance(Bar(), Foo)
3223                self.assertIsSubclass(Bar, Foo)
3224
3225                @runtime_checkable
3226                class SupportsTrunc[T](Protocol):
3227                    def __trunc__(self) -> T: ...
3228
3229                self.assertIsInstance(0.0, SupportsTrunc)
3230                self.assertIsSubclass(float, SupportsTrunc)
3231
3232            def test_no_weird_caching_with_issubclass_after_isinstance_pep695(self):
3233                @runtime_checkable
3234                class Spam[T](Protocol):
3235                    x: T
3236
3237                class Eggs[T]:
3238                    def __init__(self, x: T) -> None:
3239                        self.x = x
3240
3241                self.assertIsInstance(Eggs(42), Spam)
3242
3243                # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
3244                # TypeError wouldn't be raised here,
3245                # as the cached result of the isinstance() check immediately above
3246                # would mean the issubclass() call would short-circuit
3247                # before we got to the "raise TypeError" line
3248                with self.assertRaises(TypeError):
3249                    issubclass(Eggs, Spam)
3250            """
3251        ))
3252
3253    def test_init_called(self):
3254        T = TypeVar('T')
3255        class P(Protocol[T]): pass
3256        class C(P[T]):
3257            def __init__(self):
3258                self.test = 'OK'
3259        self.assertEqual(C[int]().test, 'OK')
3260
3261    def test_protocols_bad_subscripts(self):
3262        T = TypeVar('T')
3263        S = TypeVar('S')
3264        with self.assertRaises(TypeError):
3265            class P(Protocol[T, T]): pass
3266        with self.assertRaises(TypeError):
3267            class P2(Protocol[int]): pass
3268        with self.assertRaises(TypeError):
3269            class P3(Protocol[T], Protocol[S]): pass
3270        with self.assertRaises(TypeError):
3271            class P4(typing.Mapping[T, S], Protocol[T]): pass
3272
3273    def test_generic_protocols_repr(self):
3274        T = TypeVar('T')
3275        S = TypeVar('S')
3276        class P(Protocol[T, S]): pass
3277        self.assertTrue(repr(P[T, S]).endswith('P[~T, ~S]'))
3278        self.assertTrue(repr(P[int, str]).endswith('P[int, str]'))
3279
3280    def test_generic_protocols_eq(self):
3281        T = TypeVar('T')
3282        S = TypeVar('S')
3283        class P(Protocol[T, S]): pass
3284        self.assertEqual(P, P)
3285        self.assertEqual(P[int, T], P[int, T])
3286        self.assertEqual(P[T, T][Tuple[T, S]][int, str],
3287                         P[Tuple[int, str], Tuple[int, str]])
3288
3289    def test_generic_protocols_special_from_generic(self):
3290        T = TypeVar('T')
3291        class P(Protocol[T]): pass
3292        self.assertEqual(P.__parameters__, (T,))
3293        self.assertEqual(P[int].__parameters__, ())
3294        self.assertEqual(P[int].__args__, (int,))
3295        self.assertIs(P[int].__origin__, P)
3296
3297    def test_generic_protocols_special_from_protocol(self):
3298        @runtime_checkable
3299        class PR(Protocol):
3300            x = 1
3301        class P(Protocol):
3302            def meth(self):
3303                pass
3304        T = TypeVar('T')
3305        class PG(Protocol[T]):
3306            x = 1
3307            def meth(self):
3308                pass
3309        self.assertTrue(P._is_protocol)
3310        self.assertTrue(PR._is_protocol)
3311        self.assertTrue(PG._is_protocol)
3312        self.assertFalse(P._is_runtime_protocol)
3313        self.assertTrue(PR._is_runtime_protocol)
3314        self.assertTrue(PG[int]._is_protocol)
3315        self.assertEqual(typing_extensions._get_protocol_attrs(P), {'meth'})
3316        self.assertEqual(typing_extensions._get_protocol_attrs(PR), {'x'})
3317        self.assertEqual(frozenset(typing_extensions._get_protocol_attrs(PG)),
3318                         frozenset({'x', 'meth'}))
3319
3320    def test_no_runtime_deco_on_nominal(self):
3321        with self.assertRaises(TypeError):
3322            @runtime_checkable
3323            class C: pass
3324        class Proto(Protocol):
3325            x = 1
3326        with self.assertRaises(TypeError):
3327            @runtime_checkable
3328            class Concrete(Proto):
3329                pass
3330
3331    def test_none_treated_correctly(self):
3332        @runtime_checkable
3333        class P(Protocol):
3334            x: int = None
3335        class B: pass
3336        self.assertNotIsInstance(B(), P)
3337        class C:
3338            x = 1
3339        class D:
3340            x = None
3341        self.assertIsInstance(C(), P)
3342        self.assertIsInstance(D(), P)
3343        class CI:
3344            def __init__(self):
3345                self.x = 1
3346        class DI:
3347            def __init__(self):
3348                self.x = None
3349        self.assertIsInstance(CI(), P)
3350        self.assertIsInstance(DI(), P)
3351
3352    def test_protocols_in_unions(self):
3353        class P(Protocol):
3354            x: int = None
3355        Alias = typing.Union[typing.Iterable, P]
3356        Alias2 = typing.Union[P, typing.Iterable]
3357        self.assertEqual(Alias, Alias2)
3358
3359    def test_protocols_pickleable(self):
3360        global P, CP  # pickle wants to reference the class by name
3361        T = TypeVar('T')
3362
3363        @runtime_checkable
3364        class P(Protocol[T]):
3365            x = 1
3366        class CP(P[int]):
3367            pass
3368
3369        c = CP()
3370        c.foo = 42
3371        c.bar = 'abc'
3372        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
3373            z = pickle.dumps(c, proto)
3374            x = pickle.loads(z)
3375            self.assertEqual(x.foo, 42)
3376            self.assertEqual(x.bar, 'abc')
3377            self.assertEqual(x.x, 1)
3378            self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'})
3379            s = pickle.dumps(P)
3380            D = pickle.loads(s)
3381            class E:
3382                x = 1
3383            self.assertIsInstance(E(), D)
3384
3385    def test_collections_protocols_allowed(self):
3386        @runtime_checkable
3387        class Custom(collections.abc.Iterable, Protocol):
3388            def close(self): pass
3389
3390        class A: ...
3391        class B:
3392            def __iter__(self):
3393                return []
3394            def close(self):
3395                return 0
3396
3397        self.assertIsSubclass(B, Custom)
3398        self.assertNotIsSubclass(A, Custom)
3399
3400    @skipUnless(
3401        hasattr(collections.abc, "Buffer"),
3402        "needs collections.abc.Buffer to exist"
3403    )
3404    @skip_if_py312b1
3405    def test_collections_abc_buffer_protocol_allowed(self):
3406        @runtime_checkable
3407        class ReleasableBuffer(collections.abc.Buffer, Protocol):
3408            def __release_buffer__(self, mv: memoryview) -> None: ...
3409
3410        class C: pass
3411        class D:
3412            def __buffer__(self, flags: int) -> memoryview:
3413                return memoryview(b'')
3414            def __release_buffer__(self, mv: memoryview) -> None:
3415                pass
3416
3417        self.assertIsSubclass(D, ReleasableBuffer)
3418        self.assertIsInstance(D(), ReleasableBuffer)
3419        self.assertNotIsSubclass(C, ReleasableBuffer)
3420        self.assertNotIsInstance(C(), ReleasableBuffer)
3421
3422    def test_builtin_protocol_allowlist(self):
3423        with self.assertRaises(TypeError):
3424            class CustomProtocol(TestCase, Protocol):
3425                pass
3426
3427        class CustomContextManager(typing.ContextManager, Protocol):
3428            pass
3429
3430    @skip_if_py312b1
3431    def test_typing_extensions_protocol_allowlist(self):
3432        @runtime_checkable
3433        class ReleasableBuffer(Buffer, Protocol):
3434            def __release_buffer__(self, mv: memoryview) -> None: ...
3435
3436        class C: pass
3437        class D:
3438            def __buffer__(self, flags: int) -> memoryview:
3439                return memoryview(b'')
3440            def __release_buffer__(self, mv: memoryview) -> None:
3441                pass
3442
3443        self.assertIsSubclass(D, ReleasableBuffer)
3444        self.assertIsInstance(D(), ReleasableBuffer)
3445        self.assertNotIsSubclass(C, ReleasableBuffer)
3446        self.assertNotIsInstance(C(), ReleasableBuffer)
3447
3448    def test_non_runtime_protocol_isinstance_check(self):
3449        class P(Protocol):
3450            x: int
3451
3452        with self.assertRaisesRegex(TypeError, "@runtime_checkable"):
3453            isinstance(1, P)
3454
3455    def test_no_init_same_for_different_protocol_implementations(self):
3456        class CustomProtocolWithoutInitA(Protocol):
3457            pass
3458
3459        class CustomProtocolWithoutInitB(Protocol):
3460            pass
3461
3462        self.assertEqual(CustomProtocolWithoutInitA.__init__, CustomProtocolWithoutInitB.__init__)
3463
3464    def test_protocol_generic_over_paramspec(self):
3465        P = ParamSpec("P")
3466        T = TypeVar("T")
3467        T2 = TypeVar("T2")
3468
3469        class MemoizedFunc(Protocol[P, T, T2]):
3470            cache: typing.Dict[T2, T]
3471            def __call__(self, *args: P.args, **kwargs: P.kwargs) -> T: ...
3472
3473        self.assertEqual(MemoizedFunc.__parameters__, (P, T, T2))
3474        self.assertTrue(MemoizedFunc._is_protocol)
3475
3476        with self.assertRaises(TypeError):
3477            MemoizedFunc[[int, str, str]]
3478
3479        if sys.version_info >= (3, 10):
3480            # These unfortunately don't pass on <=3.9,
3481            # due to typing._type_check on older Python versions
3482            X = MemoizedFunc[[int, str, str], T, T2]
3483            self.assertEqual(X.__parameters__, (T, T2))
3484            self.assertEqual(X.__args__, ((int, str, str), T, T2))
3485
3486            Y = X[bytes, memoryview]
3487            self.assertEqual(Y.__parameters__, ())
3488            self.assertEqual(Y.__args__, ((int, str, str), bytes, memoryview))
3489
3490    def test_protocol_generic_over_typevartuple(self):
3491        Ts = TypeVarTuple("Ts")
3492        T = TypeVar("T")
3493        T2 = TypeVar("T2")
3494
3495        class MemoizedFunc(Protocol[Unpack[Ts], T, T2]):
3496            cache: typing.Dict[T2, T]
3497            def __call__(self, *args: Unpack[Ts]) -> T: ...
3498
3499        self.assertEqual(MemoizedFunc.__parameters__, (Ts, T, T2))
3500        self.assertTrue(MemoizedFunc._is_protocol)
3501
3502        things = "arguments" if sys.version_info >= (3, 10) else "parameters"
3503
3504        # A bug was fixed in 3.11.1
3505        # (https://github.com/python/cpython/commit/74920aa27d0c57443dd7f704d6272cca9c507ab3)
3506        # That means this assertion doesn't pass on 3.11.0,
3507        # but it passes on all other Python versions
3508        if sys.version_info[:3] != (3, 11, 0):
3509            with self.assertRaisesRegex(TypeError, f"Too few {things}"):
3510                MemoizedFunc[int]
3511
3512        X = MemoizedFunc[int, T, T2]
3513        self.assertEqual(X.__parameters__, (T, T2))
3514        self.assertEqual(X.__args__, (int, T, T2))
3515
3516        Y = X[bytes, memoryview]
3517        self.assertEqual(Y.__parameters__, ())
3518        self.assertEqual(Y.__args__, (int, bytes, memoryview))
3519
3520    def test_get_protocol_members(self):
3521        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3522            get_protocol_members(object)
3523        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3524            get_protocol_members(object())
3525        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3526            get_protocol_members(Protocol)
3527        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3528            get_protocol_members(Generic)
3529
3530        class P(Protocol):
3531            a: int
3532            def b(self) -> str: ...
3533            @property
3534            def c(self) -> int: ...
3535
3536        self.assertEqual(get_protocol_members(P), {'a', 'b', 'c'})
3537        self.assertIsInstance(get_protocol_members(P), frozenset)
3538        self.assertIsNot(get_protocol_members(P), P.__protocol_attrs__)
3539
3540        class Concrete:
3541            a: int
3542            def b(self) -> str: return "capybara"
3543            @property
3544            def c(self) -> int: return 5
3545
3546        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3547            get_protocol_members(Concrete)
3548        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3549            get_protocol_members(Concrete())
3550
3551        class ConcreteInherit(P):
3552            a: int = 42
3553            def b(self) -> str: return "capybara"
3554            @property
3555            def c(self) -> int: return 5
3556
3557        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3558            get_protocol_members(ConcreteInherit)
3559        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3560            get_protocol_members(ConcreteInherit())
3561
3562    def test_get_protocol_members_typing(self):
3563        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3564            get_protocol_members(typing.Protocol)
3565
3566        class P(typing.Protocol):
3567            a: int
3568            def b(self) -> str: ...
3569            @property
3570            def c(self) -> int: ...
3571
3572        self.assertEqual(get_protocol_members(P), {'a', 'b', 'c'})
3573        self.assertIsInstance(get_protocol_members(P), frozenset)
3574        if hasattr(P, "__protocol_attrs__"):
3575            self.assertIsNot(get_protocol_members(P), P.__protocol_attrs__)
3576
3577        class Concrete:
3578            a: int
3579            def b(self) -> str: return "capybara"
3580            @property
3581            def c(self) -> int: return 5
3582
3583        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3584            get_protocol_members(Concrete)
3585        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3586            get_protocol_members(Concrete())
3587
3588        class ConcreteInherit(P):
3589            a: int = 42
3590            def b(self) -> str: return "capybara"
3591            @property
3592            def c(self) -> int: return 5
3593
3594        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3595            get_protocol_members(ConcreteInherit)
3596        with self.assertRaisesRegex(TypeError, "not a Protocol"):
3597            get_protocol_members(ConcreteInherit())
3598
3599    def test_is_protocol(self):
3600        self.assertTrue(is_protocol(Proto))
3601        self.assertTrue(is_protocol(Point))
3602        self.assertFalse(is_protocol(Concrete))
3603        self.assertFalse(is_protocol(Concrete()))
3604        self.assertFalse(is_protocol(Generic))
3605        self.assertFalse(is_protocol(object))
3606
3607        # Protocol is not itself a protocol
3608        self.assertFalse(is_protocol(Protocol))
3609
3610    def test_is_protocol_with_typing(self):
3611        self.assertFalse(is_protocol(typing.Protocol))
3612
3613        class TypingProto(typing.Protocol):
3614            a: int
3615
3616        self.assertTrue(is_protocol(TypingProto))
3617
3618        class Concrete(TypingProto):
3619            a: int
3620
3621        self.assertFalse(is_protocol(Concrete))
3622
3623    @skip_if_py312b1
3624    def test_interaction_with_isinstance_checks_on_superclasses_with_ABCMeta(self):
3625        # Ensure the cache is empty, or this test won't work correctly
3626        collections.abc.Sized._abc_registry_clear()
3627
3628        class Foo(collections.abc.Sized, Protocol): pass
3629
3630        # CPython gh-105144: this previously raised TypeError
3631        # if a Protocol subclass of Sized had been created
3632        # before any isinstance() checks against Sized
3633        self.assertNotIsInstance(1, collections.abc.Sized)
3634
3635    @skip_if_py312b1
3636    def test_interaction_with_isinstance_checks_on_superclasses_with_ABCMeta_2(self):
3637        # Ensure the cache is empty, or this test won't work correctly
3638        collections.abc.Sized._abc_registry_clear()
3639
3640        class Foo(typing.Sized, Protocol): pass
3641
3642        # CPython gh-105144: this previously raised TypeError
3643        # if a Protocol subclass of Sized had been created
3644        # before any isinstance() checks against Sized
3645        self.assertNotIsInstance(1, typing.Sized)
3646
3647    def test_empty_protocol_decorated_with_final(self):
3648        @final
3649        @runtime_checkable
3650        class EmptyProtocol(Protocol): ...
3651
3652        self.assertIsSubclass(object, EmptyProtocol)
3653        self.assertIsInstance(object(), EmptyProtocol)
3654
3655    def test_protocol_decorated_with_final_callable_members(self):
3656        @final
3657        @runtime_checkable
3658        class ProtocolWithMethod(Protocol):
3659            def startswith(self, string: str) -> bool: ...
3660
3661        self.assertIsSubclass(str, ProtocolWithMethod)
3662        self.assertNotIsSubclass(int, ProtocolWithMethod)
3663        self.assertIsInstance('foo', ProtocolWithMethod)
3664        self.assertNotIsInstance(42, ProtocolWithMethod)
3665
3666    def test_protocol_decorated_with_final_noncallable_members(self):
3667        @final
3668        @runtime_checkable
3669        class ProtocolWithNonCallableMember(Protocol):
3670            x: int
3671
3672        class Foo:
3673            x = 42
3674
3675        only_callable_members_please = (
3676            r"Protocols with non-method members don't support issubclass()"
3677        )
3678
3679        with self.assertRaisesRegex(TypeError, only_callable_members_please):
3680            issubclass(Foo, ProtocolWithNonCallableMember)
3681
3682        with self.assertRaisesRegex(TypeError, only_callable_members_please):
3683            issubclass(int, ProtocolWithNonCallableMember)
3684
3685        self.assertIsInstance(Foo(), ProtocolWithNonCallableMember)
3686        self.assertNotIsInstance(42, ProtocolWithNonCallableMember)
3687
3688    def test_protocol_decorated_with_final_mixed_members(self):
3689        @final
3690        @runtime_checkable
3691        class ProtocolWithMixedMembers(Protocol):
3692            x: int
3693            def method(self) -> None: ...
3694
3695        class Foo:
3696            x = 42
3697            def method(self) -> None: ...
3698
3699        only_callable_members_please = (
3700            r"Protocols with non-method members don't support issubclass()"
3701        )
3702
3703        with self.assertRaisesRegex(TypeError, only_callable_members_please):
3704            issubclass(Foo, ProtocolWithMixedMembers)
3705
3706        with self.assertRaisesRegex(TypeError, only_callable_members_please):
3707            issubclass(int, ProtocolWithMixedMembers)
3708
3709        self.assertIsInstance(Foo(), ProtocolWithMixedMembers)
3710        self.assertNotIsInstance(42, ProtocolWithMixedMembers)
3711
3712    def test_protocol_issubclass_error_message(self):
3713        @runtime_checkable
3714        class Vec2D(Protocol):
3715            x: float
3716            y: float
3717
3718            def square_norm(self) -> float:
3719                return self.x ** 2 + self.y ** 2
3720
3721        self.assertEqual(Vec2D.__protocol_attrs__, {'x', 'y', 'square_norm'})
3722        expected_error_message = (
3723            "Protocols with non-method members don't support issubclass()."
3724            " Non-method members: 'x', 'y'."
3725        )
3726        with self.assertRaisesRegex(TypeError, re.escape(expected_error_message)):
3727            issubclass(int, Vec2D)
3728
3729    def test_nonruntime_protocol_interaction_with_evil_classproperty(self):
3730        class classproperty:
3731            def __get__(self, instance, type):
3732                raise RuntimeError("NO")
3733
3734        class Commentable(Protocol):
3735            evil = classproperty()
3736
3737        # recognised as a protocol attr,
3738        # but not actually accessed by the protocol metaclass
3739        # (which would raise RuntimeError) for non-runtime protocols.
3740        # See gh-113320
3741        self.assertEqual(get_protocol_members(Commentable), {"evil"})
3742
3743    def test_runtime_protocol_interaction_with_evil_classproperty(self):
3744        class CustomError(Exception): pass
3745
3746        class classproperty:
3747            def __get__(self, instance, type):
3748                raise CustomError
3749
3750        with self.assertRaises(TypeError) as cm:
3751            @runtime_checkable
3752            class Commentable(Protocol):
3753                evil = classproperty()
3754
3755        exc = cm.exception
3756        self.assertEqual(
3757            exc.args[0],
3758            "Failed to determine whether protocol member 'evil' is a method member"
3759        )
3760        self.assertIs(type(exc.__cause__), CustomError)
3761
3762    def test_extensions_runtimecheckable_on_typing_Protocol(self):
3763        @runtime_checkable
3764        class Functor(typing.Protocol):
3765            def foo(self) -> None: ...
3766
3767        self.assertNotIsSubclass(object, Functor)
3768
3769        class Bar:
3770            def foo(self): pass
3771
3772        self.assertIsSubclass(Bar, Functor)
3773
3774
3775class Point2DGeneric(Generic[T], TypedDict):
3776    a: T
3777    b: T
3778
3779
3780class Bar(Foo):
3781    b: int
3782
3783
3784class BarGeneric(FooGeneric[T], total=False):
3785    b: int
3786
3787
3788class TypedDictTests(BaseTestCase):
3789    def test_basics_functional_syntax(self):
3790        Emp = TypedDict('Emp', {'name': str, 'id': int})
3791        self.assertIsSubclass(Emp, dict)
3792        self.assertIsSubclass(Emp, typing.MutableMapping)
3793        self.assertNotIsSubclass(Emp, collections.abc.Sequence)
3794        jim = Emp(name='Jim', id=1)
3795        self.assertIs(type(jim), dict)
3796        self.assertEqual(jim['name'], 'Jim')
3797        self.assertEqual(jim['id'], 1)
3798        self.assertEqual(Emp.__name__, 'Emp')
3799        self.assertEqual(Emp.__module__, __name__)
3800        self.assertEqual(Emp.__bases__, (dict,))
3801        self.assertEqual(Emp.__annotations__, {'name': str, 'id': int})
3802        self.assertEqual(Emp.__total__, True)
3803
3804    @skipIf(sys.version_info < (3, 13), "Change in behavior in 3.13")
3805    def test_keywords_syntax_raises_on_3_13(self):
3806        with self.assertRaises(TypeError), self.assertWarns(DeprecationWarning):
3807            TypedDict('Emp', name=str, id=int)
3808
3809    @skipIf(sys.version_info >= (3, 13), "3.13 removes support for kwargs")
3810    def test_basics_keywords_syntax(self):
3811        with self.assertWarns(DeprecationWarning):
3812            Emp = TypedDict('Emp', name=str, id=int)
3813        self.assertIsSubclass(Emp, dict)
3814        self.assertIsSubclass(Emp, typing.MutableMapping)
3815        self.assertNotIsSubclass(Emp, collections.abc.Sequence)
3816        jim = Emp(name='Jim', id=1)
3817        self.assertIs(type(jim), dict)
3818        self.assertEqual(jim['name'], 'Jim')
3819        self.assertEqual(jim['id'], 1)
3820        self.assertEqual(Emp.__name__, 'Emp')
3821        self.assertEqual(Emp.__module__, __name__)
3822        self.assertEqual(Emp.__bases__, (dict,))
3823        self.assertEqual(Emp.__annotations__, {'name': str, 'id': int})
3824        self.assertEqual(Emp.__total__, True)
3825
3826    @skipIf(sys.version_info >= (3, 13), "3.13 removes support for kwargs")
3827    def test_typeddict_special_keyword_names(self):
3828        with self.assertWarns(DeprecationWarning):
3829            TD = TypedDict("TD", cls=type, self=object, typename=str, _typename=int,
3830                           fields=list, _fields=dict)
3831        self.assertEqual(TD.__name__, 'TD')
3832        self.assertEqual(TD.__annotations__, {'cls': type, 'self': object, 'typename': str,
3833                                              '_typename': int, 'fields': list, '_fields': dict})
3834        a = TD(cls=str, self=42, typename='foo', _typename=53,
3835               fields=[('bar', tuple)], _fields={'baz', set})
3836        self.assertEqual(a['cls'], str)
3837        self.assertEqual(a['self'], 42)
3838        self.assertEqual(a['typename'], 'foo')
3839        self.assertEqual(a['_typename'], 53)
3840        self.assertEqual(a['fields'], [('bar', tuple)])
3841        self.assertEqual(a['_fields'], {'baz', set})
3842
3843    def test_typeddict_create_errors(self):
3844        with self.assertRaises(TypeError):
3845            TypedDict.__new__()
3846        with self.assertRaises(TypeError):
3847            TypedDict()
3848        with self.assertRaises(TypeError):
3849            TypedDict('Emp', [('name', str)], None)
3850
3851    def test_typeddict_errors(self):
3852        Emp = TypedDict('Emp', {'name': str, 'id': int})
3853        self.assertEqual(TypedDict.__module__, 'typing_extensions')
3854        jim = Emp(name='Jim', id=1)
3855        with self.assertRaises(TypeError):
3856            isinstance({}, Emp)
3857        with self.assertRaises(TypeError):
3858            isinstance(jim, Emp)
3859        with self.assertRaises(TypeError):
3860            issubclass(dict, Emp)
3861
3862        if not TYPING_3_11_0:
3863            with self.assertRaises(TypeError), self.assertWarns(DeprecationWarning):
3864                TypedDict('Hi', x=1)
3865            with self.assertRaises(TypeError):
3866                TypedDict('Hi', [('x', int), ('y', 1)])
3867        with self.assertRaises(TypeError):
3868            TypedDict('Hi', [('x', int)], y=int)
3869
3870    def test_py36_class_syntax_usage(self):
3871        self.assertEqual(LabelPoint2D.__name__, 'LabelPoint2D')
3872        self.assertEqual(LabelPoint2D.__module__, __name__)
3873        self.assertEqual(LabelPoint2D.__annotations__, {'x': int, 'y': int, 'label': str})
3874        self.assertEqual(LabelPoint2D.__bases__, (dict,))
3875        self.assertEqual(LabelPoint2D.__total__, True)
3876        self.assertNotIsSubclass(LabelPoint2D, typing.Sequence)
3877        not_origin = Point2D(x=0, y=1)
3878        self.assertEqual(not_origin['x'], 0)
3879        self.assertEqual(not_origin['y'], 1)
3880        other = LabelPoint2D(x=0, y=1, label='hi')
3881        self.assertEqual(other['label'], 'hi')
3882
3883    def test_pickle(self):
3884        global EmpD  # pickle wants to reference the class by name
3885        EmpD = TypedDict('EmpD', {'name': str, 'id': int})
3886        jane = EmpD({'name': 'jane', 'id': 37})
3887        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
3888            z = pickle.dumps(jane, proto)
3889            jane2 = pickle.loads(z)
3890            self.assertEqual(jane2, jane)
3891            self.assertEqual(jane2, {'name': 'jane', 'id': 37})
3892            ZZ = pickle.dumps(EmpD, proto)
3893            EmpDnew = pickle.loads(ZZ)
3894            self.assertEqual(EmpDnew({'name': 'jane', 'id': 37}), jane)
3895
3896    def test_pickle_generic(self):
3897        point = Point2DGeneric(a=5.0, b=3.0)
3898        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
3899            z = pickle.dumps(point, proto)
3900            point2 = pickle.loads(z)
3901            self.assertEqual(point2, point)
3902            self.assertEqual(point2, {'a': 5.0, 'b': 3.0})
3903            ZZ = pickle.dumps(Point2DGeneric, proto)
3904            Point2DGenericNew = pickle.loads(ZZ)
3905            self.assertEqual(Point2DGenericNew({'a': 5.0, 'b': 3.0}), point)
3906
3907    def test_optional(self):
3908        EmpD = TypedDict('EmpD', {'name': str, 'id': int})
3909
3910        self.assertEqual(typing.Optional[EmpD], typing.Union[None, EmpD])
3911        self.assertNotEqual(typing.List[EmpD], typing.Tuple[EmpD])
3912
3913    def test_total(self):
3914        D = TypedDict('D', {'x': int}, total=False)
3915        self.assertEqual(D(), {})
3916        self.assertEqual(D(x=1), {'x': 1})
3917        self.assertEqual(D.__total__, False)
3918        self.assertEqual(D.__required_keys__, frozenset())
3919        self.assertEqual(D.__optional_keys__, {'x'})
3920
3921        self.assertEqual(Options(), {})
3922        self.assertEqual(Options(log_level=2), {'log_level': 2})
3923        self.assertEqual(Options.__total__, False)
3924        self.assertEqual(Options.__required_keys__, frozenset())
3925        self.assertEqual(Options.__optional_keys__, {'log_level', 'log_path'})
3926
3927    def test_optional_keys(self):
3928        class Point2Dor3D(Point2D, total=False):
3929            z: int
3930
3931        assert Point2Dor3D.__required_keys__ == frozenset(['x', 'y'])
3932        assert Point2Dor3D.__optional_keys__ == frozenset(['z'])
3933
3934    def test_keys_inheritance(self):
3935        class BaseAnimal(TypedDict):
3936            name: str
3937
3938        class Animal(BaseAnimal, total=False):
3939            voice: str
3940            tail: bool
3941
3942        class Cat(Animal):
3943            fur_color: str
3944
3945        assert BaseAnimal.__required_keys__ == frozenset(['name'])
3946        assert BaseAnimal.__optional_keys__ == frozenset([])
3947        assert BaseAnimal.__annotations__ == {'name': str}
3948
3949        assert Animal.__required_keys__ == frozenset(['name'])
3950        assert Animal.__optional_keys__ == frozenset(['tail', 'voice'])
3951        assert Animal.__annotations__ == {
3952            'name': str,
3953            'tail': bool,
3954            'voice': str,
3955        }
3956
3957        assert Cat.__required_keys__ == frozenset(['name', 'fur_color'])
3958        assert Cat.__optional_keys__ == frozenset(['tail', 'voice'])
3959        assert Cat.__annotations__ == {
3960            'fur_color': str,
3961            'name': str,
3962            'tail': bool,
3963            'voice': str,
3964        }
3965
3966    def test_required_notrequired_keys(self):
3967        self.assertEqual(NontotalMovie.__required_keys__,
3968                         frozenset({"title"}))
3969        self.assertEqual(NontotalMovie.__optional_keys__,
3970                         frozenset({"year"}))
3971
3972        self.assertEqual(TotalMovie.__required_keys__,
3973                         frozenset({"title"}))
3974        self.assertEqual(TotalMovie.__optional_keys__,
3975                         frozenset({"year"}))
3976
3977        self.assertEqual(VeryAnnotated.__required_keys__,
3978                         frozenset())
3979        self.assertEqual(VeryAnnotated.__optional_keys__,
3980                         frozenset({"a"}))
3981
3982        self.assertEqual(AnnotatedMovie.__required_keys__,
3983                         frozenset({"title"}))
3984        self.assertEqual(AnnotatedMovie.__optional_keys__,
3985                         frozenset({"year"}))
3986
3987        self.assertEqual(WeirdlyQuotedMovie.__required_keys__,
3988                         frozenset({"title"}))
3989        self.assertEqual(WeirdlyQuotedMovie.__optional_keys__,
3990                         frozenset({"year"}))
3991
3992        self.assertEqual(ChildTotalMovie.__required_keys__,
3993                         frozenset({"title"}))
3994        self.assertEqual(ChildTotalMovie.__optional_keys__,
3995                         frozenset({"year"}))
3996
3997        self.assertEqual(ChildDeeplyAnnotatedMovie.__required_keys__,
3998                         frozenset({"title"}))
3999        self.assertEqual(ChildDeeplyAnnotatedMovie.__optional_keys__,
4000                         frozenset({"year"}))
4001
4002    def test_multiple_inheritance(self):
4003        class One(TypedDict):
4004            one: int
4005        class Two(TypedDict):
4006            two: str
4007        class Untotal(TypedDict, total=False):
4008            untotal: str
4009        Inline = TypedDict('Inline', {'inline': bool})
4010        class Regular:
4011            pass
4012
4013        class Child(One, Two):
4014            child: bool
4015        self.assertEqual(
4016            Child.__required_keys__,
4017            frozenset(['one', 'two', 'child']),
4018        )
4019        self.assertEqual(
4020            Child.__optional_keys__,
4021            frozenset([]),
4022        )
4023        self.assertEqual(
4024            Child.__annotations__,
4025            {'one': int, 'two': str, 'child': bool},
4026        )
4027
4028        class ChildWithOptional(One, Untotal):
4029            child: bool
4030        self.assertEqual(
4031            ChildWithOptional.__required_keys__,
4032            frozenset(['one', 'child']),
4033        )
4034        self.assertEqual(
4035            ChildWithOptional.__optional_keys__,
4036            frozenset(['untotal']),
4037        )
4038        self.assertEqual(
4039            ChildWithOptional.__annotations__,
4040            {'one': int, 'untotal': str, 'child': bool},
4041        )
4042
4043        class ChildWithTotalFalse(One, Untotal, total=False):
4044            child: bool
4045        self.assertEqual(
4046            ChildWithTotalFalse.__required_keys__,
4047            frozenset(['one']),
4048        )
4049        self.assertEqual(
4050            ChildWithTotalFalse.__optional_keys__,
4051            frozenset(['untotal', 'child']),
4052        )
4053        self.assertEqual(
4054            ChildWithTotalFalse.__annotations__,
4055            {'one': int, 'untotal': str, 'child': bool},
4056        )
4057
4058        class ChildWithInlineAndOptional(Untotal, Inline):
4059            child: bool
4060        self.assertEqual(
4061            ChildWithInlineAndOptional.__required_keys__,
4062            frozenset(['inline', 'child']),
4063        )
4064        self.assertEqual(
4065            ChildWithInlineAndOptional.__optional_keys__,
4066            frozenset(['untotal']),
4067        )
4068        self.assertEqual(
4069            ChildWithInlineAndOptional.__annotations__,
4070            {'inline': bool, 'untotal': str, 'child': bool},
4071        )
4072
4073        class Closed(TypedDict, closed=True):
4074            __extra_items__: None
4075
4076        class Unclosed(TypedDict, closed=False):
4077            ...
4078
4079        class ChildUnclosed(Closed, Unclosed):
4080            ...
4081
4082        self.assertFalse(ChildUnclosed.__closed__)
4083        self.assertEqual(ChildUnclosed.__extra_items__, type(None))
4084
4085        class ChildClosed(Unclosed, Closed):
4086            ...
4087
4088        self.assertFalse(ChildClosed.__closed__)
4089        self.assertEqual(ChildClosed.__extra_items__, type(None))
4090
4091        wrong_bases = [
4092            (One, Regular),
4093            (Regular, One),
4094            (One, Two, Regular),
4095            (Inline, Regular),
4096            (Untotal, Regular),
4097        ]
4098        for bases in wrong_bases:
4099            with self.subTest(bases=bases):
4100                with self.assertRaisesRegex(
4101                    TypeError,
4102                    'cannot inherit from both a TypedDict type and a non-TypedDict',
4103                ):
4104                    class Wrong(*bases):
4105                        pass
4106
4107    def test_is_typeddict(self):
4108        self.assertIs(is_typeddict(Point2D), True)
4109        self.assertIs(is_typeddict(Point2Dor3D), True)
4110        self.assertIs(is_typeddict(Union[str, int]), False)
4111        # classes, not instances
4112        self.assertIs(is_typeddict(Point2D()), False)
4113        call_based = TypedDict('call_based', {'a': int})
4114        self.assertIs(is_typeddict(call_based), True)
4115        self.assertIs(is_typeddict(call_based()), False)
4116
4117        T = TypeVar("T")
4118        class BarGeneric(TypedDict, Generic[T]):
4119            a: T
4120        self.assertIs(is_typeddict(BarGeneric), True)
4121        self.assertIs(is_typeddict(BarGeneric[int]), False)
4122        self.assertIs(is_typeddict(BarGeneric()), False)
4123
4124        if hasattr(typing, "TypeAliasType"):
4125            ns = {"TypedDict": TypedDict}
4126            exec("""if True:
4127                class NewGeneric[T](TypedDict):
4128                    a: T
4129            """, ns)
4130            NewGeneric = ns["NewGeneric"]
4131            self.assertIs(is_typeddict(NewGeneric), True)
4132            self.assertIs(is_typeddict(NewGeneric[int]), False)
4133            self.assertIs(is_typeddict(NewGeneric()), False)
4134
4135        # The TypedDict constructor is not itself a TypedDict
4136        self.assertIs(is_typeddict(TypedDict), False)
4137        if hasattr(typing, "TypedDict"):
4138            self.assertIs(is_typeddict(typing.TypedDict), False)
4139
4140    def test_is_typeddict_against_typeddict_from_typing(self):
4141        Point = typing.TypedDict('Point', {'x': int, 'y': int})
4142
4143        class PointDict2D(typing.TypedDict):
4144            x: int
4145            y: int
4146
4147        class PointDict3D(PointDict2D, total=False):
4148            z: int
4149
4150        assert is_typeddict(Point) is True
4151        assert is_typeddict(PointDict2D) is True
4152        assert is_typeddict(PointDict3D) is True
4153
4154    @skipUnless(HAS_FORWARD_MODULE, "ForwardRef.__forward_module__ was added in 3.9")
4155    def test_get_type_hints_cross_module_subclass(self):
4156        self.assertNotIn("_DoNotImport", globals())
4157        self.assertEqual(
4158            {k: v.__name__ for k, v in get_type_hints(Bar).items()},
4159            {'a': "_DoNotImport", 'b': "int"}
4160        )
4161
4162    def test_get_type_hints_generic(self):
4163        self.assertEqual(
4164            get_type_hints(BarGeneric),
4165            {'a': typing.Optional[T], 'b': int}
4166        )
4167
4168        class FooBarGeneric(BarGeneric[int]):
4169            c: str
4170
4171        self.assertEqual(
4172            get_type_hints(FooBarGeneric),
4173            {'a': typing.Optional[T], 'b': int, 'c': str}
4174        )
4175
4176    @skipUnless(TYPING_3_12_0, "PEP 695 required")
4177    def test_pep695_generic_typeddict(self):
4178        ns = {"TypedDict": TypedDict}
4179        exec("""if True:
4180            class A[T](TypedDict):
4181                a: T
4182            """, ns)
4183        A = ns["A"]
4184        T, = A.__type_params__
4185        self.assertIsInstance(T, TypeVar)
4186        self.assertEqual(T.__name__, 'T')
4187        self.assertEqual(A.__bases__, (Generic, dict))
4188        self.assertEqual(A.__orig_bases__, (TypedDict, Generic[T]))
4189        self.assertEqual(A.__mro__, (A, Generic, dict, object))
4190        self.assertEqual(A.__parameters__, (T,))
4191        self.assertEqual(A[str].__parameters__, ())
4192        self.assertEqual(A[str].__args__, (str,))
4193
4194    def test_generic_inheritance(self):
4195        class A(TypedDict, Generic[T]):
4196            a: T
4197
4198        self.assertEqual(A.__bases__, (Generic, dict))
4199        self.assertEqual(A.__orig_bases__, (TypedDict, Generic[T]))
4200        self.assertEqual(A.__mro__, (A, Generic, dict, object))
4201        self.assertEqual(A.__parameters__, (T,))
4202        self.assertEqual(A[str].__parameters__, ())
4203        self.assertEqual(A[str].__args__, (str,))
4204
4205        class A2(Generic[T], TypedDict):
4206            a: T
4207
4208        self.assertEqual(A2.__bases__, (Generic, dict))
4209        self.assertEqual(A2.__orig_bases__, (Generic[T], TypedDict))
4210        self.assertEqual(A2.__mro__, (A2, Generic, dict, object))
4211        self.assertEqual(A2.__parameters__, (T,))
4212        self.assertEqual(A2[str].__parameters__, ())
4213        self.assertEqual(A2[str].__args__, (str,))
4214
4215        class B(A[KT], total=False):
4216            b: KT
4217
4218        self.assertEqual(B.__bases__, (Generic, dict))
4219        self.assertEqual(B.__orig_bases__, (A[KT],))
4220        self.assertEqual(B.__mro__, (B, Generic, dict, object))
4221        self.assertEqual(B.__parameters__, (KT,))
4222        self.assertEqual(B.__total__, False)
4223        self.assertEqual(B.__optional_keys__, frozenset(['b']))
4224        self.assertEqual(B.__required_keys__, frozenset(['a']))
4225
4226        self.assertEqual(B[str].__parameters__, ())
4227        self.assertEqual(B[str].__args__, (str,))
4228        self.assertEqual(B[str].__origin__, B)
4229
4230        class C(B[int]):
4231            c: int
4232
4233        self.assertEqual(C.__bases__, (Generic, dict))
4234        self.assertEqual(C.__orig_bases__, (B[int],))
4235        self.assertEqual(C.__mro__, (C, Generic, dict, object))
4236        self.assertEqual(C.__parameters__, ())
4237        self.assertEqual(C.__total__, True)
4238        self.assertEqual(C.__optional_keys__, frozenset(['b']))
4239        self.assertEqual(C.__required_keys__, frozenset(['a', 'c']))
4240        assert C.__annotations__ == {
4241            'a': T,
4242            'b': KT,
4243            'c': int,
4244        }
4245        with self.assertRaises(TypeError):
4246            C[str]
4247
4248        class Point3D(Point2DGeneric[T], Generic[T, KT]):
4249            c: KT
4250
4251        self.assertEqual(Point3D.__bases__, (Generic, dict))
4252        self.assertEqual(Point3D.__orig_bases__, (Point2DGeneric[T], Generic[T, KT]))
4253        self.assertEqual(Point3D.__mro__, (Point3D, Generic, dict, object))
4254        self.assertEqual(Point3D.__parameters__, (T, KT))
4255        self.assertEqual(Point3D.__total__, True)
4256        self.assertEqual(Point3D.__optional_keys__, frozenset())
4257        self.assertEqual(Point3D.__required_keys__, frozenset(['a', 'b', 'c']))
4258        self.assertEqual(Point3D.__annotations__, {
4259            'a': T,
4260            'b': T,
4261            'c': KT,
4262        })
4263        self.assertEqual(Point3D[int, str].__origin__, Point3D)
4264
4265        with self.assertRaises(TypeError):
4266            Point3D[int]
4267
4268        with self.assertRaises(TypeError):
4269            class Point3D(Point2DGeneric[T], Generic[KT]):
4270                c: KT
4271
4272    def test_implicit_any_inheritance(self):
4273        class A(TypedDict, Generic[T]):
4274            a: T
4275
4276        class B(A[KT], total=False):
4277            b: KT
4278
4279        class WithImplicitAny(B):
4280            c: int
4281
4282        self.assertEqual(WithImplicitAny.__bases__, (Generic, dict,))
4283        self.assertEqual(WithImplicitAny.__mro__, (WithImplicitAny, Generic, dict, object))
4284        # Consistent with GenericTests.test_implicit_any
4285        self.assertEqual(WithImplicitAny.__parameters__, ())
4286        self.assertEqual(WithImplicitAny.__total__, True)
4287        self.assertEqual(WithImplicitAny.__optional_keys__, frozenset(['b']))
4288        self.assertEqual(WithImplicitAny.__required_keys__, frozenset(['a', 'c']))
4289        assert WithImplicitAny.__annotations__ == {
4290            'a': T,
4291            'b': KT,
4292            'c': int,
4293        }
4294        with self.assertRaises(TypeError):
4295            WithImplicitAny[str]
4296
4297    @skipUnless(TYPING_3_9_0, "Was changed in 3.9")
4298    def test_non_generic_subscript(self):
4299        # For backward compatibility, subscription works
4300        # on arbitrary TypedDict types.
4301        # (But we don't attempt to backport this misfeature onto 3.8.)
4302        class TD(TypedDict):
4303            a: T
4304        A = TD[int]
4305        self.assertEqual(A.__origin__, TD)
4306        self.assertEqual(A.__parameters__, ())
4307        self.assertEqual(A.__args__, (int,))
4308        a = A(a=1)
4309        self.assertIs(type(a), dict)
4310        self.assertEqual(a, {'a': 1})
4311
4312    def test_orig_bases(self):
4313        T = TypeVar('T')
4314
4315        class Parent(TypedDict):
4316            pass
4317
4318        class Child(Parent):
4319            pass
4320
4321        class OtherChild(Parent):
4322            pass
4323
4324        class MixedChild(Child, OtherChild, Parent):
4325            pass
4326
4327        class GenericParent(TypedDict, Generic[T]):
4328            pass
4329
4330        class GenericChild(GenericParent[int]):
4331            pass
4332
4333        class OtherGenericChild(GenericParent[str]):
4334            pass
4335
4336        class MixedGenericChild(GenericChild, OtherGenericChild, GenericParent[float]):
4337            pass
4338
4339        class MultipleGenericBases(GenericParent[int], GenericParent[float]):
4340            pass
4341
4342        CallTypedDict = TypedDict('CallTypedDict', {})
4343
4344        self.assertEqual(Parent.__orig_bases__, (TypedDict,))
4345        self.assertEqual(Child.__orig_bases__, (Parent,))
4346        self.assertEqual(OtherChild.__orig_bases__, (Parent,))
4347        self.assertEqual(MixedChild.__orig_bases__, (Child, OtherChild, Parent,))
4348        self.assertEqual(GenericParent.__orig_bases__, (TypedDict, Generic[T]))
4349        self.assertEqual(GenericChild.__orig_bases__, (GenericParent[int],))
4350        self.assertEqual(OtherGenericChild.__orig_bases__, (GenericParent[str],))
4351        self.assertEqual(MixedGenericChild.__orig_bases__, (GenericChild, OtherGenericChild, GenericParent[float]))
4352        self.assertEqual(MultipleGenericBases.__orig_bases__, (GenericParent[int], GenericParent[float]))
4353        self.assertEqual(CallTypedDict.__orig_bases__, (TypedDict,))
4354
4355    def test_zero_fields_typeddicts(self):
4356        T1 = TypedDict("T1", {})
4357        class T2(TypedDict): pass
4358        try:
4359            ns = {"TypedDict": TypedDict}
4360            exec("class T3[tvar](TypedDict): pass", ns)
4361            T3 = ns["T3"]
4362        except SyntaxError:
4363            class T3(TypedDict): pass
4364        S = TypeVar("S")
4365        class T4(TypedDict, Generic[S]): pass
4366
4367        expected_warning = re.escape(
4368            "Failing to pass a value for the 'fields' parameter is deprecated "
4369            "and will be disallowed in Python 3.15. "
4370            "To create a TypedDict class with 0 fields "
4371            "using the functional syntax, "
4372            "pass an empty dictionary, e.g. `T5 = TypedDict('T5', {})`."
4373        )
4374        with self.assertWarnsRegex(DeprecationWarning, fr"^{expected_warning}$"):
4375            T5 = TypedDict('T5')
4376
4377        expected_warning = re.escape(
4378            "Passing `None` as the 'fields' parameter is deprecated "
4379            "and will be disallowed in Python 3.15. "
4380            "To create a TypedDict class with 0 fields "
4381            "using the functional syntax, "
4382            "pass an empty dictionary, e.g. `T6 = TypedDict('T6', {})`."
4383        )
4384        with self.assertWarnsRegex(DeprecationWarning, fr"^{expected_warning}$"):
4385            T6 = TypedDict('T6', None)
4386
4387        for klass in T1, T2, T3, T4, T5, T6:
4388            with self.subTest(klass=klass.__name__):
4389                self.assertEqual(klass.__annotations__, {})
4390                self.assertEqual(klass.__required_keys__, set())
4391                self.assertEqual(klass.__optional_keys__, set())
4392                self.assertIsInstance(klass(), dict)
4393
4394    def test_readonly_inheritance(self):
4395        class Base1(TypedDict):
4396            a: ReadOnly[int]
4397
4398        class Child1(Base1):
4399            b: str
4400
4401        self.assertEqual(Child1.__readonly_keys__, frozenset({'a'}))
4402        self.assertEqual(Child1.__mutable_keys__, frozenset({'b'}))
4403
4404        class Base2(TypedDict):
4405            a: ReadOnly[int]
4406
4407        class Child2(Base2):
4408            b: str
4409
4410        self.assertEqual(Child1.__readonly_keys__, frozenset({'a'}))
4411        self.assertEqual(Child1.__mutable_keys__, frozenset({'b'}))
4412
4413    def test_make_mutable_key_readonly(self):
4414        class Base(TypedDict):
4415            a: int
4416
4417        self.assertEqual(Base.__readonly_keys__, frozenset())
4418        self.assertEqual(Base.__mutable_keys__, frozenset({'a'}))
4419
4420        class Child(Base):
4421            a: ReadOnly[int]  # type checker error, but allowed at runtime
4422
4423        self.assertEqual(Child.__readonly_keys__, frozenset({'a'}))
4424        self.assertEqual(Child.__mutable_keys__, frozenset())
4425
4426    def test_can_make_readonly_key_mutable(self):
4427        class Base(TypedDict):
4428            a: ReadOnly[int]
4429
4430        class Child(Base):
4431            a: int
4432
4433        self.assertEqual(Child.__readonly_keys__, frozenset())
4434        self.assertEqual(Child.__mutable_keys__, frozenset({'a'}))
4435
4436    def test_combine_qualifiers(self):
4437        class AllTheThings(TypedDict):
4438            a: Annotated[Required[ReadOnly[int]], "why not"]
4439            b: Required[Annotated[ReadOnly[int], "why not"]]
4440            c: ReadOnly[NotRequired[Annotated[int, "why not"]]]
4441            d: NotRequired[Annotated[int, "why not"]]
4442
4443        self.assertEqual(AllTheThings.__required_keys__, frozenset({'a', 'b'}))
4444        self.assertEqual(AllTheThings.__optional_keys__, frozenset({'c', 'd'}))
4445        self.assertEqual(AllTheThings.__readonly_keys__, frozenset({'a', 'b', 'c'}))
4446        self.assertEqual(AllTheThings.__mutable_keys__, frozenset({'d'}))
4447
4448        self.assertEqual(
4449            get_type_hints(AllTheThings, include_extras=False),
4450            {'a': int, 'b': int, 'c': int, 'd': int},
4451        )
4452        self.assertEqual(
4453            get_type_hints(AllTheThings, include_extras=True),
4454            {
4455                'a': Annotated[Required[ReadOnly[int]], 'why not'],
4456                'b': Required[Annotated[ReadOnly[int], 'why not']],
4457                'c': ReadOnly[NotRequired[Annotated[int, 'why not']]],
4458                'd': NotRequired[Annotated[int, 'why not']],
4459            },
4460        )
4461
4462    def test_extra_keys_non_readonly(self):
4463        class Base(TypedDict, closed=True):
4464            __extra_items__: str
4465
4466        class Child(Base):
4467            a: NotRequired[int]
4468
4469        self.assertEqual(Child.__required_keys__, frozenset({}))
4470        self.assertEqual(Child.__optional_keys__, frozenset({'a'}))
4471        self.assertEqual(Child.__readonly_keys__, frozenset({}))
4472        self.assertEqual(Child.__mutable_keys__, frozenset({'a'}))
4473
4474    def test_extra_keys_readonly(self):
4475        class Base(TypedDict, closed=True):
4476            __extra_items__: ReadOnly[str]
4477
4478        class Child(Base):
4479            a: NotRequired[str]
4480
4481        self.assertEqual(Child.__required_keys__, frozenset({}))
4482        self.assertEqual(Child.__optional_keys__, frozenset({'a'}))
4483        self.assertEqual(Child.__readonly_keys__, frozenset({}))
4484        self.assertEqual(Child.__mutable_keys__, frozenset({'a'}))
4485
4486    def test_extra_key_required(self):
4487        with self.assertRaisesRegex(
4488            TypeError,
4489            "Special key __extra_items__ does not support Required"
4490        ):
4491            TypedDict("A", {"__extra_items__": Required[int]}, closed=True)
4492
4493        with self.assertRaisesRegex(
4494            TypeError,
4495            "Special key __extra_items__ does not support NotRequired"
4496        ):
4497            TypedDict("A", {"__extra_items__": NotRequired[int]}, closed=True)
4498
4499    def test_regular_extra_items(self):
4500        class ExtraReadOnly(TypedDict):
4501            __extra_items__: ReadOnly[str]
4502
4503        self.assertEqual(ExtraReadOnly.__required_keys__, frozenset({'__extra_items__'}))
4504        self.assertEqual(ExtraReadOnly.__optional_keys__, frozenset({}))
4505        self.assertEqual(ExtraReadOnly.__readonly_keys__, frozenset({'__extra_items__'}))
4506        self.assertEqual(ExtraReadOnly.__mutable_keys__, frozenset({}))
4507        self.assertEqual(ExtraReadOnly.__extra_items__, None)
4508        self.assertFalse(ExtraReadOnly.__closed__)
4509
4510        class ExtraRequired(TypedDict):
4511            __extra_items__: Required[str]
4512
4513        self.assertEqual(ExtraRequired.__required_keys__, frozenset({'__extra_items__'}))
4514        self.assertEqual(ExtraRequired.__optional_keys__, frozenset({}))
4515        self.assertEqual(ExtraRequired.__readonly_keys__, frozenset({}))
4516        self.assertEqual(ExtraRequired.__mutable_keys__, frozenset({'__extra_items__'}))
4517        self.assertEqual(ExtraRequired.__extra_items__, None)
4518        self.assertFalse(ExtraRequired.__closed__)
4519
4520        class ExtraNotRequired(TypedDict):
4521            __extra_items__: NotRequired[str]
4522
4523        self.assertEqual(ExtraNotRequired.__required_keys__, frozenset({}))
4524        self.assertEqual(ExtraNotRequired.__optional_keys__, frozenset({'__extra_items__'}))
4525        self.assertEqual(ExtraNotRequired.__readonly_keys__, frozenset({}))
4526        self.assertEqual(ExtraNotRequired.__mutable_keys__, frozenset({'__extra_items__'}))
4527        self.assertEqual(ExtraNotRequired.__extra_items__, None)
4528        self.assertFalse(ExtraNotRequired.__closed__)
4529
4530    def test_closed_inheritance(self):
4531        class Base(TypedDict, closed=True):
4532            __extra_items__: ReadOnly[Union[str, None]]
4533
4534        self.assertEqual(Base.__required_keys__, frozenset({}))
4535        self.assertEqual(Base.__optional_keys__, frozenset({}))
4536        self.assertEqual(Base.__readonly_keys__, frozenset({}))
4537        self.assertEqual(Base.__mutable_keys__, frozenset({}))
4538        self.assertEqual(Base.__annotations__, {})
4539        self.assertEqual(Base.__extra_items__, ReadOnly[Union[str, None]])
4540        self.assertTrue(Base.__closed__)
4541
4542        class Child(Base):
4543            a: int
4544            __extra_items__: int
4545
4546        self.assertEqual(Child.__required_keys__, frozenset({'a', "__extra_items__"}))
4547        self.assertEqual(Child.__optional_keys__, frozenset({}))
4548        self.assertEqual(Child.__readonly_keys__, frozenset({}))
4549        self.assertEqual(Child.__mutable_keys__, frozenset({'a', "__extra_items__"}))
4550        self.assertEqual(Child.__annotations__, {"__extra_items__": int, "a": int})
4551        self.assertEqual(Child.__extra_items__, ReadOnly[Union[str, None]])
4552        self.assertFalse(Child.__closed__)
4553
4554        class GrandChild(Child, closed=True):
4555            __extra_items__: str
4556
4557        self.assertEqual(GrandChild.__required_keys__, frozenset({'a', "__extra_items__"}))
4558        self.assertEqual(GrandChild.__optional_keys__, frozenset({}))
4559        self.assertEqual(GrandChild.__readonly_keys__, frozenset({}))
4560        self.assertEqual(GrandChild.__mutable_keys__, frozenset({'a', "__extra_items__"}))
4561        self.assertEqual(GrandChild.__annotations__, {"__extra_items__": int, "a": int})
4562        self.assertEqual(GrandChild.__extra_items__, str)
4563        self.assertTrue(GrandChild.__closed__)
4564
4565    def test_implicit_extra_items(self):
4566        class Base(TypedDict):
4567            a: int
4568
4569        self.assertEqual(Base.__extra_items__, None)
4570        self.assertFalse(Base.__closed__)
4571
4572        class ChildA(Base, closed=True):
4573            ...
4574
4575        self.assertEqual(ChildA.__extra_items__, Never)
4576        self.assertTrue(ChildA.__closed__)
4577
4578        class ChildB(Base, closed=True):
4579            __extra_items__: None
4580
4581        self.assertEqual(ChildB.__extra_items__, type(None))
4582        self.assertTrue(ChildB.__closed__)
4583
4584    @skipIf(
4585        TYPING_3_13_0,
4586        "The keyword argument alternative to define a "
4587        "TypedDict type using the functional syntax is no longer supported"
4588    )
4589    def test_backwards_compatibility(self):
4590        with self.assertWarns(DeprecationWarning):
4591            TD = TypedDict("TD", closed=int)
4592        self.assertFalse(TD.__closed__)
4593        self.assertEqual(TD.__annotations__, {"closed": int})
4594
4595
4596class AnnotatedTests(BaseTestCase):
4597
4598    def test_repr(self):
4599        if hasattr(typing, 'Annotated'):
4600            mod_name = 'typing'
4601        else:
4602            mod_name = "typing_extensions"
4603        self.assertEqual(
4604            repr(Annotated[int, 4, 5]),
4605            mod_name + ".Annotated[int, 4, 5]"
4606        )
4607        self.assertEqual(
4608            repr(Annotated[List[int], 4, 5]),
4609            mod_name + ".Annotated[typing.List[int], 4, 5]"
4610        )
4611
4612    def test_flatten(self):
4613        A = Annotated[Annotated[int, 4], 5]
4614        self.assertEqual(A, Annotated[int, 4, 5])
4615        self.assertEqual(A.__metadata__, (4, 5))
4616        self.assertEqual(A.__origin__, int)
4617
4618    def test_specialize(self):
4619        L = Annotated[List[T], "my decoration"]
4620        LI = Annotated[List[int], "my decoration"]
4621        self.assertEqual(L[int], Annotated[List[int], "my decoration"])
4622        self.assertEqual(L[int].__metadata__, ("my decoration",))
4623        self.assertEqual(L[int].__origin__, List[int])
4624        with self.assertRaises(TypeError):
4625            LI[int]
4626        with self.assertRaises(TypeError):
4627            L[int, float]
4628
4629    def test_hash_eq(self):
4630        self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1)
4631        self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4])
4632        self.assertNotEqual(Annotated[int, 4, 5], Annotated[str, 4, 5])
4633        self.assertNotEqual(Annotated[int, 4], Annotated[int, 4, 4])
4634        self.assertEqual(
4635            {Annotated[int, 4, 5], Annotated[int, 4, 5], Annotated[T, 4, 5]},
4636            {Annotated[int, 4, 5], Annotated[T, 4, 5]}
4637        )
4638
4639    def test_instantiate(self):
4640        class C:
4641            classvar = 4
4642
4643            def __init__(self, x):
4644                self.x = x
4645
4646            def __eq__(self, other):
4647                if not isinstance(other, C):
4648                    return NotImplemented
4649                return other.x == self.x
4650
4651        A = Annotated[C, "a decoration"]
4652        a = A(5)
4653        c = C(5)
4654        self.assertEqual(a, c)
4655        self.assertEqual(a.x, c.x)
4656        self.assertEqual(a.classvar, c.classvar)
4657
4658    def test_instantiate_generic(self):
4659        MyCount = Annotated[typing_extensions.Counter[T], "my decoration"]
4660        self.assertEqual(MyCount([4, 4, 5]), {4: 2, 5: 1})
4661        self.assertEqual(MyCount[int]([4, 4, 5]), {4: 2, 5: 1})
4662
4663    def test_cannot_instantiate_forward(self):
4664        A = Annotated["int", (5, 6)]
4665        with self.assertRaises(TypeError):
4666            A(5)
4667
4668    def test_cannot_instantiate_type_var(self):
4669        A = Annotated[T, (5, 6)]
4670        with self.assertRaises(TypeError):
4671            A(5)
4672
4673    def test_cannot_getattr_typevar(self):
4674        with self.assertRaises(AttributeError):
4675            Annotated[T, (5, 7)].x
4676
4677    def test_attr_passthrough(self):
4678        class C:
4679            classvar = 4
4680
4681        A = Annotated[C, "a decoration"]
4682        self.assertEqual(A.classvar, 4)
4683        A.x = 5
4684        self.assertEqual(C.x, 5)
4685
4686    @skipIf(sys.version_info[:2] in ((3, 9), (3, 10)), "Waiting for bpo-46491 bugfix.")
4687    def test_special_form_containment(self):
4688        class C:
4689            classvar: Annotated[ClassVar[int], "a decoration"] = 4
4690            const: Annotated[Final[int], "Const"] = 4
4691
4692        self.assertEqual(get_type_hints(C, globals())["classvar"], ClassVar[int])
4693        self.assertEqual(get_type_hints(C, globals())["const"], Final[int])
4694
4695    def test_cannot_subclass(self):
4696        with self.assertRaisesRegex(TypeError, "Cannot subclass .*Annotated"):
4697            class C(Annotated):
4698                pass
4699
4700    def test_cannot_check_instance(self):
4701        with self.assertRaises(TypeError):
4702            isinstance(5, Annotated[int, "positive"])
4703
4704    def test_cannot_check_subclass(self):
4705        with self.assertRaises(TypeError):
4706            issubclass(int, Annotated[int, "positive"])
4707
4708    def test_pickle(self):
4709        samples = [typing.Any, typing.Union[int, str],
4710                   typing.Optional[str], Tuple[int, ...],
4711                   typing.Callable[[str], bytes],
4712                   Self, LiteralString, Never]
4713
4714        for t in samples:
4715            x = Annotated[t, "a"]
4716
4717            for prot in range(pickle.HIGHEST_PROTOCOL + 1):
4718                with self.subTest(protocol=prot, type=t):
4719                    pickled = pickle.dumps(x, prot)
4720                    restored = pickle.loads(pickled)
4721                    self.assertEqual(x, restored)
4722
4723        global _Annotated_test_G
4724
4725        class _Annotated_test_G(Generic[T]):
4726            x = 1
4727
4728        G = Annotated[_Annotated_test_G[int], "A decoration"]
4729        G.foo = 42
4730        G.bar = 'abc'
4731
4732        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
4733            z = pickle.dumps(G, proto)
4734            x = pickle.loads(z)
4735            self.assertEqual(x.foo, 42)
4736            self.assertEqual(x.bar, 'abc')
4737            self.assertEqual(x.x, 1)
4738
4739    def test_subst(self):
4740        dec = "a decoration"
4741        dec2 = "another decoration"
4742
4743        S = Annotated[T, dec2]
4744        self.assertEqual(S[int], Annotated[int, dec2])
4745
4746        self.assertEqual(S[Annotated[int, dec]], Annotated[int, dec, dec2])
4747        L = Annotated[List[T], dec]
4748
4749        self.assertEqual(L[int], Annotated[List[int], dec])
4750        with self.assertRaises(TypeError):
4751            L[int, int]
4752
4753        self.assertEqual(S[L[int]], Annotated[List[int], dec, dec2])
4754
4755        D = Annotated[Dict[KT, VT], dec]
4756        self.assertEqual(D[str, int], Annotated[Dict[str, int], dec])
4757        with self.assertRaises(TypeError):
4758            D[int]
4759
4760        It = Annotated[int, dec]
4761        with self.assertRaises(TypeError):
4762            It[None]
4763
4764        LI = L[int]
4765        with self.assertRaises(TypeError):
4766            LI[None]
4767
4768    def test_annotated_in_other_types(self):
4769        X = List[Annotated[T, 5]]
4770        self.assertEqual(X[int], List[Annotated[int, 5]])
4771
4772    def test_nested_annotated_with_unhashable_metadata(self):
4773        X = Annotated[
4774            List[Annotated[str, {"unhashable_metadata"}]],
4775            "metadata"
4776        ]
4777        self.assertEqual(X.__origin__, List[Annotated[str, {"unhashable_metadata"}]])
4778        self.assertEqual(X.__metadata__, ("metadata",))
4779
4780
4781class GetTypeHintsTests(BaseTestCase):
4782    def test_get_type_hints(self):
4783        def foobar(x: List['X']): ...
4784        X = Annotated[int, (1, 10)]
4785        self.assertEqual(
4786            get_type_hints(foobar, globals(), locals()),
4787            {'x': List[int]}
4788        )
4789        self.assertEqual(
4790            get_type_hints(foobar, globals(), locals(), include_extras=True),
4791            {'x': List[Annotated[int, (1, 10)]]}
4792        )
4793        BA = Tuple[Annotated[T, (1, 0)], ...]
4794        def barfoo(x: BA): ...
4795        self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], Tuple[T, ...])
4796        self.assertIs(
4797            get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'],
4798            BA
4799        )
4800        def barfoo2(x: typing.Callable[..., Annotated[List[T], "const"]],
4801                    y: typing.Union[int, Annotated[T, "mutable"]]): ...
4802        self.assertEqual(
4803            get_type_hints(barfoo2, globals(), locals()),
4804            {'x': typing.Callable[..., List[T]], 'y': typing.Union[int, T]}
4805        )
4806        BA2 = typing.Callable[..., List[T]]
4807        def barfoo3(x: BA2): ...
4808        self.assertIs(
4809            get_type_hints(barfoo3, globals(), locals(), include_extras=True)["x"],
4810            BA2
4811        )
4812
4813    def test_get_type_hints_refs(self):
4814
4815        Const = Annotated[T, "Const"]
4816
4817        class MySet(Generic[T]):
4818
4819            def __ior__(self, other: "Const[MySet[T]]") -> "MySet[T]":
4820                ...
4821
4822            def __iand__(self, other: Const["MySet[T]"]) -> "MySet[T]":
4823                ...
4824
4825        self.assertEqual(
4826            get_type_hints(MySet.__iand__, globals(), locals()),
4827            {'other': MySet[T], 'return': MySet[T]}
4828        )
4829
4830        self.assertEqual(
4831            get_type_hints(MySet.__iand__, globals(), locals(), include_extras=True),
4832            {'other': Const[MySet[T]], 'return': MySet[T]}
4833        )
4834
4835        self.assertEqual(
4836            get_type_hints(MySet.__ior__, globals(), locals()),
4837            {'other': MySet[T], 'return': MySet[T]}
4838        )
4839
4840    def test_get_type_hints_typeddict(self):
4841        assert get_type_hints(TotalMovie) == {'title': str, 'year': int}
4842        assert get_type_hints(TotalMovie, include_extras=True) == {
4843            'title': str,
4844            'year': NotRequired[int],
4845        }
4846
4847        assert get_type_hints(AnnotatedMovie) == {'title': str, 'year': int}
4848        assert get_type_hints(AnnotatedMovie, include_extras=True) == {
4849            'title': Annotated[Required[str], "foobar"],
4850            'year': NotRequired[Annotated[int, 2000]],
4851        }
4852
4853    def test_orig_bases(self):
4854        T = TypeVar('T')
4855
4856        class Parent(TypedDict):
4857            pass
4858
4859        class Child(Parent):
4860            pass
4861
4862        class OtherChild(Parent):
4863            pass
4864
4865        class MixedChild(Child, OtherChild, Parent):
4866            pass
4867
4868        class GenericParent(TypedDict, Generic[T]):
4869            pass
4870
4871        class GenericChild(GenericParent[int]):
4872            pass
4873
4874        class OtherGenericChild(GenericParent[str]):
4875            pass
4876
4877        class MixedGenericChild(GenericChild, OtherGenericChild, GenericParent[float]):
4878            pass
4879
4880        class MultipleGenericBases(GenericParent[int], GenericParent[float]):
4881            pass
4882
4883        CallTypedDict = TypedDict('CallTypedDict', {})
4884
4885        self.assertEqual(Parent.__orig_bases__, (TypedDict,))
4886        self.assertEqual(Child.__orig_bases__, (Parent,))
4887        self.assertEqual(OtherChild.__orig_bases__, (Parent,))
4888        self.assertEqual(MixedChild.__orig_bases__, (Child, OtherChild, Parent,))
4889        self.assertEqual(GenericParent.__orig_bases__, (TypedDict, Generic[T]))
4890        self.assertEqual(GenericChild.__orig_bases__, (GenericParent[int],))
4891        self.assertEqual(OtherGenericChild.__orig_bases__, (GenericParent[str],))
4892        self.assertEqual(MixedGenericChild.__orig_bases__, (GenericChild, OtherGenericChild, GenericParent[float]))
4893        self.assertEqual(MultipleGenericBases.__orig_bases__, (GenericParent[int], GenericParent[float]))
4894        self.assertEqual(CallTypedDict.__orig_bases__, (TypedDict,))
4895
4896
4897class TypeAliasTests(BaseTestCase):
4898    def test_canonical_usage_with_variable_annotation(self):
4899        ns = {}
4900        exec('Alias: TypeAlias = Employee', globals(), ns)
4901
4902    def test_canonical_usage_with_type_comment(self):
4903        Alias: TypeAlias = Employee  # noqa: F841
4904
4905    def test_cannot_instantiate(self):
4906        with self.assertRaises(TypeError):
4907            TypeAlias()
4908
4909    def test_no_isinstance(self):
4910        with self.assertRaises(TypeError):
4911            isinstance(42, TypeAlias)
4912
4913    def test_no_issubclass(self):
4914        with self.assertRaises(TypeError):
4915            issubclass(Employee, TypeAlias)
4916
4917        with self.assertRaises(TypeError):
4918            issubclass(TypeAlias, Employee)
4919
4920    def test_cannot_subclass(self):
4921        with self.assertRaises(TypeError):
4922            class C(TypeAlias):
4923                pass
4924
4925        with self.assertRaises(TypeError):
4926            class D(type(TypeAlias)):
4927                pass
4928
4929    def test_repr(self):
4930        if hasattr(typing, 'TypeAlias'):
4931            self.assertEqual(repr(TypeAlias), 'typing.TypeAlias')
4932        else:
4933            self.assertEqual(repr(TypeAlias), 'typing_extensions.TypeAlias')
4934
4935    def test_cannot_subscript(self):
4936        with self.assertRaises(TypeError):
4937            TypeAlias[int]
4938
4939class ParamSpecTests(BaseTestCase):
4940
4941    def test_basic_plain(self):
4942        P = ParamSpec('P')
4943        self.assertEqual(P, P)
4944        self.assertIsInstance(P, ParamSpec)
4945        self.assertEqual(P.__name__, 'P')
4946        # Should be hashable
4947        hash(P)
4948
4949    def test_repr(self):
4950        P = ParamSpec('P')
4951        P_co = ParamSpec('P_co', covariant=True)
4952        P_contra = ParamSpec('P_contra', contravariant=True)
4953        P_infer = ParamSpec('P_infer', infer_variance=True)
4954        P_2 = ParamSpec('P_2')
4955        self.assertEqual(repr(P), '~P')
4956        self.assertEqual(repr(P_2), '~P_2')
4957
4958        # Note: PEP 612 doesn't require these to be repr-ed correctly, but
4959        # just follow CPython.
4960        self.assertEqual(repr(P_co), '+P_co')
4961        self.assertEqual(repr(P_contra), '-P_contra')
4962        # On other versions we use typing.ParamSpec, but it is not aware of
4963        # infer_variance=. Not worth creating our own version of ParamSpec
4964        # for this.
4965        if hasattr(typing, 'TypeAliasType') or not hasattr(typing, 'ParamSpec'):
4966            self.assertEqual(repr(P_infer), 'P_infer')
4967        else:
4968            self.assertEqual(repr(P_infer), '~P_infer')
4969
4970    def test_variance(self):
4971        P_co = ParamSpec('P_co', covariant=True)
4972        P_contra = ParamSpec('P_contra', contravariant=True)
4973        P_infer = ParamSpec('P_infer', infer_variance=True)
4974
4975        self.assertIs(P_co.__covariant__, True)
4976        self.assertIs(P_co.__contravariant__, False)
4977        self.assertIs(P_co.__infer_variance__, False)
4978
4979        self.assertIs(P_contra.__covariant__, False)
4980        self.assertIs(P_contra.__contravariant__, True)
4981        self.assertIs(P_contra.__infer_variance__, False)
4982
4983        self.assertIs(P_infer.__covariant__, False)
4984        self.assertIs(P_infer.__contravariant__, False)
4985        self.assertIs(P_infer.__infer_variance__, True)
4986
4987    def test_valid_uses(self):
4988        P = ParamSpec('P')
4989        T = TypeVar('T')
4990        C1 = typing.Callable[P, int]
4991        self.assertEqual(C1.__args__, (P, int))
4992        self.assertEqual(C1.__parameters__, (P,))
4993        C2 = typing.Callable[P, T]
4994        self.assertEqual(C2.__args__, (P, T))
4995        self.assertEqual(C2.__parameters__, (P, T))
4996
4997        # Test collections.abc.Callable too.
4998        if sys.version_info[:2] >= (3, 9):
4999            # Note: no tests for Callable.__parameters__ here
5000            # because types.GenericAlias Callable is hardcoded to search
5001            # for tp_name "TypeVar" in C.  This was changed in 3.10.
5002            C3 = collections.abc.Callable[P, int]
5003            self.assertEqual(C3.__args__, (P, int))
5004            C4 = collections.abc.Callable[P, T]
5005            self.assertEqual(C4.__args__, (P, T))
5006
5007        # ParamSpec instances should also have args and kwargs attributes.
5008        # Note: not in dir(P) because of __class__ hacks
5009        self.assertTrue(hasattr(P, 'args'))
5010        self.assertTrue(hasattr(P, 'kwargs'))
5011
5012    @skipIf((3, 10, 0) <= sys.version_info[:3] <= (3, 10, 2), "Needs bpo-46676.")
5013    def test_args_kwargs(self):
5014        P = ParamSpec('P')
5015        P_2 = ParamSpec('P_2')
5016        # Note: not in dir(P) because of __class__ hacks
5017        self.assertTrue(hasattr(P, 'args'))
5018        self.assertTrue(hasattr(P, 'kwargs'))
5019        self.assertIsInstance(P.args, ParamSpecArgs)
5020        self.assertIsInstance(P.kwargs, ParamSpecKwargs)
5021        self.assertIs(P.args.__origin__, P)
5022        self.assertIs(P.kwargs.__origin__, P)
5023        self.assertEqual(P.args, P.args)
5024        self.assertEqual(P.kwargs, P.kwargs)
5025        self.assertNotEqual(P.args, P_2.args)
5026        self.assertNotEqual(P.kwargs, P_2.kwargs)
5027        self.assertNotEqual(P.args, P.kwargs)
5028        self.assertNotEqual(P.kwargs, P.args)
5029        self.assertNotEqual(P.args, P_2.kwargs)
5030        self.assertEqual(repr(P.args), "P.args")
5031        self.assertEqual(repr(P.kwargs), "P.kwargs")
5032
5033    def test_user_generics(self):
5034        T = TypeVar("T")
5035        P = ParamSpec("P")
5036        P_2 = ParamSpec("P_2")
5037
5038        class X(Generic[T, P]):
5039            pass
5040
5041        class Y(Protocol[T, P]):
5042            pass
5043
5044        for klass in X, Y:
5045            with self.subTest(klass=klass.__name__):
5046                G1 = klass[int, P_2]
5047                self.assertEqual(G1.__args__, (int, P_2))
5048                self.assertEqual(G1.__parameters__, (P_2,))
5049
5050                G2 = klass[int, Concatenate[int, P_2]]
5051                self.assertEqual(G2.__args__, (int, Concatenate[int, P_2]))
5052                self.assertEqual(G2.__parameters__, (P_2,))
5053
5054        # The following are some valid uses cases in PEP 612 that don't work:
5055        # These do not work in 3.9, _type_check blocks the list and ellipsis.
5056        # G3 = X[int, [int, bool]]
5057        # G4 = X[int, ...]
5058        # G5 = Z[[int, str, bool]]
5059        # Not working because this is special-cased in 3.10.
5060        # G6 = Z[int, str, bool]
5061
5062        class Z(Generic[P]):
5063            pass
5064
5065        class ProtoZ(Protocol[P]):
5066            pass
5067
5068    def test_pickle(self):
5069        global P, P_co, P_contra, P_default
5070        P = ParamSpec('P')
5071        P_co = ParamSpec('P_co', covariant=True)
5072        P_contra = ParamSpec('P_contra', contravariant=True)
5073        P_default = ParamSpec('P_default', default=[int])
5074        for proto in range(pickle.HIGHEST_PROTOCOL):
5075            with self.subTest(f'Pickle protocol {proto}'):
5076                for paramspec in (P, P_co, P_contra, P_default):
5077                    z = pickle.loads(pickle.dumps(paramspec, proto))
5078                    self.assertEqual(z.__name__, paramspec.__name__)
5079                    self.assertEqual(z.__covariant__, paramspec.__covariant__)
5080                    self.assertEqual(z.__contravariant__, paramspec.__contravariant__)
5081                    self.assertEqual(z.__bound__, paramspec.__bound__)
5082                    self.assertEqual(z.__default__, paramspec.__default__)
5083
5084    def test_eq(self):
5085        P = ParamSpec('P')
5086        self.assertEqual(P, P)
5087        self.assertEqual(hash(P), hash(P))
5088        # ParamSpec should compare by id similar to TypeVar in CPython
5089        self.assertNotEqual(ParamSpec('P'), P)
5090        self.assertIsNot(ParamSpec('P'), P)
5091        # Note: normally you don't test this as it breaks when there's
5092        # a hash collision. However, ParamSpec *must* guarantee that
5093        # as long as two objects don't have the same ID, their hashes
5094        # won't be the same.
5095        self.assertNotEqual(hash(ParamSpec('P')), hash(P))
5096
5097    def test_isinstance_results_unaffected_by_presence_of_tracing_function(self):
5098        # See https://github.com/python/typing_extensions/issues/318
5099
5100        code = textwrap.dedent(
5101            """\
5102            import sys, typing
5103
5104            def trace_call(*args):
5105                return trace_call
5106
5107            def run():
5108                sys.modules.pop("typing_extensions", None)
5109                from typing_extensions import ParamSpec
5110                return isinstance(ParamSpec("P"), typing.TypeVar)
5111
5112            isinstance_result_1 = run()
5113            sys.setprofile(trace_call)
5114            isinstance_result_2 = run()
5115            sys.stdout.write(f"{isinstance_result_1} {isinstance_result_2}")
5116            """
5117        )
5118
5119        # Run this in an isolated process or it pollutes the environment
5120        # and makes other tests fail:
5121        try:
5122            proc = subprocess.run(
5123                [sys.executable, "-c", code], check=True, capture_output=True, text=True,
5124            )
5125        except subprocess.CalledProcessError as exc:
5126            print("stdout", exc.stdout, sep="\n")
5127            print("stderr", exc.stderr, sep="\n")
5128            raise
5129
5130        # Sanity checks that assert the test is working as expected
5131        self.assertIsInstance(proc.stdout, str)
5132        result1, result2 = proc.stdout.split(" ")
5133        self.assertIn(result1, {"True", "False"})
5134        self.assertIn(result2, {"True", "False"})
5135
5136        # The actual test:
5137        self.assertEqual(result1, result2)
5138
5139
5140class ConcatenateTests(BaseTestCase):
5141    def test_basics(self):
5142        P = ParamSpec('P')
5143
5144        class MyClass: ...
5145
5146        c = Concatenate[MyClass, P]
5147        self.assertNotEqual(c, Concatenate)
5148
5149    def test_valid_uses(self):
5150        P = ParamSpec('P')
5151        T = TypeVar('T')
5152
5153        C1 = Callable[Concatenate[int, P], int]
5154        C2 = Callable[Concatenate[int, T, P], T]
5155        self.assertEqual(C1.__origin__, C2.__origin__)
5156        self.assertNotEqual(C1, C2)
5157
5158        # Test collections.abc.Callable too.
5159        if sys.version_info[:2] >= (3, 9):
5160            C3 = collections.abc.Callable[Concatenate[int, P], int]
5161            C4 = collections.abc.Callable[Concatenate[int, T, P], T]
5162            self.assertEqual(C3.__origin__, C4.__origin__)
5163            self.assertNotEqual(C3, C4)
5164
5165    def test_invalid_uses(self):
5166        P = ParamSpec('P')
5167        T = TypeVar('T')
5168
5169        with self.assertRaisesRegex(
5170            TypeError,
5171            'Cannot take a Concatenate of no types',
5172        ):
5173            Concatenate[()]
5174
5175        with self.assertRaisesRegex(
5176            TypeError,
5177            'The last parameter to Concatenate should be a ParamSpec variable',
5178        ):
5179            Concatenate[P, T]
5180
5181        if not TYPING_3_11_0:
5182            with self.assertRaisesRegex(
5183                TypeError,
5184                'each arg must be a type',
5185            ):
5186                Concatenate[1, P]
5187
5188    def test_basic_introspection(self):
5189        P = ParamSpec('P')
5190        C1 = Concatenate[int, P]
5191        C2 = Concatenate[int, T, P]
5192        self.assertEqual(C1.__origin__, Concatenate)
5193        self.assertEqual(C1.__args__, (int, P))
5194        self.assertEqual(C2.__origin__, Concatenate)
5195        self.assertEqual(C2.__args__, (int, T, P))
5196
5197    def test_eq(self):
5198        P = ParamSpec('P')
5199        C1 = Concatenate[int, P]
5200        C2 = Concatenate[int, P]
5201        C3 = Concatenate[int, T, P]
5202        self.assertEqual(C1, C2)
5203        self.assertEqual(hash(C1), hash(C2))
5204        self.assertNotEqual(C1, C3)
5205
5206
5207class TypeGuardTests(BaseTestCase):
5208    def test_basics(self):
5209        TypeGuard[int]  # OK
5210        self.assertEqual(TypeGuard[int], TypeGuard[int])
5211
5212        def foo(arg) -> TypeGuard[int]: ...
5213        self.assertEqual(gth(foo), {'return': TypeGuard[int]})
5214
5215    def test_repr(self):
5216        if hasattr(typing, 'TypeGuard'):
5217            mod_name = 'typing'
5218        else:
5219            mod_name = 'typing_extensions'
5220        self.assertEqual(repr(TypeGuard), f'{mod_name}.TypeGuard')
5221        cv = TypeGuard[int]
5222        self.assertEqual(repr(cv), f'{mod_name}.TypeGuard[int]')
5223        cv = TypeGuard[Employee]
5224        self.assertEqual(repr(cv), f'{mod_name}.TypeGuard[{__name__}.Employee]')
5225        cv = TypeGuard[Tuple[int]]
5226        self.assertEqual(repr(cv), f'{mod_name}.TypeGuard[typing.Tuple[int]]')
5227
5228    def test_cannot_subclass(self):
5229        with self.assertRaises(TypeError):
5230            class C(type(TypeGuard)):
5231                pass
5232        with self.assertRaises(TypeError):
5233            class D(type(TypeGuard[int])):
5234                pass
5235
5236    def test_cannot_init(self):
5237        with self.assertRaises(TypeError):
5238            TypeGuard()
5239        with self.assertRaises(TypeError):
5240            type(TypeGuard)()
5241        with self.assertRaises(TypeError):
5242            type(TypeGuard[Optional[int]])()
5243
5244    def test_no_isinstance(self):
5245        with self.assertRaises(TypeError):
5246            isinstance(1, TypeGuard[int])
5247        with self.assertRaises(TypeError):
5248            issubclass(int, TypeGuard)
5249
5250
5251class TypeIsTests(BaseTestCase):
5252    def test_basics(self):
5253        TypeIs[int]  # OK
5254        self.assertEqual(TypeIs[int], TypeIs[int])
5255
5256        def foo(arg) -> TypeIs[int]: ...
5257        self.assertEqual(gth(foo), {'return': TypeIs[int]})
5258
5259    def test_repr(self):
5260        if hasattr(typing, 'TypeIs'):
5261            mod_name = 'typing'
5262        else:
5263            mod_name = 'typing_extensions'
5264        self.assertEqual(repr(TypeIs), f'{mod_name}.TypeIs')
5265        cv = TypeIs[int]
5266        self.assertEqual(repr(cv), f'{mod_name}.TypeIs[int]')
5267        cv = TypeIs[Employee]
5268        self.assertEqual(repr(cv), f'{mod_name}.TypeIs[{__name__}.Employee]')
5269        cv = TypeIs[Tuple[int]]
5270        self.assertEqual(repr(cv), f'{mod_name}.TypeIs[typing.Tuple[int]]')
5271
5272    def test_cannot_subclass(self):
5273        with self.assertRaises(TypeError):
5274            class C(type(TypeIs)):
5275                pass
5276        with self.assertRaises(TypeError):
5277            class D(type(TypeIs[int])):
5278                pass
5279
5280    def test_cannot_init(self):
5281        with self.assertRaises(TypeError):
5282            TypeIs()
5283        with self.assertRaises(TypeError):
5284            type(TypeIs)()
5285        with self.assertRaises(TypeError):
5286            type(TypeIs[Optional[int]])()
5287
5288    def test_no_isinstance(self):
5289        with self.assertRaises(TypeError):
5290            isinstance(1, TypeIs[int])
5291        with self.assertRaises(TypeError):
5292            issubclass(int, TypeIs)
5293
5294
5295class LiteralStringTests(BaseTestCase):
5296    def test_basics(self):
5297        class Foo:
5298            def bar(self) -> LiteralString: ...
5299            def baz(self) -> "LiteralString": ...
5300
5301        self.assertEqual(gth(Foo.bar), {'return': LiteralString})
5302        self.assertEqual(gth(Foo.baz), {'return': LiteralString})
5303
5304    def test_get_origin(self):
5305        self.assertIsNone(get_origin(LiteralString))
5306
5307    def test_repr(self):
5308        if hasattr(typing, 'LiteralString'):
5309            mod_name = 'typing'
5310        else:
5311            mod_name = 'typing_extensions'
5312        self.assertEqual(repr(LiteralString), f'{mod_name}.LiteralString')
5313
5314    def test_cannot_subscript(self):
5315        with self.assertRaises(TypeError):
5316            LiteralString[int]
5317
5318    def test_cannot_subclass(self):
5319        with self.assertRaises(TypeError):
5320            class C(type(LiteralString)):
5321                pass
5322        with self.assertRaises(TypeError):
5323            class D(LiteralString):
5324                pass
5325
5326    def test_cannot_init(self):
5327        with self.assertRaises(TypeError):
5328            LiteralString()
5329        with self.assertRaises(TypeError):
5330            type(LiteralString)()
5331
5332    def test_no_isinstance(self):
5333        with self.assertRaises(TypeError):
5334            isinstance(1, LiteralString)
5335        with self.assertRaises(TypeError):
5336            issubclass(int, LiteralString)
5337
5338    def test_alias(self):
5339        StringTuple = Tuple[LiteralString, LiteralString]
5340        class Alias:
5341            def return_tuple(self) -> StringTuple:
5342                return ("foo", "pep" + "675")
5343
5344    def test_typevar(self):
5345        StrT = TypeVar("StrT", bound=LiteralString)
5346        self.assertIs(StrT.__bound__, LiteralString)
5347
5348    def test_pickle(self):
5349        for proto in range(pickle.HIGHEST_PROTOCOL):
5350            pickled = pickle.dumps(LiteralString, protocol=proto)
5351            self.assertIs(LiteralString, pickle.loads(pickled))
5352
5353
5354class SelfTests(BaseTestCase):
5355    def test_basics(self):
5356        class Foo:
5357            def bar(self) -> Self: ...
5358
5359        self.assertEqual(gth(Foo.bar), {'return': Self})
5360
5361    def test_repr(self):
5362        if hasattr(typing, 'Self'):
5363            mod_name = 'typing'
5364        else:
5365            mod_name = 'typing_extensions'
5366        self.assertEqual(repr(Self), f'{mod_name}.Self')
5367
5368    def test_cannot_subscript(self):
5369        with self.assertRaises(TypeError):
5370            Self[int]
5371
5372    def test_cannot_subclass(self):
5373        with self.assertRaises(TypeError):
5374            class C(type(Self)):
5375                pass
5376
5377    def test_cannot_init(self):
5378        with self.assertRaises(TypeError):
5379            Self()
5380        with self.assertRaises(TypeError):
5381            type(Self)()
5382
5383    def test_no_isinstance(self):
5384        with self.assertRaises(TypeError):
5385            isinstance(1, Self)
5386        with self.assertRaises(TypeError):
5387            issubclass(int, Self)
5388
5389    def test_alias(self):
5390        TupleSelf = Tuple[Self, Self]
5391        class Alias:
5392            def return_tuple(self) -> TupleSelf:
5393                return (self, self)
5394
5395    def test_pickle(self):
5396        for proto in range(pickle.HIGHEST_PROTOCOL):
5397            pickled = pickle.dumps(Self, protocol=proto)
5398            self.assertIs(Self, pickle.loads(pickled))
5399
5400
5401class UnpackTests(BaseTestCase):
5402    def test_basic_plain(self):
5403        Ts = TypeVarTuple('Ts')
5404        self.assertEqual(Unpack[Ts], Unpack[Ts])
5405        with self.assertRaises(TypeError):
5406            Unpack()
5407
5408    def test_repr(self):
5409        Ts = TypeVarTuple('Ts')
5410        self.assertEqual(repr(Unpack[Ts]), f'{Unpack.__module__}.Unpack[Ts]')
5411
5412    def test_cannot_subclass_vars(self):
5413        with self.assertRaises(TypeError):
5414            class V(Unpack[TypeVarTuple('Ts')]):
5415                pass
5416
5417    def test_tuple(self):
5418        Ts = TypeVarTuple('Ts')
5419        Tuple[Unpack[Ts]]
5420
5421    def test_union(self):
5422        Xs = TypeVarTuple('Xs')
5423        Ys = TypeVarTuple('Ys')
5424        self.assertEqual(
5425            Union[Unpack[Xs]],
5426            Unpack[Xs]
5427        )
5428        self.assertNotEqual(
5429            Union[Unpack[Xs]],
5430            Union[Unpack[Xs], Unpack[Ys]]
5431        )
5432        self.assertEqual(
5433            Union[Unpack[Xs], Unpack[Xs]],
5434            Unpack[Xs]
5435        )
5436        self.assertNotEqual(
5437            Union[Unpack[Xs], int],
5438            Union[Unpack[Xs]]
5439        )
5440        self.assertNotEqual(
5441            Union[Unpack[Xs], int],
5442            Union[int]
5443        )
5444        self.assertEqual(
5445            Union[Unpack[Xs], int].__args__,
5446            (Unpack[Xs], int)
5447        )
5448        self.assertEqual(
5449            Union[Unpack[Xs], int].__parameters__,
5450            (Xs,)
5451        )
5452        self.assertIs(
5453            Union[Unpack[Xs], int].__origin__,
5454            Union
5455        )
5456
5457    def test_concatenation(self):
5458        Xs = TypeVarTuple('Xs')
5459        self.assertEqual(Tuple[int, Unpack[Xs]].__args__, (int, Unpack[Xs]))
5460        self.assertEqual(Tuple[Unpack[Xs], int].__args__, (Unpack[Xs], int))
5461        self.assertEqual(Tuple[int, Unpack[Xs], str].__args__,
5462                         (int, Unpack[Xs], str))
5463        class C(Generic[Unpack[Xs]]): pass
5464        class D(Protocol[Unpack[Xs]]): pass
5465        for klass in C, D:
5466            with self.subTest(klass=klass.__name__):
5467                self.assertEqual(klass[int, Unpack[Xs]].__args__, (int, Unpack[Xs]))
5468                self.assertEqual(klass[Unpack[Xs], int].__args__, (Unpack[Xs], int))
5469                self.assertEqual(klass[int, Unpack[Xs], str].__args__,
5470                                 (int, Unpack[Xs], str))
5471
5472    def test_class(self):
5473        Ts = TypeVarTuple('Ts')
5474
5475        class C(Generic[Unpack[Ts]]): pass
5476        class D(Protocol[Unpack[Ts]]): pass
5477
5478        for klass in C, D:
5479            with self.subTest(klass=klass.__name__):
5480                self.assertEqual(klass[int].__args__, (int,))
5481                self.assertEqual(klass[int, str].__args__, (int, str))
5482
5483        with self.assertRaises(TypeError):
5484            class C(Generic[Unpack[Ts], int]): pass
5485
5486        with self.assertRaises(TypeError):
5487            class D(Protocol[Unpack[Ts], int]): pass
5488
5489        T1 = TypeVar('T')
5490        T2 = TypeVar('T')
5491        class C(Generic[T1, T2, Unpack[Ts]]): pass
5492        class D(Protocol[T1, T2, Unpack[Ts]]): pass
5493        for klass in C, D:
5494            with self.subTest(klass=klass.__name__):
5495                self.assertEqual(klass[int, str].__args__, (int, str))
5496                self.assertEqual(klass[int, str, float].__args__, (int, str, float))
5497                self.assertEqual(
5498                    klass[int, str, float, bool].__args__, (int, str, float, bool)
5499                )
5500                # A bug was fixed in 3.11.1
5501                # (https://github.com/python/cpython/commit/74920aa27d0c57443dd7f704d6272cca9c507ab3)
5502                # That means this assertion doesn't pass on 3.11.0,
5503                # but it passes on all other Python versions
5504                if sys.version_info[:3] != (3, 11, 0):
5505                    with self.assertRaises(TypeError):
5506                        klass[int]
5507
5508
5509class TypeVarTupleTests(BaseTestCase):
5510
5511    def test_basic_plain(self):
5512        Ts = TypeVarTuple('Ts')
5513        self.assertEqual(Ts, Ts)
5514        self.assertIsInstance(Ts, TypeVarTuple)
5515        Xs = TypeVarTuple('Xs')
5516        Ys = TypeVarTuple('Ys')
5517        self.assertNotEqual(Xs, Ys)
5518
5519    def test_repr(self):
5520        Ts = TypeVarTuple('Ts')
5521        self.assertEqual(repr(Ts), 'Ts')
5522
5523    def test_no_redefinition(self):
5524        self.assertNotEqual(TypeVarTuple('Ts'), TypeVarTuple('Ts'))
5525
5526    def test_cannot_subclass_vars(self):
5527        with self.assertRaises(TypeError):
5528            class V(TypeVarTuple('Ts')):
5529                pass
5530
5531    def test_cannot_subclass_var_itself(self):
5532        with self.assertRaises(TypeError):
5533            class V(TypeVarTuple):
5534                pass
5535
5536    def test_cannot_instantiate_vars(self):
5537        Ts = TypeVarTuple('Ts')
5538        with self.assertRaises(TypeError):
5539            Ts()
5540
5541    def test_tuple(self):
5542        Ts = TypeVarTuple('Ts')
5543        # Not legal at type checking time but we can't really check against it.
5544        Tuple[Ts]
5545
5546    def test_args_and_parameters(self):
5547        Ts = TypeVarTuple('Ts')
5548
5549        t = Tuple[tuple(Ts)]
5550        if sys.version_info >= (3, 11):
5551            self.assertEqual(t.__args__, (typing.Unpack[Ts],))
5552        else:
5553            self.assertEqual(t.__args__, (Unpack[Ts],))
5554        self.assertEqual(t.__parameters__, (Ts,))
5555
5556    def test_pickle(self):
5557        global Ts, Ts_default  # pickle wants to reference the class by name
5558        Ts = TypeVarTuple('Ts')
5559        Ts_default = TypeVarTuple('Ts_default', default=Unpack[Tuple[int, str]])
5560
5561        for proto in range(pickle.HIGHEST_PROTOCOL):
5562            for typevartuple in (Ts, Ts_default):
5563                z = pickle.loads(pickle.dumps(typevartuple, proto))
5564                self.assertEqual(z.__name__, typevartuple.__name__)
5565                self.assertEqual(z.__default__, typevartuple.__default__)
5566
5567
5568class FinalDecoratorTests(BaseTestCase):
5569    def test_final_unmodified(self):
5570        def func(x): ...
5571        self.assertIs(func, final(func))
5572
5573    def test_dunder_final(self):
5574        @final
5575        def func(): ...
5576        @final
5577        class Cls: ...
5578        self.assertIs(True, func.__final__)
5579        self.assertIs(True, Cls.__final__)
5580
5581        class Wrapper:
5582            __slots__ = ("func",)
5583            def __init__(self, func):
5584                self.func = func
5585            def __call__(self, *args, **kwargs):
5586                return self.func(*args, **kwargs)
5587
5588        # Check that no error is thrown if the attribute
5589        # is not writable.
5590        @final
5591        @Wrapper
5592        def wrapped(): ...
5593        self.assertIsInstance(wrapped, Wrapper)
5594        self.assertIs(False, hasattr(wrapped, "__final__"))
5595
5596        class Meta(type):
5597            @property
5598            def __final__(self): return "can't set me"
5599        @final
5600        class WithMeta(metaclass=Meta): ...
5601        self.assertEqual(WithMeta.__final__, "can't set me")
5602
5603        # Builtin classes throw TypeError if you try to set an
5604        # attribute.
5605        final(int)
5606        self.assertIs(False, hasattr(int, "__final__"))
5607
5608        # Make sure it works with common builtin decorators
5609        class Methods:
5610            @final
5611            @classmethod
5612            def clsmethod(cls): ...
5613
5614            @final
5615            @staticmethod
5616            def stmethod(): ...
5617
5618            # The other order doesn't work because property objects
5619            # don't allow attribute assignment.
5620            @property
5621            @final
5622            def prop(self): ...
5623
5624            @final
5625            @lru_cache  # noqa: B019
5626            def cached(self): ...
5627
5628        # Use getattr_static because the descriptor returns the
5629        # underlying function, which doesn't have __final__.
5630        self.assertIs(
5631            True,
5632            inspect.getattr_static(Methods, "clsmethod").__final__
5633        )
5634        self.assertIs(
5635            True,
5636            inspect.getattr_static(Methods, "stmethod").__final__
5637        )
5638        self.assertIs(True, Methods.prop.fget.__final__)
5639        self.assertIs(True, Methods.cached.__final__)
5640
5641
5642class RevealTypeTests(BaseTestCase):
5643    def test_reveal_type(self):
5644        obj = object()
5645
5646        with contextlib.redirect_stderr(io.StringIO()) as stderr:
5647            self.assertIs(obj, reveal_type(obj))
5648            self.assertEqual("Runtime type is 'object'", stderr.getvalue().strip())
5649
5650
5651class DataclassTransformTests(BaseTestCase):
5652    def test_decorator(self):
5653        def create_model(*, frozen: bool = False, kw_only: bool = True):
5654            return lambda cls: cls
5655
5656        decorated = dataclass_transform(kw_only_default=True, order_default=False)(create_model)
5657
5658        class CustomerModel:
5659            id: int
5660
5661        self.assertIs(decorated, create_model)
5662        self.assertEqual(
5663            decorated.__dataclass_transform__,
5664            {
5665                "eq_default": True,
5666                "order_default": False,
5667                "kw_only_default": True,
5668                "frozen_default": False,
5669                "field_specifiers": (),
5670                "kwargs": {},
5671            }
5672        )
5673        self.assertIs(
5674            decorated(frozen=True, kw_only=False)(CustomerModel),
5675            CustomerModel
5676        )
5677
5678    def test_base_class(self):
5679        class ModelBase:
5680            def __init_subclass__(cls, *, frozen: bool = False): ...
5681
5682        Decorated = dataclass_transform(
5683            eq_default=True,
5684            order_default=True,
5685            # Arbitrary unrecognized kwargs are accepted at runtime.
5686            make_everything_awesome=True,
5687        )(ModelBase)
5688
5689        class CustomerModel(Decorated, frozen=True):
5690            id: int
5691
5692        self.assertIs(Decorated, ModelBase)
5693        self.assertEqual(
5694            Decorated.__dataclass_transform__,
5695            {
5696                "eq_default": True,
5697                "order_default": True,
5698                "kw_only_default": False,
5699                "frozen_default": False,
5700                "field_specifiers": (),
5701                "kwargs": {"make_everything_awesome": True},
5702            }
5703        )
5704        self.assertIsSubclass(CustomerModel, Decorated)
5705
5706    def test_metaclass(self):
5707        class Field: ...
5708
5709        class ModelMeta(type):
5710            def __new__(
5711                cls, name, bases, namespace, *, init: bool = True,
5712            ):
5713                return super().__new__(cls, name, bases, namespace)
5714
5715        Decorated = dataclass_transform(
5716            order_default=True, field_specifiers=(Field,)
5717        )(ModelMeta)
5718
5719        class ModelBase(metaclass=Decorated): ...
5720
5721        class CustomerModel(ModelBase, init=False):
5722            id: int
5723
5724        self.assertIs(Decorated, ModelMeta)
5725        self.assertEqual(
5726            Decorated.__dataclass_transform__,
5727            {
5728                "eq_default": True,
5729                "order_default": True,
5730                "kw_only_default": False,
5731                "frozen_default": False,
5732                "field_specifiers": (Field,),
5733                "kwargs": {},
5734            }
5735        )
5736        self.assertIsInstance(CustomerModel, Decorated)
5737
5738
5739class AllTests(BaseTestCase):
5740
5741    def test_drop_in_for_typing(self):
5742        # Check that the typing_extensions.__all__ is a superset of
5743        # typing.__all__.
5744        t_all = set(typing.__all__)
5745        te_all = set(typing_extensions.__all__)
5746        exceptions = {"ByteString"}
5747        self.assertGreaterEqual(te_all, t_all - exceptions)
5748        # Deprecated, to be removed in 3.14
5749        self.assertFalse(hasattr(typing_extensions, "ByteString"))
5750        # These were never included in `typing.__all__`,
5751        # and have been removed in Python 3.13
5752        self.assertNotIn('re', te_all)
5753        self.assertNotIn('io', te_all)
5754
5755    def test_typing_extensions_includes_standard(self):
5756        a = typing_extensions.__all__
5757        self.assertIn('ClassVar', a)
5758        self.assertIn('Type', a)
5759        self.assertIn('ChainMap', a)
5760        self.assertIn('ContextManager', a)
5761        self.assertIn('Counter', a)
5762        self.assertIn('DefaultDict', a)
5763        self.assertIn('Deque', a)
5764        self.assertIn('NewType', a)
5765        self.assertIn('overload', a)
5766        self.assertIn('Text', a)
5767        self.assertIn('TYPE_CHECKING', a)
5768        self.assertIn('TypeAlias', a)
5769        self.assertIn('ParamSpec', a)
5770        self.assertIn("Concatenate", a)
5771
5772        self.assertIn('Annotated', a)
5773        self.assertIn('get_type_hints', a)
5774
5775        self.assertIn('Awaitable', a)
5776        self.assertIn('AsyncIterator', a)
5777        self.assertIn('AsyncIterable', a)
5778        self.assertIn('Coroutine', a)
5779        self.assertIn('AsyncContextManager', a)
5780
5781        self.assertIn('AsyncGenerator', a)
5782
5783        self.assertIn('Protocol', a)
5784        self.assertIn('runtime', a)
5785
5786        # Check that all objects in `__all__` are present in the module
5787        for name in a:
5788            self.assertTrue(hasattr(typing_extensions, name))
5789
5790    def test_all_names_in___all__(self):
5791        exclude = {
5792            'GenericMeta',
5793            'KT',
5794            'PEP_560',
5795            'T',
5796            'T_co',
5797            'T_contra',
5798            'VT',
5799        }
5800        actual_names = {
5801            name for name in dir(typing_extensions)
5802            if not name.startswith("_")
5803            and not isinstance(getattr(typing_extensions, name), types.ModuleType)
5804        }
5805        # Make sure all public names are in __all__
5806        self.assertEqual({*exclude, *typing_extensions.__all__},
5807                         actual_names)
5808        # Make sure all excluded names actually exist
5809        self.assertLessEqual(exclude, actual_names)
5810
5811    def test_typing_extensions_defers_when_possible(self):
5812        exclude = set()
5813        if sys.version_info < (3, 10):
5814            exclude |= {'get_args', 'get_origin'}
5815        if sys.version_info < (3, 10, 1):
5816            exclude |= {"Literal"}
5817        if sys.version_info < (3, 11):
5818            exclude |= {'final', 'Any', 'NewType', 'overload'}
5819        if sys.version_info < (3, 12):
5820            exclude |= {
5821                'SupportsAbs', 'SupportsBytes',
5822                'SupportsComplex', 'SupportsFloat', 'SupportsIndex', 'SupportsInt',
5823                'SupportsRound', 'Unpack', 'dataclass_transform',
5824            }
5825        if sys.version_info < (3, 13):
5826            exclude |= {
5827                'NamedTuple', 'Protocol', 'runtime_checkable', 'Generator',
5828                'AsyncGenerator', 'ContextManager', 'AsyncContextManager',
5829                'ParamSpec', 'TypeVar', 'TypeVarTuple', 'get_type_hints',
5830            }
5831        if not typing_extensions._PEP_728_IMPLEMENTED:
5832            exclude |= {'TypedDict', 'is_typeddict'}
5833        for item in typing_extensions.__all__:
5834            if item not in exclude and hasattr(typing, item):
5835                self.assertIs(
5836                    getattr(typing_extensions, item),
5837                    getattr(typing, item))
5838
5839    def test_typing_extensions_compiles_with_opt(self):
5840        file_path = typing_extensions.__file__
5841        try:
5842            subprocess.check_output(f'{sys.executable} -OO {file_path}',
5843                                    stderr=subprocess.STDOUT,
5844                                    shell=True)
5845        except subprocess.CalledProcessError:
5846            self.fail('Module does not compile with optimize=2 (-OO flag).')
5847
5848
5849class CoolEmployee(NamedTuple):
5850    name: str
5851    cool: int
5852
5853
5854class CoolEmployeeWithDefault(NamedTuple):
5855    name: str
5856    cool: int = 0
5857
5858
5859class XMeth(NamedTuple):
5860    x: int
5861
5862    def double(self):
5863        return 2 * self.x
5864
5865
5866class NamedTupleTests(BaseTestCase):
5867    class NestedEmployee(NamedTuple):
5868        name: str
5869        cool: int
5870
5871    def test_basics(self):
5872        Emp = NamedTuple('Emp', [('name', str), ('id', int)])
5873        self.assertIsSubclass(Emp, tuple)
5874        joe = Emp('Joe', 42)
5875        jim = Emp(name='Jim', id=1)
5876        self.assertIsInstance(joe, Emp)
5877        self.assertIsInstance(joe, tuple)
5878        self.assertEqual(joe.name, 'Joe')
5879        self.assertEqual(joe.id, 42)
5880        self.assertEqual(jim.name, 'Jim')
5881        self.assertEqual(jim.id, 1)
5882        self.assertEqual(Emp.__name__, 'Emp')
5883        self.assertEqual(Emp._fields, ('name', 'id'))
5884        self.assertEqual(Emp.__annotations__,
5885                         collections.OrderedDict([('name', str), ('id', int)]))
5886
5887    def test_annotation_usage(self):
5888        tim = CoolEmployee('Tim', 9000)
5889        self.assertIsInstance(tim, CoolEmployee)
5890        self.assertIsInstance(tim, tuple)
5891        self.assertEqual(tim.name, 'Tim')
5892        self.assertEqual(tim.cool, 9000)
5893        self.assertEqual(CoolEmployee.__name__, 'CoolEmployee')
5894        self.assertEqual(CoolEmployee._fields, ('name', 'cool'))
5895        self.assertEqual(CoolEmployee.__annotations__,
5896                         collections.OrderedDict(name=str, cool=int))
5897
5898    def test_annotation_usage_with_default(self):
5899        jelle = CoolEmployeeWithDefault('Jelle')
5900        self.assertIsInstance(jelle, CoolEmployeeWithDefault)
5901        self.assertIsInstance(jelle, tuple)
5902        self.assertEqual(jelle.name, 'Jelle')
5903        self.assertEqual(jelle.cool, 0)
5904        cooler_employee = CoolEmployeeWithDefault('Sjoerd', 1)
5905        self.assertEqual(cooler_employee.cool, 1)
5906
5907        self.assertEqual(CoolEmployeeWithDefault.__name__, 'CoolEmployeeWithDefault')
5908        self.assertEqual(CoolEmployeeWithDefault._fields, ('name', 'cool'))
5909        self.assertEqual(CoolEmployeeWithDefault.__annotations__,
5910                         dict(name=str, cool=int))
5911
5912        with self.assertRaisesRegex(
5913            TypeError,
5914            'Non-default namedtuple field y cannot follow default field x'
5915        ):
5916            class NonDefaultAfterDefault(NamedTuple):
5917                x: int = 3
5918                y: int
5919
5920    def test_field_defaults(self):
5921        self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0))
5922
5923    def test_annotation_usage_with_methods(self):
5924        self.assertEqual(XMeth(1).double(), 2)
5925        self.assertEqual(XMeth(42).x, XMeth(42)[0])
5926        self.assertEqual(str(XRepr(42)), '42 -> 1')
5927        self.assertEqual(XRepr(1, 2) + XRepr(3), 0)
5928
5929        bad_overwrite_error_message = 'Cannot overwrite NamedTuple attribute'
5930
5931        with self.assertRaisesRegex(AttributeError, bad_overwrite_error_message):
5932            class XMethBad(NamedTuple):
5933                x: int
5934                def _fields(self):
5935                    return 'no chance for this'
5936
5937        with self.assertRaisesRegex(AttributeError, bad_overwrite_error_message):
5938            class XMethBad2(NamedTuple):
5939                x: int
5940                def _source(self):
5941                    return 'no chance for this as well'
5942
5943    def test_multiple_inheritance(self):
5944        class A:
5945            pass
5946        with self.assertRaisesRegex(
5947            TypeError,
5948            'can only inherit from a NamedTuple type and Generic'
5949        ):
5950            class X(NamedTuple, A):
5951                x: int
5952
5953        with self.assertRaisesRegex(
5954            TypeError,
5955            'can only inherit from a NamedTuple type and Generic'
5956        ):
5957            class Y(NamedTuple, tuple):
5958                x: int
5959
5960        with self.assertRaisesRegex(TypeError, 'duplicate base class'):
5961            class Z(NamedTuple, NamedTuple):
5962                x: int
5963
5964        class A(NamedTuple):
5965            x: int
5966        with self.assertRaisesRegex(
5967            TypeError,
5968            'can only inherit from a NamedTuple type and Generic'
5969        ):
5970            class XX(NamedTuple, A):
5971                y: str
5972
5973    def test_generic(self):
5974        class X(NamedTuple, Generic[T]):
5975            x: T
5976        self.assertEqual(X.__bases__, (tuple, Generic))
5977        self.assertEqual(X.__orig_bases__, (NamedTuple, Generic[T]))
5978        self.assertEqual(X.__mro__, (X, tuple, Generic, object))
5979
5980        class Y(Generic[T], NamedTuple):
5981            x: T
5982        self.assertEqual(Y.__bases__, (Generic, tuple))
5983        self.assertEqual(Y.__orig_bases__, (Generic[T], NamedTuple))
5984        self.assertEqual(Y.__mro__, (Y, Generic, tuple, object))
5985
5986        for G in X, Y:
5987            with self.subTest(type=G):
5988                self.assertEqual(G.__parameters__, (T,))
5989                A = G[int]
5990                self.assertIs(A.__origin__, G)
5991                self.assertEqual(A.__args__, (int,))
5992                self.assertEqual(A.__parameters__, ())
5993
5994                a = A(3)
5995                self.assertIs(type(a), G)
5996                self.assertIsInstance(a, G)
5997                self.assertEqual(a.x, 3)
5998
5999                things = "arguments" if sys.version_info >= (3, 10) else "parameters"
6000                with self.assertRaisesRegex(TypeError, f'Too many {things}'):
6001                    G[int, str]
6002
6003    @skipUnless(TYPING_3_9_0, "tuple.__class_getitem__ was added in 3.9")
6004    def test_non_generic_subscript_py39_plus(self):
6005        # For backward compatibility, subscription works
6006        # on arbitrary NamedTuple types.
6007        class Group(NamedTuple):
6008            key: T
6009            group: list[T]
6010        A = Group[int]
6011        self.assertEqual(A.__origin__, Group)
6012        self.assertEqual(A.__parameters__, ())
6013        self.assertEqual(A.__args__, (int,))
6014        a = A(1, [2])
6015        self.assertIs(type(a), Group)
6016        self.assertEqual(a, (1, [2]))
6017
6018    @skipIf(TYPING_3_9_0, "Test isn't relevant to 3.9+")
6019    def test_non_generic_subscript_error_message_py38(self):
6020        class Group(NamedTuple):
6021            key: T
6022            group: List[T]
6023
6024        with self.assertRaisesRegex(TypeError, 'not subscriptable'):
6025            Group[int]
6026
6027        for attr in ('__args__', '__origin__', '__parameters__'):
6028            with self.subTest(attr=attr):
6029                self.assertFalse(hasattr(Group, attr))
6030
6031    def test_namedtuple_keyword_usage(self):
6032        with self.assertWarnsRegex(
6033            DeprecationWarning,
6034            "Creating NamedTuple classes using keyword arguments is deprecated"
6035        ):
6036            LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int)
6037
6038        nick = LocalEmployee('Nick', 25)
6039        self.assertIsInstance(nick, tuple)
6040        self.assertEqual(nick.name, 'Nick')
6041        self.assertEqual(LocalEmployee.__name__, 'LocalEmployee')
6042        self.assertEqual(LocalEmployee._fields, ('name', 'age'))
6043        self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int))
6044
6045        with self.assertRaisesRegex(
6046            TypeError,
6047            "Either list of fields or keywords can be provided to NamedTuple, not both"
6048        ):
6049            NamedTuple('Name', [('x', int)], y=str)
6050
6051        with self.assertRaisesRegex(
6052            TypeError,
6053            "Either list of fields or keywords can be provided to NamedTuple, not both"
6054        ):
6055            NamedTuple('Name', [], y=str)
6056
6057        with self.assertRaisesRegex(
6058            TypeError,
6059            (
6060                r"Cannot pass `None` as the 'fields' parameter "
6061                r"and also specify fields using keyword arguments"
6062            )
6063        ):
6064            NamedTuple('Name', None, x=int)
6065
6066    def test_namedtuple_special_keyword_names(self):
6067        with self.assertWarnsRegex(
6068            DeprecationWarning,
6069            "Creating NamedTuple classes using keyword arguments is deprecated"
6070        ):
6071            NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list)
6072
6073        self.assertEqual(NT.__name__, 'NT')
6074        self.assertEqual(NT._fields, ('cls', 'self', 'typename', 'fields'))
6075        a = NT(cls=str, self=42, typename='foo', fields=[('bar', tuple)])
6076        self.assertEqual(a.cls, str)
6077        self.assertEqual(a.self, 42)
6078        self.assertEqual(a.typename, 'foo')
6079        self.assertEqual(a.fields, [('bar', tuple)])
6080
6081    def test_empty_namedtuple(self):
6082        expected_warning = re.escape(
6083            "Failing to pass a value for the 'fields' parameter is deprecated "
6084            "and will be disallowed in Python 3.15. "
6085            "To create a NamedTuple class with 0 fields "
6086            "using the functional syntax, "
6087            "pass an empty list, e.g. `NT1 = NamedTuple('NT1', [])`."
6088        )
6089        with self.assertWarnsRegex(DeprecationWarning, fr"^{expected_warning}$"):
6090            NT1 = NamedTuple('NT1')
6091
6092        expected_warning = re.escape(
6093            "Passing `None` as the 'fields' parameter is deprecated "
6094            "and will be disallowed in Python 3.15. "
6095            "To create a NamedTuple class with 0 fields "
6096            "using the functional syntax, "
6097            "pass an empty list, e.g. `NT2 = NamedTuple('NT2', [])`."
6098        )
6099        with self.assertWarnsRegex(DeprecationWarning, fr"^{expected_warning}$"):
6100            NT2 = NamedTuple('NT2', None)
6101
6102        NT3 = NamedTuple('NT2', [])
6103
6104        class CNT(NamedTuple):
6105            pass  # empty body
6106
6107        for struct in NT1, NT2, NT3, CNT:
6108            with self.subTest(struct=struct):
6109                self.assertEqual(struct._fields, ())
6110                self.assertEqual(struct.__annotations__, {})
6111                self.assertIsInstance(struct(), struct)
6112                self.assertEqual(struct._field_defaults, {})
6113
6114    def test_namedtuple_errors(self):
6115        with self.assertRaises(TypeError):
6116            NamedTuple.__new__()
6117        with self.assertRaises(TypeError):
6118            NamedTuple()
6119        with self.assertRaises(TypeError):
6120            NamedTuple('Emp', [('name', str)], None)
6121        with self.assertRaisesRegex(ValueError, 'cannot start with an underscore'):
6122            NamedTuple('Emp', [('_name', str)])
6123        with self.assertRaises(TypeError):
6124            NamedTuple(typename='Emp', name=str, id=int)
6125
6126    def test_copy_and_pickle(self):
6127        global Emp  # pickle wants to reference the class by name
6128        Emp = NamedTuple('Emp', [('name', str), ('cool', int)])
6129        for cls in Emp, CoolEmployee, self.NestedEmployee:
6130            with self.subTest(cls=cls):
6131                jane = cls('jane', 37)
6132                for proto in range(pickle.HIGHEST_PROTOCOL + 1):
6133                    z = pickle.dumps(jane, proto)
6134                    jane2 = pickle.loads(z)
6135                    self.assertEqual(jane2, jane)
6136                    self.assertIsInstance(jane2, cls)
6137
6138                jane2 = copy.copy(jane)
6139                self.assertEqual(jane2, jane)
6140                self.assertIsInstance(jane2, cls)
6141
6142                jane2 = copy.deepcopy(jane)
6143                self.assertEqual(jane2, jane)
6144                self.assertIsInstance(jane2, cls)
6145
6146    def test_docstring(self):
6147        self.assertIsInstance(NamedTuple.__doc__, str)
6148
6149    @skipUnless(TYPING_3_9_0, "NamedTuple was a class on 3.8 and lower")
6150    def test_same_as_typing_NamedTuple_39_plus(self):
6151        self.assertEqual(
6152            set(dir(NamedTuple)) - {"__text_signature__"},
6153            set(dir(typing.NamedTuple))
6154        )
6155        self.assertIs(type(NamedTuple), type(typing.NamedTuple))
6156
6157    @skipIf(TYPING_3_9_0, "tests are only relevant to <=3.8")
6158    def test_same_as_typing_NamedTuple_38_minus(self):
6159        self.assertEqual(
6160            self.NestedEmployee.__annotations__,
6161            self.NestedEmployee._field_types
6162        )
6163
6164    def test_orig_bases(self):
6165        T = TypeVar('T')
6166
6167        class SimpleNamedTuple(NamedTuple):
6168            pass
6169
6170        class GenericNamedTuple(NamedTuple, Generic[T]):
6171            pass
6172
6173        self.assertEqual(SimpleNamedTuple.__orig_bases__, (NamedTuple,))
6174        self.assertEqual(GenericNamedTuple.__orig_bases__, (NamedTuple, Generic[T]))
6175
6176        CallNamedTuple = NamedTuple('CallNamedTuple', [])
6177
6178        self.assertEqual(CallNamedTuple.__orig_bases__, (NamedTuple,))
6179
6180    def test_setname_called_on_values_in_class_dictionary(self):
6181        class Vanilla:
6182            def __set_name__(self, owner, name):
6183                self.name = name
6184
6185        class Foo(NamedTuple):
6186            attr = Vanilla()
6187
6188        foo = Foo()
6189        self.assertEqual(len(foo), 0)
6190        self.assertNotIn('attr', Foo._fields)
6191        self.assertIsInstance(foo.attr, Vanilla)
6192        self.assertEqual(foo.attr.name, "attr")
6193
6194        class Bar(NamedTuple):
6195            attr: Vanilla = Vanilla()
6196
6197        bar = Bar()
6198        self.assertEqual(len(bar), 1)
6199        self.assertIn('attr', Bar._fields)
6200        self.assertIsInstance(bar.attr, Vanilla)
6201        self.assertEqual(bar.attr.name, "attr")
6202
6203    @skipIf(
6204        TYPING_3_12_0,
6205        "__set_name__ behaviour changed on py312+ to use BaseException.add_note()"
6206    )
6207    def test_setname_raises_the_same_as_on_other_classes_py311_minus(self):
6208        class CustomException(BaseException): pass
6209
6210        class Annoying:
6211            def __set_name__(self, owner, name):
6212                raise CustomException
6213
6214        annoying = Annoying()
6215
6216        with self.assertRaises(RuntimeError) as cm:
6217            class NormalClass:
6218                attr = annoying
6219        normal_exception = cm.exception
6220
6221        with self.assertRaises(RuntimeError) as cm:
6222            class NamedTupleClass(NamedTuple):
6223                attr = annoying
6224        namedtuple_exception = cm.exception
6225
6226        self.assertIs(type(namedtuple_exception), RuntimeError)
6227        self.assertIs(type(namedtuple_exception), type(normal_exception))
6228        self.assertEqual(len(namedtuple_exception.args), len(normal_exception.args))
6229        self.assertEqual(
6230            namedtuple_exception.args[0],
6231            normal_exception.args[0].replace("NormalClass", "NamedTupleClass")
6232        )
6233
6234        self.assertIs(type(namedtuple_exception.__cause__), CustomException)
6235        self.assertIs(
6236            type(namedtuple_exception.__cause__), type(normal_exception.__cause__)
6237        )
6238        self.assertEqual(
6239            namedtuple_exception.__cause__.args, normal_exception.__cause__.args
6240        )
6241
6242    @skipUnless(
6243        TYPING_3_12_0,
6244        "__set_name__ behaviour changed on py312+ to use BaseException.add_note()"
6245    )
6246    def test_setname_raises_the_same_as_on_other_classes_py312_plus(self):
6247        class CustomException(BaseException): pass
6248
6249        class Annoying:
6250            def __set_name__(self, owner, name):
6251                raise CustomException
6252
6253        annoying = Annoying()
6254
6255        with self.assertRaises(CustomException) as cm:
6256            class NormalClass:
6257                attr = annoying
6258        normal_exception = cm.exception
6259
6260        with self.assertRaises(CustomException) as cm:
6261            class NamedTupleClass(NamedTuple):
6262                attr = annoying
6263        namedtuple_exception = cm.exception
6264
6265        expected_note = (
6266            "Error calling __set_name__ on 'Annoying' instance "
6267            "'attr' in 'NamedTupleClass'"
6268        )
6269
6270        self.assertIs(type(namedtuple_exception), CustomException)
6271        self.assertIs(type(namedtuple_exception), type(normal_exception))
6272        self.assertEqual(namedtuple_exception.args, normal_exception.args)
6273
6274        self.assertEqual(len(namedtuple_exception.__notes__), 1)
6275        self.assertEqual(
6276            len(namedtuple_exception.__notes__), len(normal_exception.__notes__)
6277        )
6278
6279        self.assertEqual(namedtuple_exception.__notes__[0], expected_note)
6280        self.assertEqual(
6281            namedtuple_exception.__notes__[0],
6282            normal_exception.__notes__[0].replace("NormalClass", "NamedTupleClass")
6283        )
6284
6285    def test_strange_errors_when_accessing_set_name_itself(self):
6286        class CustomException(Exception): pass
6287
6288        class Meta(type):
6289            def __getattribute__(self, attr):
6290                if attr == "__set_name__":
6291                    raise CustomException
6292                return object.__getattribute__(self, attr)
6293
6294        class VeryAnnoying(metaclass=Meta): pass
6295
6296        very_annoying = VeryAnnoying()
6297
6298        with self.assertRaises(CustomException):
6299            class Foo(NamedTuple):
6300                attr = very_annoying
6301
6302
6303class TypeVarTests(BaseTestCase):
6304    def test_basic_plain(self):
6305        T = TypeVar('T')
6306        # T equals itself.
6307        self.assertEqual(T, T)
6308        # T is an instance of TypeVar
6309        self.assertIsInstance(T, TypeVar)
6310        self.assertEqual(T.__name__, 'T')
6311        self.assertEqual(T.__constraints__, ())
6312        self.assertIs(T.__bound__, None)
6313        self.assertIs(T.__covariant__, False)
6314        self.assertIs(T.__contravariant__, False)
6315        self.assertIs(T.__infer_variance__, False)
6316
6317    def test_attributes(self):
6318        T_bound = TypeVar('T_bound', bound=int)
6319        self.assertEqual(T_bound.__name__, 'T_bound')
6320        self.assertEqual(T_bound.__constraints__, ())
6321        self.assertIs(T_bound.__bound__, int)
6322
6323        T_constraints = TypeVar('T_constraints', int, str)
6324        self.assertEqual(T_constraints.__name__, 'T_constraints')
6325        self.assertEqual(T_constraints.__constraints__, (int, str))
6326        self.assertIs(T_constraints.__bound__, None)
6327
6328        T_co = TypeVar('T_co', covariant=True)
6329        self.assertEqual(T_co.__name__, 'T_co')
6330        self.assertIs(T_co.__covariant__, True)
6331        self.assertIs(T_co.__contravariant__, False)
6332        self.assertIs(T_co.__infer_variance__, False)
6333
6334        T_contra = TypeVar('T_contra', contravariant=True)
6335        self.assertEqual(T_contra.__name__, 'T_contra')
6336        self.assertIs(T_contra.__covariant__, False)
6337        self.assertIs(T_contra.__contravariant__, True)
6338        self.assertIs(T_contra.__infer_variance__, False)
6339
6340        T_infer = TypeVar('T_infer', infer_variance=True)
6341        self.assertEqual(T_infer.__name__, 'T_infer')
6342        self.assertIs(T_infer.__covariant__, False)
6343        self.assertIs(T_infer.__contravariant__, False)
6344        self.assertIs(T_infer.__infer_variance__, True)
6345
6346    def test_typevar_instance_type_error(self):
6347        T = TypeVar('T')
6348        with self.assertRaises(TypeError):
6349            isinstance(42, T)
6350
6351    def test_typevar_subclass_type_error(self):
6352        T = TypeVar('T')
6353        with self.assertRaises(TypeError):
6354            issubclass(int, T)
6355        with self.assertRaises(TypeError):
6356            issubclass(T, int)
6357
6358    def test_constrained_error(self):
6359        with self.assertRaises(TypeError):
6360            X = TypeVar('X', int)
6361            X
6362
6363    def test_union_unique(self):
6364        X = TypeVar('X')
6365        Y = TypeVar('Y')
6366        self.assertNotEqual(X, Y)
6367        self.assertEqual(Union[X], X)
6368        self.assertNotEqual(Union[X], Union[X, Y])
6369        self.assertEqual(Union[X, X], X)
6370        self.assertNotEqual(Union[X, int], Union[X])
6371        self.assertNotEqual(Union[X, int], Union[int])
6372        self.assertEqual(Union[X, int].__args__, (X, int))
6373        self.assertEqual(Union[X, int].__parameters__, (X,))
6374        self.assertIs(Union[X, int].__origin__, Union)
6375
6376    if hasattr(types, "UnionType"):
6377        def test_or(self):
6378            X = TypeVar('X')
6379            # use a string because str doesn't implement
6380            # __or__/__ror__ itself
6381            self.assertEqual(X | "x", Union[X, "x"])
6382            self.assertEqual("x" | X, Union["x", X])
6383            # make sure the order is correct
6384            self.assertEqual(get_args(X | "x"), (X, typing.ForwardRef("x")))
6385            self.assertEqual(get_args("x" | X), (typing.ForwardRef("x"), X))
6386
6387    def test_union_constrained(self):
6388        A = TypeVar('A', str, bytes)
6389        self.assertNotEqual(Union[A, str], Union[A])
6390
6391    def test_repr(self):
6392        self.assertEqual(repr(T), '~T')
6393        self.assertEqual(repr(KT), '~KT')
6394        self.assertEqual(repr(VT), '~VT')
6395        self.assertEqual(repr(AnyStr), '~AnyStr')
6396        T_co = TypeVar('T_co', covariant=True)
6397        self.assertEqual(repr(T_co), '+T_co')
6398        T_contra = TypeVar('T_contra', contravariant=True)
6399        self.assertEqual(repr(T_contra), '-T_contra')
6400
6401    def test_no_redefinition(self):
6402        self.assertNotEqual(TypeVar('T'), TypeVar('T'))
6403        self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str))
6404
6405    def test_cannot_subclass(self):
6406        with self.assertRaises(TypeError):
6407            class V(TypeVar): pass
6408        T = TypeVar("T")
6409        with self.assertRaises(TypeError):
6410            class W(T): pass
6411
6412    def test_cannot_instantiate_vars(self):
6413        with self.assertRaises(TypeError):
6414            TypeVar('A')()
6415
6416    def test_bound_errors(self):
6417        with self.assertRaises(TypeError):
6418            TypeVar('X', bound=Union)
6419        with self.assertRaises(TypeError):
6420            TypeVar('X', str, float, bound=Employee)
6421        with self.assertRaisesRegex(TypeError,
6422                                    r"Bound must be a type\. Got \(1, 2\)\."):
6423            TypeVar('X', bound=(1, 2))
6424
6425    # Technically we could run it on later versions of 3.8,
6426    # but that's not worth the effort.
6427    @skipUnless(TYPING_3_9_0, "Fix was not backported")
6428    def test_missing__name__(self):
6429        # See bpo-39942
6430        code = ("import typing\n"
6431                "T = typing.TypeVar('T')\n"
6432                )
6433        exec(code, {})
6434
6435    def test_no_bivariant(self):
6436        with self.assertRaises(ValueError):
6437            TypeVar('T', covariant=True, contravariant=True)
6438
6439    def test_cannot_combine_explicit_and_infer(self):
6440        with self.assertRaises(ValueError):
6441            TypeVar('T', covariant=True, infer_variance=True)
6442        with self.assertRaises(ValueError):
6443            TypeVar('T', contravariant=True, infer_variance=True)
6444
6445
6446class TypeVarLikeDefaultsTests(BaseTestCase):
6447    def test_typevar(self):
6448        T = typing_extensions.TypeVar('T', default=int)
6449        typing_T = typing.TypeVar('T')
6450        self.assertEqual(T.__default__, int)
6451        self.assertIsInstance(T, typing_extensions.TypeVar)
6452        self.assertIsInstance(T, typing.TypeVar)
6453        self.assertIsInstance(typing_T, typing.TypeVar)
6454        self.assertIsInstance(typing_T, typing_extensions.TypeVar)
6455
6456        class A(Generic[T]): ...
6457        self.assertEqual(Optional[T].__args__, (T, type(None)))
6458
6459    def test_typevar_none(self):
6460        U = typing_extensions.TypeVar('U')
6461        U_None = typing_extensions.TypeVar('U_None', default=None)
6462        self.assertIs(U.__default__, NoDefault)
6463        self.assertFalse(U.has_default())
6464        self.assertEqual(U_None.__default__, None)
6465        self.assertTrue(U_None.has_default())
6466
6467    def test_paramspec(self):
6468        P = ParamSpec('P', default=[str, int])
6469        self.assertEqual(P.__default__, [str, int])
6470        self.assertTrue(P.has_default())
6471        self.assertIsInstance(P, ParamSpec)
6472        if hasattr(typing, "ParamSpec"):
6473            self.assertIsInstance(P, typing.ParamSpec)
6474            typing_P = typing.ParamSpec('P')
6475            self.assertIsInstance(typing_P, typing.ParamSpec)
6476            self.assertIsInstance(typing_P, ParamSpec)
6477
6478        class A(Generic[P]): ...
6479        self.assertEqual(typing.Callable[P, None].__args__, (P, type(None)))
6480
6481        P_default = ParamSpec('P_default', default=...)
6482        self.assertIs(P_default.__default__, ...)
6483        self.assertTrue(P_default.has_default())
6484
6485    def test_paramspec_none(self):
6486        U = ParamSpec('U')
6487        U_None = ParamSpec('U_None', default=None)
6488        self.assertIs(U.__default__, NoDefault)
6489        self.assertFalse(U.has_default())
6490        self.assertIs(U_None.__default__, None)
6491        self.assertTrue(U_None.has_default())
6492
6493    def test_typevartuple(self):
6494        Ts = TypeVarTuple('Ts', default=Unpack[Tuple[str, int]])
6495        self.assertEqual(Ts.__default__, Unpack[Tuple[str, int]])
6496        self.assertIsInstance(Ts, TypeVarTuple)
6497        self.assertTrue(Ts.has_default())
6498        if hasattr(typing, "TypeVarTuple"):
6499            self.assertIsInstance(Ts, typing.TypeVarTuple)
6500            typing_Ts = typing.TypeVarTuple('Ts')
6501            self.assertIsInstance(typing_Ts, typing.TypeVarTuple)
6502            self.assertIsInstance(typing_Ts, TypeVarTuple)
6503
6504        class A(Generic[Unpack[Ts]]): ...
6505        self.assertEqual(Optional[Unpack[Ts]].__args__, (Unpack[Ts], type(None)))
6506
6507    @skipIf(
6508        sys.version_info < (3, 11, 1),
6509        "Not yet backported for older versions of Python"
6510    )
6511    def test_typevartuple_specialization(self):
6512        T = TypeVar("T")
6513        Ts = TypeVarTuple('Ts', default=Unpack[Tuple[str, int]])
6514        self.assertEqual(Ts.__default__, Unpack[Tuple[str, int]])
6515        class A(Generic[T, Unpack[Ts]]): ...
6516        self.assertEqual(A[float].__args__, (float, str, int))
6517        self.assertEqual(A[float, range].__args__, (float, range))
6518        self.assertEqual(A[float, Unpack[tuple[int, ...]]].__args__, (float, Unpack[tuple[int, ...]]))
6519
6520    @skipIf(
6521        sys.version_info < (3, 11, 1),
6522        "Not yet backported for older versions of Python"
6523    )
6524    def test_typevar_and_typevartuple_specialization(self):
6525        T = TypeVar("T")
6526        U = TypeVar("U", default=float)
6527        Ts = TypeVarTuple('Ts', default=Unpack[Tuple[str, int]])
6528        self.assertEqual(Ts.__default__, Unpack[Tuple[str, int]])
6529        class A(Generic[T, U, Unpack[Ts]]): ...
6530        self.assertEqual(A[int].__args__, (int, float, str, int))
6531        self.assertEqual(A[int, str].__args__, (int, str, str, int))
6532        self.assertEqual(A[int, str, range].__args__, (int, str, range))
6533        self.assertEqual(A[int, str, Unpack[tuple[int, ...]]].__args__, (int, str, Unpack[tuple[int, ...]]))
6534
6535    def test_no_default_after_typevar_tuple(self):
6536        T = TypeVar("T", default=int)
6537        Ts = TypeVarTuple("Ts")
6538        Ts_default = TypeVarTuple("Ts_default", default=Unpack[Tuple[str, int]])
6539
6540        with self.assertRaises(TypeError):
6541            class X(Generic[Unpack[Ts], T]): ...
6542
6543        with self.assertRaises(TypeError):
6544            class Y(Generic[Unpack[Ts_default], T]): ...
6545
6546    def test_typevartuple_none(self):
6547        U = TypeVarTuple('U')
6548        U_None = TypeVarTuple('U_None', default=None)
6549        self.assertIs(U.__default__, NoDefault)
6550        self.assertFalse(U.has_default())
6551        self.assertIs(U_None.__default__, None)
6552        self.assertTrue(U_None.has_default())
6553
6554    def test_no_default_after_non_default(self):
6555        DefaultStrT = typing_extensions.TypeVar('DefaultStrT', default=str)
6556        T = TypeVar('T')
6557
6558        with self.assertRaises(TypeError):
6559            Generic[DefaultStrT, T]
6560
6561    def test_need_more_params(self):
6562        DefaultStrT = typing_extensions.TypeVar('DefaultStrT', default=str)
6563        T = typing_extensions.TypeVar('T')
6564        U = typing_extensions.TypeVar('U')
6565
6566        class A(Generic[T, U, DefaultStrT]): ...
6567        A[int, bool]
6568        A[int, bool, str]
6569
6570        with self.assertRaises(
6571            TypeError, msg="Too few arguments for .+; actual 1, expected at least 2"
6572        ):
6573            A[int]
6574
6575    def test_pickle(self):
6576        global U, U_co, U_contra, U_default  # pickle wants to reference the class by name
6577        U = typing_extensions.TypeVar('U')
6578        U_co = typing_extensions.TypeVar('U_co', covariant=True)
6579        U_contra = typing_extensions.TypeVar('U_contra', contravariant=True)
6580        U_default = typing_extensions.TypeVar('U_default', default=int)
6581        for proto in range(pickle.HIGHEST_PROTOCOL):
6582            for typevar in (U, U_co, U_contra, U_default):
6583                z = pickle.loads(pickle.dumps(typevar, proto))
6584                self.assertEqual(z.__name__, typevar.__name__)
6585                self.assertEqual(z.__covariant__, typevar.__covariant__)
6586                self.assertEqual(z.__contravariant__, typevar.__contravariant__)
6587                self.assertEqual(z.__bound__, typevar.__bound__)
6588                self.assertEqual(z.__default__, typevar.__default__)
6589
6590    def test_strange_defaults_are_allowed(self):
6591        # Leave it to type checkers to check whether strange default values
6592        # should be allowed or disallowed
6593        def not_a_type(): ...
6594
6595        for typevarlike_cls in TypeVar, ParamSpec, TypeVarTuple:
6596            for default in not_a_type, 42, bytearray(), (int, not_a_type, 42):
6597                with self.subTest(typevarlike_cls=typevarlike_cls, default=default):
6598                    T = typevarlike_cls("T", default=default)
6599                    self.assertEqual(T.__default__, default)
6600
6601    @skip_if_py313_beta_1
6602    def test_allow_default_after_non_default_in_alias(self):
6603        T_default = TypeVar('T_default', default=int)
6604        T = TypeVar('T')
6605        Ts = TypeVarTuple('Ts')
6606
6607        a1 = Callable[[T_default], T]
6608        self.assertEqual(a1.__args__, (T_default, T))
6609
6610        if sys.version_info >= (3, 9):
6611            a2 = dict[T_default, T]
6612            self.assertEqual(a2.__args__, (T_default, T))
6613
6614        a3 = typing.Dict[T_default, T]
6615        self.assertEqual(a3.__args__, (T_default, T))
6616
6617        a4 = Callable[[Unpack[Ts]], T]
6618        self.assertEqual(a4.__args__, (Unpack[Ts], T))
6619
6620    @skipIf(
6621        typing_extensions.Protocol is typing.Protocol,
6622        "Test currently fails with the CPython version of Protocol and that's not our fault"
6623    )
6624    def test_generic_with_broken_eq(self):
6625        # See https://github.com/python/typing_extensions/pull/422 for context
6626        class BrokenEq(type):
6627            def __eq__(self, other):
6628                if other is typing_extensions.Protocol:
6629                    raise TypeError("I'm broken")
6630                return False
6631
6632        class G(Generic[T], metaclass=BrokenEq):
6633            pass
6634
6635        alias = G[int]
6636        self.assertIs(get_origin(alias), G)
6637        self.assertEqual(get_args(alias), (int,))
6638
6639    @skipIf(
6640        sys.version_info < (3, 11, 1),
6641        "Not yet backported for older versions of Python"
6642    )
6643    def test_paramspec_specialization(self):
6644        T = TypeVar("T")
6645        P = ParamSpec('P', default=[str, int])
6646        self.assertEqual(P.__default__, [str, int])
6647        class A(Generic[T, P]): ...
6648        self.assertEqual(A[float].__args__, (float, (str, int)))
6649        self.assertEqual(A[float, [range]].__args__, (float, (range,)))
6650
6651    @skipIf(
6652        sys.version_info < (3, 11, 1),
6653        "Not yet backported for older versions of Python"
6654    )
6655    def test_typevar_and_paramspec_specialization(self):
6656        T = TypeVar("T")
6657        U = TypeVar("U", default=float)
6658        P = ParamSpec('P', default=[str, int])
6659        self.assertEqual(P.__default__, [str, int])
6660        class A(Generic[T, U, P]): ...
6661        self.assertEqual(A[float].__args__, (float, float, (str, int)))
6662        self.assertEqual(A[float, int].__args__, (float, int, (str, int)))
6663        self.assertEqual(A[float, int, [range]].__args__, (float, int, (range,)))
6664
6665    @skipIf(
6666        sys.version_info < (3, 11, 1),
6667        "Not yet backported for older versions of Python"
6668    )
6669    def test_paramspec_and_typevar_specialization(self):
6670        T = TypeVar("T")
6671        P = ParamSpec('P', default=[str, int])
6672        U = TypeVar("U", default=float)
6673        self.assertEqual(P.__default__, [str, int])
6674        class A(Generic[T, P, U]): ...
6675        self.assertEqual(A[float].__args__, (float, (str, int), float))
6676        self.assertEqual(A[float, [range]].__args__, (float, (range,), float))
6677        self.assertEqual(A[float, [range], int].__args__, (float, (range,), int))
6678
6679
6680class NoDefaultTests(BaseTestCase):
6681    @skip_if_py313_beta_1
6682    def test_pickling(self):
6683        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
6684            s = pickle.dumps(NoDefault, proto)
6685            loaded = pickle.loads(s)
6686            self.assertIs(NoDefault, loaded)
6687
6688    @skip_if_py313_beta_1
6689    def test_doc(self):
6690        self.assertIsInstance(NoDefault.__doc__, str)
6691
6692    def test_constructor(self):
6693        self.assertIs(NoDefault, type(NoDefault)())
6694        with self.assertRaises(TypeError):
6695            type(NoDefault)(1)
6696
6697    def test_repr(self):
6698        self.assertRegex(repr(NoDefault), r'typing(_extensions)?\.NoDefault')
6699
6700    def test_no_call(self):
6701        with self.assertRaises(TypeError):
6702            NoDefault()
6703
6704    @skip_if_py313_beta_1
6705    def test_immutable(self):
6706        with self.assertRaises(AttributeError):
6707            NoDefault.foo = 'bar'
6708        with self.assertRaises(AttributeError):
6709            NoDefault.foo
6710
6711        # TypeError is consistent with the behavior of NoneType
6712        with self.assertRaises(TypeError):
6713            type(NoDefault).foo = 3
6714        with self.assertRaises(AttributeError):
6715            type(NoDefault).foo
6716
6717
6718class TypeVarInferVarianceTests(BaseTestCase):
6719    def test_typevar(self):
6720        T = typing_extensions.TypeVar('T')
6721        self.assertFalse(T.__infer_variance__)
6722        T_infer = typing_extensions.TypeVar('T_infer', infer_variance=True)
6723        self.assertTrue(T_infer.__infer_variance__)
6724        T_noinfer = typing_extensions.TypeVar('T_noinfer', infer_variance=False)
6725        self.assertFalse(T_noinfer.__infer_variance__)
6726
6727    def test_pickle(self):
6728        global U, U_infer  # pickle wants to reference the class by name
6729        U = typing_extensions.TypeVar('U')
6730        U_infer = typing_extensions.TypeVar('U_infer', infer_variance=True)
6731        for proto in range(pickle.HIGHEST_PROTOCOL):
6732            for typevar in (U, U_infer):
6733                z = pickle.loads(pickle.dumps(typevar, proto))
6734                self.assertEqual(z.__name__, typevar.__name__)
6735                self.assertEqual(z.__covariant__, typevar.__covariant__)
6736                self.assertEqual(z.__contravariant__, typevar.__contravariant__)
6737                self.assertEqual(z.__bound__, typevar.__bound__)
6738                self.assertEqual(z.__infer_variance__, typevar.__infer_variance__)
6739
6740
6741class BufferTests(BaseTestCase):
6742    def test(self):
6743        self.assertIsInstance(memoryview(b''), Buffer)
6744        self.assertIsInstance(bytearray(), Buffer)
6745        self.assertIsInstance(b"x", Buffer)
6746        self.assertNotIsInstance(1, Buffer)
6747
6748        self.assertIsSubclass(bytearray, Buffer)
6749        self.assertIsSubclass(memoryview, Buffer)
6750        self.assertIsSubclass(bytes, Buffer)
6751        self.assertNotIsSubclass(int, Buffer)
6752
6753        class MyRegisteredBuffer:
6754            def __buffer__(self, flags: int) -> memoryview:
6755                return memoryview(b'')
6756
6757        # On 3.12, collections.abc.Buffer does a structural compatibility check
6758        if TYPING_3_12_0:
6759            self.assertIsInstance(MyRegisteredBuffer(), Buffer)
6760            self.assertIsSubclass(MyRegisteredBuffer, Buffer)
6761        else:
6762            self.assertNotIsInstance(MyRegisteredBuffer(), Buffer)
6763            self.assertNotIsSubclass(MyRegisteredBuffer, Buffer)
6764        Buffer.register(MyRegisteredBuffer)
6765        self.assertIsInstance(MyRegisteredBuffer(), Buffer)
6766        self.assertIsSubclass(MyRegisteredBuffer, Buffer)
6767
6768        class MySubclassedBuffer(Buffer):
6769            def __buffer__(self, flags: int) -> memoryview:
6770                return memoryview(b'')
6771
6772        self.assertIsInstance(MySubclassedBuffer(), Buffer)
6773        self.assertIsSubclass(MySubclassedBuffer, Buffer)
6774
6775
6776class GetOriginalBasesTests(BaseTestCase):
6777    def test_basics(self):
6778        T = TypeVar('T')
6779        class A: pass
6780        class B(Generic[T]): pass
6781        class C(B[int]): pass
6782        class D(B[str], float): pass
6783        self.assertEqual(get_original_bases(A), (object,))
6784        self.assertEqual(get_original_bases(B), (Generic[T],))
6785        self.assertEqual(get_original_bases(C), (B[int],))
6786        self.assertEqual(get_original_bases(int), (object,))
6787        self.assertEqual(get_original_bases(D), (B[str], float))
6788
6789        with self.assertRaisesRegex(TypeError, "Expected an instance of type"):
6790            get_original_bases(object())
6791
6792    @skipUnless(TYPING_3_9_0, "PEP 585 is yet to be")
6793    def test_builtin_generics(self):
6794        class E(list[T]): pass
6795        class F(list[int]): pass
6796
6797        self.assertEqual(get_original_bases(E), (list[T],))
6798        self.assertEqual(get_original_bases(F), (list[int],))
6799
6800    @skipIf(
6801        sys.version_info[:3] == (3, 12, 0) and sys.version_info[3] in {"alpha", "beta"},
6802        "Early versions of py312 had a bug"
6803    )
6804    def test_concrete_subclasses_of_generic_classes(self):
6805        T = TypeVar("T")
6806
6807        class FirstBase(Generic[T]): pass
6808        class SecondBase(Generic[T]): pass
6809        class First(FirstBase[int]): pass
6810        class Second(SecondBase[int]): pass
6811        class G(First, Second): pass
6812        self.assertEqual(get_original_bases(G), (First, Second))
6813
6814        class First_(Generic[T]): pass
6815        class Second_(Generic[T]): pass
6816        class H(First_, Second_): pass
6817        self.assertEqual(get_original_bases(H), (First_, Second_))
6818
6819    def test_namedtuples(self):
6820        # On 3.12, this should work well with typing.NamedTuple and typing_extensions.NamedTuple
6821        # On lower versions, it will only work fully with typing_extensions.NamedTuple
6822        if sys.version_info >= (3, 12):
6823            namedtuple_classes = (typing.NamedTuple, typing_extensions.NamedTuple)
6824        else:
6825            namedtuple_classes = (typing_extensions.NamedTuple,)
6826
6827        for NamedTuple in namedtuple_classes:  # noqa: F402
6828            with self.subTest(cls=NamedTuple):
6829                class ClassBasedNamedTuple(NamedTuple):
6830                    x: int
6831
6832                class GenericNamedTuple(NamedTuple, Generic[T]):
6833                    x: T
6834
6835                CallBasedNamedTuple = NamedTuple("CallBasedNamedTuple", [("x", int)])
6836
6837                self.assertIs(
6838                    get_original_bases(ClassBasedNamedTuple)[0], NamedTuple
6839                )
6840                self.assertEqual(
6841                    get_original_bases(GenericNamedTuple),
6842                    (NamedTuple, Generic[T])
6843                )
6844                self.assertIs(
6845                    get_original_bases(CallBasedNamedTuple)[0], NamedTuple
6846                )
6847
6848    def test_typeddicts(self):
6849        # On 3.12, this should work well with typing.TypedDict and typing_extensions.TypedDict
6850        # On lower versions, it will only work fully with typing_extensions.TypedDict
6851        if sys.version_info >= (3, 12):
6852            typeddict_classes = (typing.TypedDict, typing_extensions.TypedDict)
6853        else:
6854            typeddict_classes = (typing_extensions.TypedDict,)
6855
6856        for TypedDict in typeddict_classes:  # noqa: F402
6857            with self.subTest(cls=TypedDict):
6858                class ClassBasedTypedDict(TypedDict):
6859                    x: int
6860
6861                class GenericTypedDict(TypedDict, Generic[T]):
6862                    x: T
6863
6864                CallBasedTypedDict = TypedDict("CallBasedTypedDict", {"x": int})
6865
6866                self.assertIs(
6867                    get_original_bases(ClassBasedTypedDict)[0],
6868                    TypedDict
6869                )
6870                self.assertEqual(
6871                    get_original_bases(GenericTypedDict),
6872                    (TypedDict, Generic[T])
6873                )
6874                self.assertIs(
6875                    get_original_bases(CallBasedTypedDict)[0],
6876                    TypedDict
6877                )
6878
6879
6880class TypeAliasTypeTests(BaseTestCase):
6881    def test_attributes(self):
6882        Simple = TypeAliasType("Simple", int)
6883        self.assertEqual(Simple.__name__, "Simple")
6884        self.assertIs(Simple.__value__, int)
6885        self.assertEqual(Simple.__type_params__, ())
6886        self.assertEqual(Simple.__parameters__, ())
6887
6888        T = TypeVar("T")
6889        ListOrSetT = TypeAliasType("ListOrSetT", Union[List[T], Set[T]], type_params=(T,))
6890        self.assertEqual(ListOrSetT.__name__, "ListOrSetT")
6891        self.assertEqual(ListOrSetT.__value__, Union[List[T], Set[T]])
6892        self.assertEqual(ListOrSetT.__type_params__, (T,))
6893        self.assertEqual(ListOrSetT.__parameters__, (T,))
6894
6895        Ts = TypeVarTuple("Ts")
6896        Variadic = TypeAliasType("Variadic", Tuple[int, Unpack[Ts]], type_params=(Ts,))
6897        self.assertEqual(Variadic.__name__, "Variadic")
6898        self.assertEqual(Variadic.__value__, Tuple[int, Unpack[Ts]])
6899        self.assertEqual(Variadic.__type_params__, (Ts,))
6900        self.assertEqual(Variadic.__parameters__, tuple(iter(Ts)))
6901
6902    def test_cannot_set_attributes(self):
6903        Simple = TypeAliasType("Simple", int)
6904        with self.assertRaisesRegex(AttributeError, "readonly attribute"):
6905            Simple.__name__ = "NewName"
6906        with self.assertRaisesRegex(
6907            AttributeError,
6908            "attribute '__value__' of 'typing.TypeAliasType' objects is not writable",
6909        ):
6910            Simple.__value__ = str
6911        with self.assertRaisesRegex(
6912            AttributeError,
6913            "attribute '__type_params__' of 'typing.TypeAliasType' objects is not writable",
6914        ):
6915            Simple.__type_params__ = (T,)
6916        with self.assertRaisesRegex(
6917            AttributeError,
6918            "attribute '__parameters__' of 'typing.TypeAliasType' objects is not writable",
6919        ):
6920            Simple.__parameters__ = (T,)
6921        with self.assertRaisesRegex(
6922            AttributeError,
6923            "attribute '__module__' of 'typing.TypeAliasType' objects is not writable",
6924        ):
6925            Simple.__module__ = 42
6926        with self.assertRaisesRegex(
6927            AttributeError,
6928            "'typing.TypeAliasType' object has no attribute 'some_attribute'",
6929        ):
6930            Simple.some_attribute = "not allowed"
6931
6932    def test_cannot_delete_attributes(self):
6933        Simple = TypeAliasType("Simple", int)
6934        with self.assertRaisesRegex(AttributeError, "readonly attribute"):
6935            del Simple.__name__
6936        with self.assertRaisesRegex(
6937            AttributeError,
6938            "attribute '__value__' of 'typing.TypeAliasType' objects is not writable",
6939        ):
6940            del Simple.__value__
6941        with self.assertRaisesRegex(
6942            AttributeError,
6943            "'typing.TypeAliasType' object has no attribute 'some_attribute'",
6944        ):
6945            del Simple.some_attribute
6946
6947    def test_or(self):
6948        Alias = TypeAliasType("Alias", int)
6949        if sys.version_info >= (3, 10):
6950            self.assertEqual(Alias | int, Union[Alias, int])
6951            self.assertEqual(Alias | None, Union[Alias, None])
6952            self.assertEqual(Alias | (int | str), Union[Alias, int | str])
6953            self.assertEqual(Alias | list[float], Union[Alias, list[float]])
6954        else:
6955            with self.assertRaises(TypeError):
6956                Alias | int
6957        # Rejected on all versions
6958        with self.assertRaises(TypeError):
6959            Alias | "Ref"
6960
6961    def test_getitem(self):
6962        ListOrSetT = TypeAliasType("ListOrSetT", Union[List[T], Set[T]], type_params=(T,))
6963        subscripted = ListOrSetT[int]
6964        self.assertEqual(get_args(subscripted), (int,))
6965        self.assertIs(get_origin(subscripted), ListOrSetT)
6966        with self.assertRaises(TypeError):
6967            subscripted[str]
6968
6969        still_generic = ListOrSetT[Iterable[T]]
6970        self.assertEqual(get_args(still_generic), (Iterable[T],))
6971        self.assertIs(get_origin(still_generic), ListOrSetT)
6972        fully_subscripted = still_generic[float]
6973        self.assertEqual(get_args(fully_subscripted), (Iterable[float],))
6974        self.assertIs(get_origin(fully_subscripted), ListOrSetT)
6975
6976    def test_pickle(self):
6977        global Alias
6978        Alias = TypeAliasType("Alias", int)
6979        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
6980            with self.subTest(proto=proto):
6981                pickled = pickle.dumps(Alias, proto)
6982                unpickled = pickle.loads(pickled)
6983                self.assertIs(unpickled, Alias)
6984
6985    def test_no_instance_subclassing(self):
6986        with self.assertRaises(TypeError):
6987            class MyAlias(TypeAliasType):
6988                pass
6989
6990
6991class DocTests(BaseTestCase):
6992    def test_annotation(self):
6993
6994        def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: pass
6995
6996        hints = get_type_hints(hi, include_extras=True)
6997        doc_info = hints["to"].__metadata__[0]
6998        self.assertEqual(doc_info.documentation, "Who to say hi to")
6999        self.assertIsInstance(doc_info, Doc)
7000
7001    def test_repr(self):
7002        doc_info = Doc("Who to say hi to")
7003        self.assertEqual(repr(doc_info), "Doc('Who to say hi to')")
7004
7005    def test_hashability(self):
7006        doc_info = Doc("Who to say hi to")
7007        self.assertIsInstance(hash(doc_info), int)
7008        self.assertNotEqual(hash(doc_info), hash(Doc("Who not to say hi to")))
7009
7010    def test_equality(self):
7011        doc_info = Doc("Who to say hi to")
7012        # Equal to itself
7013        self.assertEqual(doc_info, doc_info)
7014        # Equal to another instance with the same string
7015        self.assertEqual(doc_info, Doc("Who to say hi to"))
7016        # Not equal to another instance with a different string
7017        self.assertNotEqual(doc_info, Doc("Who not to say hi to"))
7018
7019    def test_pickle(self):
7020        doc_info = Doc("Who to say hi to")
7021        for proto in range(pickle.HIGHEST_PROTOCOL):
7022            pickled = pickle.dumps(doc_info, protocol=proto)
7023            self.assertEqual(doc_info, pickle.loads(pickled))
7024
7025
7026@skipUnless(
7027    hasattr(typing_extensions, "CapsuleType"),
7028    "CapsuleType is not available on all Python implementations"
7029)
7030class CapsuleTypeTests(BaseTestCase):
7031    def test_capsule_type(self):
7032        import _datetime
7033        self.assertIsInstance(_datetime.datetime_CAPI, typing_extensions.CapsuleType)
7034
7035
7036if __name__ == '__main__':
7037    main()
7038