metaflow 2.15.4__py2.py3-none-any.whl → 2.15.6__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. metaflow/_vendor/typeguard/_checkers.py +259 -95
  2. metaflow/_vendor/typeguard/_config.py +4 -4
  3. metaflow/_vendor/typeguard/_decorators.py +8 -12
  4. metaflow/_vendor/typeguard/_functions.py +33 -32
  5. metaflow/_vendor/typeguard/_pytest_plugin.py +40 -13
  6. metaflow/_vendor/typeguard/_suppression.py +3 -5
  7. metaflow/_vendor/typeguard/_transformer.py +84 -48
  8. metaflow/_vendor/typeguard/_union_transformer.py +1 -0
  9. metaflow/_vendor/typeguard/_utils.py +13 -9
  10. metaflow/_vendor/typing_extensions.py +1088 -500
  11. metaflow/_vendor/v3_7/__init__.py +1 -0
  12. metaflow/_vendor/v3_7/importlib_metadata/__init__.py +1063 -0
  13. metaflow/_vendor/v3_7/importlib_metadata/_adapters.py +68 -0
  14. metaflow/_vendor/v3_7/importlib_metadata/_collections.py +30 -0
  15. metaflow/_vendor/v3_7/importlib_metadata/_compat.py +71 -0
  16. metaflow/_vendor/v3_7/importlib_metadata/_functools.py +104 -0
  17. metaflow/_vendor/v3_7/importlib_metadata/_itertools.py +73 -0
  18. metaflow/_vendor/v3_7/importlib_metadata/_meta.py +48 -0
  19. metaflow/_vendor/v3_7/importlib_metadata/_text.py +99 -0
  20. metaflow/_vendor/v3_7/importlib_metadata/py.typed +0 -0
  21. metaflow/_vendor/v3_7/typeguard/__init__.py +48 -0
  22. metaflow/_vendor/v3_7/typeguard/_checkers.py +906 -0
  23. metaflow/_vendor/v3_7/typeguard/_config.py +108 -0
  24. metaflow/_vendor/v3_7/typeguard/_decorators.py +237 -0
  25. metaflow/_vendor/v3_7/typeguard/_exceptions.py +42 -0
  26. metaflow/_vendor/v3_7/typeguard/_functions.py +310 -0
  27. metaflow/_vendor/v3_7/typeguard/_importhook.py +213 -0
  28. metaflow/_vendor/v3_7/typeguard/_memo.py +48 -0
  29. metaflow/_vendor/v3_7/typeguard/_pytest_plugin.py +100 -0
  30. metaflow/_vendor/v3_7/typeguard/_suppression.py +88 -0
  31. metaflow/_vendor/v3_7/typeguard/_transformer.py +1207 -0
  32. metaflow/_vendor/v3_7/typeguard/_union_transformer.py +54 -0
  33. metaflow/_vendor/v3_7/typeguard/_utils.py +169 -0
  34. metaflow/_vendor/v3_7/typeguard/py.typed +0 -0
  35. metaflow/_vendor/v3_7/typing_extensions.py +3072 -0
  36. metaflow/_vendor/v3_7/zipp.py +329 -0
  37. metaflow/cmd/develop/stubs.py +1 -1
  38. metaflow/extension_support/__init__.py +1 -1
  39. metaflow/plugins/argo/argo_client.py +9 -2
  40. metaflow/plugins/argo/argo_workflows.py +79 -28
  41. metaflow/plugins/argo/argo_workflows_cli.py +16 -25
  42. metaflow/plugins/argo/argo_workflows_deployer_objects.py +5 -2
  43. metaflow/plugins/cards/card_modules/main.js +52 -50
  44. metaflow/plugins/metadata_providers/service.py +16 -7
  45. metaflow/plugins/pypi/utils.py +4 -0
  46. metaflow/runner/click_api.py +7 -2
  47. metaflow/runner/deployer.py +3 -2
  48. metaflow/vendor.py +1 -0
  49. metaflow/version.py +1 -1
  50. {metaflow-2.15.4.data → metaflow-2.15.6.data}/data/share/metaflow/devtools/Tiltfile +4 -4
  51. metaflow-2.15.6.dist-info/METADATA +103 -0
  52. {metaflow-2.15.4.dist-info → metaflow-2.15.6.dist-info}/RECORD +58 -32
  53. {metaflow-2.15.4.dist-info → metaflow-2.15.6.dist-info}/WHEEL +1 -1
  54. metaflow-2.15.4.dist-info/METADATA +0 -110
  55. {metaflow-2.15.4.data → metaflow-2.15.6.data}/data/share/metaflow/devtools/Makefile +0 -0
  56. {metaflow-2.15.4.data → metaflow-2.15.6.data}/data/share/metaflow/devtools/pick_services.sh +0 -0
  57. {metaflow-2.15.4.dist-info → metaflow-2.15.6.dist-info}/LICENSE +0 -0
  58. {metaflow-2.15.4.dist-info → metaflow-2.15.6.dist-info}/entry_points.txt +0 -0
  59. {metaflow-2.15.4.dist-info → metaflow-2.15.6.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,7 @@
1
1
  import abc
2
2
  import collections
3
3
  import collections.abc
4
+ import contextlib
4
5
  import functools
5
6
  import inspect
6
7
  import operator
@@ -60,6 +61,7 @@ __all__ = [
60
61
  'clear_overloads',
61
62
  'dataclass_transform',
62
63
  'deprecated',
64
+ 'Doc',
63
65
  'get_overloads',
64
66
  'final',
65
67
  'get_args',
@@ -82,9 +84,11 @@ __all__ = [
82
84
  'TypeAlias',
83
85
  'TypeAliasType',
84
86
  'TypeGuard',
87
+ 'TypeIs',
85
88
  'TYPE_CHECKING',
86
89
  'Never',
87
90
  'NoReturn',
91
+ 'ReadOnly',
88
92
  'Required',
89
93
  'NotRequired',
90
94
 
@@ -113,6 +117,7 @@ __all__ = [
113
117
  'MutableMapping',
114
118
  'MutableSequence',
115
119
  'MutableSet',
120
+ 'NoDefault',
116
121
  'Optional',
117
122
  'Pattern',
118
123
  'Reversible',
@@ -131,6 +136,7 @@ __all__ = [
131
136
  # for backward compatibility
132
137
  PEP_560 = True
133
138
  GenericMeta = type
139
+ _PEP_696_IMPLEMENTED = sys.version_info >= (3, 13, 0, "beta")
134
140
 
135
141
  # The functions below are modified copies of typing internal helpers.
136
142
  # They are needed by _ProtocolMeta and they provide support for PEP 646.
@@ -144,27 +150,6 @@ class _Sentinel:
144
150
  _marker = _Sentinel()
145
151
 
146
152
 
147
- def _check_generic(cls, parameters, elen=_marker):
148
- """Check correct count for parameters of a generic cls (internal helper).
149
- This gives a nice error message in case of count mismatch.
150
- """
151
- if not elen:
152
- raise TypeError(f"{cls} is not a generic class")
153
- if elen is _marker:
154
- if not hasattr(cls, "__parameters__") or not cls.__parameters__:
155
- raise TypeError(f"{cls} is not a generic class")
156
- elen = len(cls.__parameters__)
157
- alen = len(parameters)
158
- if alen != elen:
159
- if hasattr(cls, "__parameters__"):
160
- parameters = [p for p in cls.__parameters__ if not _is_unpack(p)]
161
- num_tv_tuples = sum(isinstance(p, TypeVarTuple) for p in parameters)
162
- if (num_tv_tuples > 0) and (alen >= elen - num_tv_tuples):
163
- return
164
- raise TypeError(f"Too {'many' if alen > elen else 'few'} parameters for {cls};"
165
- f" actual {alen}, expected {elen}")
166
-
167
-
168
153
  if sys.version_info >= (3, 10):
169
154
  def _should_collect_from_parameters(t):
170
155
  return isinstance(
@@ -178,27 +163,6 @@ else:
178
163
  return isinstance(t, typing._GenericAlias) and not t._special
179
164
 
180
165
 
181
- def _collect_type_vars(types, typevar_types=None):
182
- """Collect all type variable contained in types in order of
183
- first appearance (lexicographic order). For example::
184
-
185
- _collect_type_vars((T, List[S, T])) == (T, S)
186
- """
187
- if typevar_types is None:
188
- typevar_types = typing.TypeVar
189
- tvars = []
190
- for t in types:
191
- if (
192
- isinstance(t, typevar_types) and
193
- t not in tvars and
194
- not _is_unpack(t)
195
- ):
196
- tvars.append(t)
197
- if _should_collect_from_parameters(t):
198
- tvars.extend([t for t in t.__parameters__ if t not in tvars])
199
- return tuple(tvars)
200
-
201
-
202
166
  NoReturn = typing.NoReturn
203
167
 
204
168
  # Some unconstrained type variables. These are used by the container types.
@@ -248,32 +212,7 @@ class _ExtensionsSpecialForm(typing._SpecialForm, _root=True):
248
212
  return 'typing_extensions.' + self._name
249
213
 
250
214
 
251
- # On older versions of typing there is an internal class named "Final".
252
- # 3.8+
253
- if hasattr(typing, 'Final') and sys.version_info[:2] >= (3, 7):
254
- Final = typing.Final
255
- # 3.7
256
- else:
257
- class _FinalForm(_ExtensionsSpecialForm, _root=True):
258
- def __getitem__(self, parameters):
259
- item = typing._type_check(parameters,
260
- f'{self._name} accepts only a single type.')
261
- return typing._GenericAlias(self, (item,))
262
-
263
- Final = _FinalForm('Final',
264
- doc="""A special typing construct to indicate that a name
265
- cannot be re-assigned or overridden in a subclass.
266
- For example:
267
-
268
- MAX_SIZE: Final = 9000
269
- MAX_SIZE += 1 # Error reported by type checker
270
-
271
- class Connection:
272
- TIMEOUT: Final[int] = 10
273
- class FastConnector(Connection):
274
- TIMEOUT = 1 # Error reported by type checker
275
-
276
- There is no runtime checking of these properties.""")
215
+ Final = typing.Final
277
216
 
278
217
  if sys.version_info >= (3, 11):
279
218
  final = typing.final
@@ -465,31 +404,101 @@ Type = typing.Type
465
404
 
466
405
  # Various ABCs mimicking those in collections.abc.
467
406
  # A few are simply re-exported for completeness.
468
-
469
-
470
407
  Awaitable = typing.Awaitable
471
408
  Coroutine = typing.Coroutine
472
409
  AsyncIterable = typing.AsyncIterable
473
410
  AsyncIterator = typing.AsyncIterator
474
411
  Deque = typing.Deque
475
- ContextManager = typing.ContextManager
476
- AsyncContextManager = typing.AsyncContextManager
477
412
  DefaultDict = typing.DefaultDict
478
-
479
- # 3.7.2+
480
- if hasattr(typing, 'OrderedDict'):
481
- OrderedDict = typing.OrderedDict
482
- # 3.7.0-3.7.2
483
- else:
484
- OrderedDict = typing._alias(collections.OrderedDict, (KT, VT))
485
-
413
+ OrderedDict = typing.OrderedDict
486
414
  Counter = typing.Counter
487
415
  ChainMap = typing.ChainMap
488
- AsyncGenerator = typing.AsyncGenerator
489
416
  Text = typing.Text
490
417
  TYPE_CHECKING = typing.TYPE_CHECKING
491
418
 
492
419
 
420
+ if sys.version_info >= (3, 13, 0, "beta"):
421
+ from typing import AsyncContextManager, AsyncGenerator, ContextManager, Generator
422
+ else:
423
+ def _is_dunder(attr):
424
+ return attr.startswith('__') and attr.endswith('__')
425
+
426
+ # Python <3.9 doesn't have typing._SpecialGenericAlias
427
+ _special_generic_alias_base = getattr(
428
+ typing, "_SpecialGenericAlias", typing._GenericAlias
429
+ )
430
+
431
+ class _SpecialGenericAlias(_special_generic_alias_base, _root=True):
432
+ def __init__(self, origin, nparams, *, inst=True, name=None, defaults=()):
433
+ if _special_generic_alias_base is typing._GenericAlias:
434
+ # Python <3.9
435
+ self.__origin__ = origin
436
+ self._nparams = nparams
437
+ super().__init__(origin, nparams, special=True, inst=inst, name=name)
438
+ else:
439
+ # Python >= 3.9
440
+ super().__init__(origin, nparams, inst=inst, name=name)
441
+ self._defaults = defaults
442
+
443
+ def __setattr__(self, attr, val):
444
+ allowed_attrs = {'_name', '_inst', '_nparams', '_defaults'}
445
+ if _special_generic_alias_base is typing._GenericAlias:
446
+ # Python <3.9
447
+ allowed_attrs.add("__origin__")
448
+ if _is_dunder(attr) or attr in allowed_attrs:
449
+ object.__setattr__(self, attr, val)
450
+ else:
451
+ setattr(self.__origin__, attr, val)
452
+
453
+ @typing._tp_cache
454
+ def __getitem__(self, params):
455
+ if not isinstance(params, tuple):
456
+ params = (params,)
457
+ msg = "Parameters to generic types must be types."
458
+ params = tuple(typing._type_check(p, msg) for p in params)
459
+ if (
460
+ self._defaults
461
+ and len(params) < self._nparams
462
+ and len(params) + len(self._defaults) >= self._nparams
463
+ ):
464
+ params = (*params, *self._defaults[len(params) - self._nparams:])
465
+ actual_len = len(params)
466
+
467
+ if actual_len != self._nparams:
468
+ if self._defaults:
469
+ expected = f"at least {self._nparams - len(self._defaults)}"
470
+ else:
471
+ expected = str(self._nparams)
472
+ if not self._nparams:
473
+ raise TypeError(f"{self} is not a generic class")
474
+ raise TypeError(
475
+ f"Too {'many' if actual_len > self._nparams else 'few'}"
476
+ f" arguments for {self};"
477
+ f" actual {actual_len}, expected {expected}"
478
+ )
479
+ return self.copy_with(params)
480
+
481
+ _NoneType = type(None)
482
+ Generator = _SpecialGenericAlias(
483
+ collections.abc.Generator, 3, defaults=(_NoneType, _NoneType)
484
+ )
485
+ AsyncGenerator = _SpecialGenericAlias(
486
+ collections.abc.AsyncGenerator, 2, defaults=(_NoneType,)
487
+ )
488
+ ContextManager = _SpecialGenericAlias(
489
+ contextlib.AbstractContextManager,
490
+ 2,
491
+ name="ContextManager",
492
+ defaults=(typing.Optional[bool],)
493
+ )
494
+ AsyncContextManager = _SpecialGenericAlias(
495
+ contextlib.AbstractAsyncContextManager,
496
+ 2,
497
+ name="AsyncContextManager",
498
+ defaults=(typing.Optional[bool],)
499
+ )
500
+
501
+
493
502
  _PROTO_ALLOWLIST = {
494
503
  'collections.abc': [
495
504
  'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable',
@@ -500,28 +509,11 @@ _PROTO_ALLOWLIST = {
500
509
  }
501
510
 
502
511
 
503
- _EXCLUDED_ATTRS = {
504
- "__abstractmethods__", "__annotations__", "__weakref__", "_is_protocol",
505
- "_is_runtime_protocol", "__dict__", "__slots__", "__parameters__",
506
- "__orig_bases__", "__module__", "_MutableMapping__marker", "__doc__",
507
- "__subclasshook__", "__orig_class__", "__init__", "__new__",
508
- "__protocol_attrs__", "__callable_proto_members_only__",
512
+ _EXCLUDED_ATTRS = frozenset(typing.EXCLUDED_ATTRIBUTES) | {
513
+ "__match_args__", "__protocol_attrs__", "__non_callable_proto_members__",
514
+ "__final__",
509
515
  }
510
516
 
511
- if sys.version_info < (3, 8):
512
- _EXCLUDED_ATTRS |= {
513
- "_gorg", "__next_in_mro__", "__extra__", "__tree_hash__", "__args__",
514
- "__origin__"
515
- }
516
-
517
- if sys.version_info >= (3, 9):
518
- _EXCLUDED_ATTRS.add("__class_getitem__")
519
-
520
- if sys.version_info >= (3, 12):
521
- _EXCLUDED_ATTRS.add("__type_params__")
522
-
523
- _EXCLUDED_ATTRS = frozenset(_EXCLUDED_ATTRS)
524
-
525
517
 
526
518
  def _get_protocol_attrs(cls):
527
519
  attrs = set()
@@ -535,46 +527,6 @@ def _get_protocol_attrs(cls):
535
527
  return attrs
536
528
 
537
529
 
538
- def _maybe_adjust_parameters(cls):
539
- """Helper function used in Protocol.__init_subclass__ and _TypedDictMeta.__new__.
540
-
541
- The contents of this function are very similar
542
- to logic found in typing.Generic.__init_subclass__
543
- on the CPython main branch.
544
- """
545
- tvars = []
546
- if '__orig_bases__' in cls.__dict__:
547
- tvars = _collect_type_vars(cls.__orig_bases__)
548
- # Look for Generic[T1, ..., Tn] or Protocol[T1, ..., Tn].
549
- # If found, tvars must be a subset of it.
550
- # If not found, tvars is it.
551
- # Also check for and reject plain Generic,
552
- # and reject multiple Generic[...] and/or Protocol[...].
553
- gvars = None
554
- for base in cls.__orig_bases__:
555
- if (isinstance(base, typing._GenericAlias) and
556
- base.__origin__ in (typing.Generic, Protocol)):
557
- # for error messages
558
- the_base = base.__origin__.__name__
559
- if gvars is not None:
560
- raise TypeError(
561
- "Cannot inherit from Generic[...]"
562
- " and/or Protocol[...] multiple types.")
563
- gvars = base.__parameters__
564
- if gvars is None:
565
- gvars = tvars
566
- else:
567
- tvarset = set(tvars)
568
- gvarset = set(gvars)
569
- if not tvarset <= gvarset:
570
- s_vars = ', '.join(str(t) for t in tvars if t not in gvarset)
571
- s_args = ', '.join(str(g) for g in gvars)
572
- raise TypeError(f"Some type variables ({s_vars}) are"
573
- f" not listed in {the_base}[{s_args}]")
574
- tvars = gvars
575
- cls.__parameters__ = tuple(tvars)
576
-
577
-
578
530
  def _caller(depth=2):
579
531
  try:
580
532
  return sys._getframe(depth).f_globals.get('__name__', '__main__')
@@ -582,9 +534,9 @@ def _caller(depth=2):
582
534
  return None
583
535
 
584
536
 
585
- # The performance of runtime-checkable protocols is significantly improved on Python 3.12,
586
- # so we backport the 3.12 version of Protocol to Python <=3.11
587
- if sys.version_info >= (3, 12):
537
+ # `__match_args__` attribute was removed from protocol members in 3.13,
538
+ # we want to backport this change to older Python versions.
539
+ if sys.version_info >= (3, 13):
588
540
  Protocol = typing.Protocol
589
541
  else:
590
542
  def _allow_reckless_class_checks(depth=3):
@@ -598,17 +550,26 @@ else:
598
550
  if type(self)._is_protocol:
599
551
  raise TypeError('Protocols cannot be instantiated')
600
552
 
601
- if sys.version_info >= (3, 8):
602
- # Inheriting from typing._ProtocolMeta isn't actually desirable,
603
- # but is necessary to allow typing.Protocol and typing_extensions.Protocol
604
- # to mix without getting TypeErrors about "metaclass conflict"
605
- _typing_Protocol = typing.Protocol
606
- _ProtocolMetaBase = type(_typing_Protocol)
607
- else:
608
- _typing_Protocol = _marker
609
- _ProtocolMetaBase = abc.ABCMeta
553
+ def _type_check_issubclass_arg_1(arg):
554
+ """Raise TypeError if `arg` is not an instance of `type`
555
+ in `issubclass(arg, <protocol>)`.
556
+
557
+ In most cases, this is verified by type.__subclasscheck__.
558
+ Checking it again unnecessarily would slow down issubclass() checks,
559
+ so, we don't perform this check unless we absolutely have to.
610
560
 
611
- class _ProtocolMeta(_ProtocolMetaBase):
561
+ For various error paths, however,
562
+ we want to ensure that *this* error message is shown to the user
563
+ where relevant, rather than a typing.py-specific error message.
564
+ """
565
+ if not isinstance(arg, type):
566
+ # Same error message as for issubclass(1, int).
567
+ raise TypeError('issubclass() arg 1 must be a class')
568
+
569
+ # Inheriting from typing._ProtocolMeta isn't actually desirable,
570
+ # but is necessary to allow typing.Protocol and typing_extensions.Protocol
571
+ # to mix without getting TypeErrors about "metaclass conflict"
572
+ class _ProtocolMeta(type(typing.Protocol)):
612
573
  # This metaclass is somewhat unfortunate,
613
574
  # but is necessary for several reasons...
614
575
  #
@@ -618,10 +579,10 @@ else:
618
579
  def __new__(mcls, name, bases, namespace, **kwargs):
619
580
  if name == "Protocol" and len(bases) < 2:
620
581
  pass
621
- elif {Protocol, _typing_Protocol} & set(bases):
582
+ elif {Protocol, typing.Protocol} & set(bases):
622
583
  for base in bases:
623
584
  if not (
624
- base in {object, typing.Generic, Protocol, _typing_Protocol}
585
+ base in {object, typing.Generic, Protocol, typing.Protocol}
625
586
  or base.__name__ in _PROTO_ALLOWLIST.get(base.__module__, [])
626
587
  or is_protocol(base)
627
588
  ):
@@ -635,11 +596,6 @@ else:
635
596
  abc.ABCMeta.__init__(cls, *args, **kwargs)
636
597
  if getattr(cls, "_is_protocol", False):
637
598
  cls.__protocol_attrs__ = _get_protocol_attrs(cls)
638
- # PEP 544 prohibits using issubclass()
639
- # with protocols that have non-method members.
640
- cls.__callable_proto_members_only__ = all(
641
- callable(getattr(cls, attr, None)) for attr in cls.__protocol_attrs__
642
- )
643
599
 
644
600
  def __subclasscheck__(cls, other):
645
601
  if cls is Protocol:
@@ -648,21 +604,23 @@ else:
648
604
  getattr(cls, '_is_protocol', False)
649
605
  and not _allow_reckless_class_checks()
650
606
  ):
651
- if not isinstance(other, type):
652
- # Same error message as for issubclass(1, int).
653
- raise TypeError('issubclass() arg 1 must be a class')
654
- if (
655
- not cls.__callable_proto_members_only__
656
- and cls.__dict__.get("__subclasshook__") is _proto_hook
657
- ):
658
- raise TypeError(
659
- "Protocols with non-method members don't support issubclass()"
660
- )
661
607
  if not getattr(cls, '_is_runtime_protocol', False):
608
+ _type_check_issubclass_arg_1(other)
662
609
  raise TypeError(
663
610
  "Instance and class checks can only be used with "
664
611
  "@runtime_checkable protocols"
665
612
  )
613
+ if (
614
+ # this attribute is set by @runtime_checkable:
615
+ cls.__non_callable_proto_members__
616
+ and cls.__dict__.get("__subclasshook__") is _proto_hook
617
+ ):
618
+ _type_check_issubclass_arg_1(other)
619
+ non_method_attrs = sorted(cls.__non_callable_proto_members__)
620
+ raise TypeError(
621
+ "Protocols with non-method members don't support issubclass()."
622
+ f" Non-method members: {str(non_method_attrs)[1:-1]}."
623
+ )
666
624
  return abc.ABCMeta.__subclasscheck__(cls, other)
667
625
 
668
626
  def __instancecheck__(cls, instance):
@@ -689,7 +647,8 @@ else:
689
647
  val = inspect.getattr_static(instance, attr)
690
648
  except AttributeError:
691
649
  break
692
- if val is None and callable(getattr(cls, attr, None)):
650
+ # this attribute is set by @runtime_checkable:
651
+ if val is None and attr not in cls.__non_callable_proto_members__:
693
652
  break
694
653
  else:
695
654
  return True
@@ -699,12 +658,10 @@ else:
699
658
  def __eq__(cls, other):
700
659
  # Hack so that typing.Generic.__class_getitem__
701
660
  # treats typing_extensions.Protocol
702
- # as equivalent to typing.Protocol on Python 3.8+
661
+ # as equivalent to typing.Protocol
703
662
  if abc.ABCMeta.__eq__(cls, other) is True:
704
663
  return True
705
- return (
706
- cls is Protocol and other is getattr(typing, "Protocol", object())
707
- )
664
+ return cls is Protocol and other is typing.Protocol
708
665
 
709
666
  # This has to be defined, or the abc-module cache
710
667
  # complains about classes with this metaclass being unhashable,
@@ -737,146 +694,88 @@ else:
737
694
  return NotImplemented
738
695
  return True
739
696
 
740
- if sys.version_info >= (3, 8):
741
- class Protocol(typing.Generic, metaclass=_ProtocolMeta):
742
- __doc__ = typing.Protocol.__doc__
743
- __slots__ = ()
744
- _is_protocol = True
745
- _is_runtime_protocol = False
746
-
747
- def __init_subclass__(cls, *args, **kwargs):
748
- super().__init_subclass__(*args, **kwargs)
697
+ class Protocol(typing.Generic, metaclass=_ProtocolMeta):
698
+ __doc__ = typing.Protocol.__doc__
699
+ __slots__ = ()
700
+ _is_protocol = True
701
+ _is_runtime_protocol = False
749
702
 
750
- # Determine if this is a protocol or a concrete subclass.
751
- if not cls.__dict__.get('_is_protocol', False):
752
- cls._is_protocol = any(b is Protocol for b in cls.__bases__)
703
+ def __init_subclass__(cls, *args, **kwargs):
704
+ super().__init_subclass__(*args, **kwargs)
753
705
 
754
- # Set (or override) the protocol subclass hook.
755
- if '__subclasshook__' not in cls.__dict__:
756
- cls.__subclasshook__ = _proto_hook
706
+ # Determine if this is a protocol or a concrete subclass.
707
+ if not cls.__dict__.get('_is_protocol', False):
708
+ cls._is_protocol = any(b is Protocol for b in cls.__bases__)
757
709
 
758
- # Prohibit instantiation for protocol classes
759
- if cls._is_protocol and cls.__init__ is Protocol.__init__:
760
- cls.__init__ = _no_init
710
+ # Set (or override) the protocol subclass hook.
711
+ if '__subclasshook__' not in cls.__dict__:
712
+ cls.__subclasshook__ = _proto_hook
761
713
 
762
- else:
763
- class Protocol(metaclass=_ProtocolMeta):
764
- # There is quite a lot of overlapping code with typing.Generic.
765
- # Unfortunately it is hard to avoid this on Python <3.8,
766
- # as the typing module on Python 3.7 doesn't let us subclass typing.Generic!
767
- """Base class for protocol classes. Protocol classes are defined as::
714
+ # Prohibit instantiation for protocol classes
715
+ if cls._is_protocol and cls.__init__ is Protocol.__init__:
716
+ cls.__init__ = _no_init
768
717
 
769
- class Proto(Protocol):
770
- def meth(self) -> int:
771
- ...
772
718
 
773
- Such classes are primarily used with static type checkers that recognize
774
- structural subtyping (static duck-typing), for example::
719
+ if sys.version_info >= (3, 13):
720
+ runtime_checkable = typing.runtime_checkable
721
+ else:
722
+ def runtime_checkable(cls):
723
+ """Mark a protocol class as a runtime protocol.
775
724
 
776
- class C:
777
- def meth(self) -> int:
778
- return 0
725
+ Such protocol can be used with isinstance() and issubclass().
726
+ Raise TypeError if applied to a non-protocol class.
727
+ This allows a simple-minded structural check very similar to
728
+ one trick ponies in collections.abc such as Iterable.
779
729
 
780
- def func(x: Proto) -> int:
781
- return x.meth()
730
+ For example::
782
731
 
783
- func(C()) # Passes static type check
732
+ @runtime_checkable
733
+ class Closable(Protocol):
734
+ def close(self): ...
784
735
 
785
- See PEP 544 for details. Protocol classes decorated with
786
- @typing_extensions.runtime_checkable act
787
- as simple-minded runtime-checkable protocols that check
788
- only the presence of given attributes, ignoring their type signatures.
736
+ assert isinstance(open('/some/file'), Closable)
789
737
 
790
- Protocol classes can be generic, they are defined as::
738
+ Warning: this will check only the presence of the required methods,
739
+ not their type signatures!
740
+ """
741
+ if not issubclass(cls, typing.Generic) or not getattr(cls, '_is_protocol', False):
742
+ raise TypeError(f'@runtime_checkable can be only applied to protocol classes,'
743
+ f' got {cls!r}')
744
+ cls._is_runtime_protocol = True
791
745
 
792
- class GenProto(Protocol[T]):
793
- def meth(self) -> T:
794
- ...
795
- """
796
- __slots__ = ()
797
- _is_protocol = True
798
- _is_runtime_protocol = False
799
-
800
- def __new__(cls, *args, **kwds):
801
- if cls is Protocol:
802
- raise TypeError("Type Protocol cannot be instantiated; "
803
- "it can only be used as a base class")
804
- return super().__new__(cls)
805
-
806
- @typing._tp_cache
807
- def __class_getitem__(cls, params):
808
- if not isinstance(params, tuple):
809
- params = (params,)
810
- if not params and cls is not typing.Tuple:
746
+ # typing.Protocol classes on <=3.11 break if we execute this block,
747
+ # because typing.Protocol classes on <=3.11 don't have a
748
+ # `__protocol_attrs__` attribute, and this block relies on the
749
+ # `__protocol_attrs__` attribute. Meanwhile, typing.Protocol classes on 3.12.2+
750
+ # break if we *don't* execute this block, because *they* assume that all
751
+ # protocol classes have a `__non_callable_proto_members__` attribute
752
+ # (which this block sets)
753
+ if isinstance(cls, _ProtocolMeta) or sys.version_info >= (3, 12, 2):
754
+ # PEP 544 prohibits using issubclass()
755
+ # with protocols that have non-method members.
756
+ # See gh-113320 for why we compute this attribute here,
757
+ # rather than in `_ProtocolMeta.__init__`
758
+ cls.__non_callable_proto_members__ = set()
759
+ for attr in cls.__protocol_attrs__:
760
+ try:
761
+ is_callable = callable(getattr(cls, attr, None))
762
+ except Exception as e:
811
763
  raise TypeError(
812
- f"Parameter list to {cls.__qualname__}[...] cannot be empty")
813
- msg = "Parameters to generic types must be types."
814
- params = tuple(typing._type_check(p, msg) for p in params)
815
- if cls is Protocol:
816
- # Generic can only be subscripted with unique type variables.
817
- if not all(isinstance(p, typing.TypeVar) for p in params):
818
- i = 0
819
- while isinstance(params[i], typing.TypeVar):
820
- i += 1
821
- raise TypeError(
822
- "Parameters to Protocol[...] must all be type variables."
823
- f" Parameter {i + 1} is {params[i]}")
824
- if len(set(params)) != len(params):
825
- raise TypeError(
826
- "Parameters to Protocol[...] must all be unique")
764
+ f"Failed to determine whether protocol member {attr!r} "
765
+ "is a method member"
766
+ ) from e
827
767
  else:
828
- # Subscripting a regular Generic subclass.
829
- _check_generic(cls, params, len(cls.__parameters__))
830
- return typing._GenericAlias(cls, params)
831
-
832
- def __init_subclass__(cls, *args, **kwargs):
833
- if '__orig_bases__' in cls.__dict__:
834
- error = typing.Generic in cls.__orig_bases__
835
- else:
836
- error = typing.Generic in cls.__bases__
837
- if error:
838
- raise TypeError("Cannot inherit from plain Generic")
839
- _maybe_adjust_parameters(cls)
840
-
841
- # Determine if this is a protocol or a concrete subclass.
842
- if not cls.__dict__.get('_is_protocol', None):
843
- cls._is_protocol = any(b is Protocol for b in cls.__bases__)
844
-
845
- # Set (or override) the protocol subclass hook.
846
- if '__subclasshook__' not in cls.__dict__:
847
- cls.__subclasshook__ = _proto_hook
848
-
849
- # Prohibit instantiation for protocol classes
850
- if cls._is_protocol and cls.__init__ is Protocol.__init__:
851
- cls.__init__ = _no_init
852
-
853
-
854
- if sys.version_info >= (3, 8):
855
- runtime_checkable = typing.runtime_checkable
856
- else:
857
- def runtime_checkable(cls):
858
- """Mark a protocol class as a runtime protocol, so that it
859
- can be used with isinstance() and issubclass(). Raise TypeError
860
- if applied to a non-protocol class.
768
+ if not is_callable:
769
+ cls.__non_callable_proto_members__.add(attr)
861
770
 
862
- This allows a simple-minded structural check very similar to the
863
- one-offs in collections.abc such as Hashable.
864
- """
865
- if not (
866
- (isinstance(cls, _ProtocolMeta) or issubclass(cls, typing.Generic))
867
- and getattr(cls, "_is_protocol", False)
868
- ):
869
- raise TypeError('@runtime_checkable can be only applied to protocol classes,'
870
- f' got {cls!r}')
871
- cls._is_runtime_protocol = True
872
771
  return cls
873
772
 
874
773
 
875
- # Exists for backwards compatibility.
774
+ # The "runtime" alias exists for backwards compatibility.
876
775
  runtime = runtime_checkable
877
776
 
878
777
 
879
- # Our version of runtime-checkable protocols is faster on Python 3.7-3.11
778
+ # Our version of runtime-checkable protocols is faster on Python 3.8-3.11
880
779
  if sys.version_info >= (3, 12):
881
780
  SupportsInt = typing.SupportsInt
882
781
  SupportsFloat = typing.SupportsFloat
@@ -953,7 +852,26 @@ else:
953
852
  pass
954
853
 
955
854
 
956
- if sys.version_info >= (3, 13):
855
+ def _ensure_subclassable(mro_entries):
856
+ def inner(func):
857
+ if sys.implementation.name == "pypy" and sys.version_info < (3, 9):
858
+ cls_dict = {
859
+ "__call__": staticmethod(func),
860
+ "__mro_entries__": staticmethod(mro_entries)
861
+ }
862
+ t = type(func.__name__, (), cls_dict)
863
+ return functools.update_wrapper(t(), func)
864
+ else:
865
+ func.__mro_entries__ = mro_entries
866
+ return func
867
+ return inner
868
+
869
+
870
+ # Update this to something like >=3.13.0b1 if and when
871
+ # PEP 728 is implemented in CPython
872
+ _PEP_728_IMPLEMENTED = False
873
+
874
+ if _PEP_728_IMPLEMENTED:
957
875
  # The standard library TypedDict in Python 3.8 does not store runtime information
958
876
  # about which (if any) keys are optional. See https://bugs.python.org/issue38834
959
877
  # The standard library TypedDict in Python 3.9.0/1 does not honour the "total"
@@ -964,6 +882,8 @@ if sys.version_info >= (3, 13):
964
882
  # Aaaand on 3.12 we add __orig_bases__ to TypedDict
965
883
  # to enable better runtime introspection.
966
884
  # On 3.13 we deprecate some odd ways of creating TypedDicts.
885
+ # Also on 3.13, PEP 705 adds the ReadOnly[] qualifier.
886
+ # PEP 728 (still pending) makes more changes.
967
887
  TypedDict = typing.TypedDict
968
888
  _TypedDictMeta = typing._TypedDictMeta
969
889
  is_typeddict = typing.is_typeddict
@@ -971,13 +891,29 @@ else:
971
891
  # 3.10.0 and later
972
892
  _TAKES_MODULE = "module" in inspect.signature(typing._type_check).parameters
973
893
 
974
- if sys.version_info >= (3, 8):
975
- _fake_name = "Protocol"
976
- else:
977
- _fake_name = "_Protocol"
894
+ def _get_typeddict_qualifiers(annotation_type):
895
+ while True:
896
+ annotation_origin = get_origin(annotation_type)
897
+ if annotation_origin is Annotated:
898
+ annotation_args = get_args(annotation_type)
899
+ if annotation_args:
900
+ annotation_type = annotation_args[0]
901
+ else:
902
+ break
903
+ elif annotation_origin is Required:
904
+ yield Required
905
+ annotation_type, = get_args(annotation_type)
906
+ elif annotation_origin is NotRequired:
907
+ yield NotRequired
908
+ annotation_type, = get_args(annotation_type)
909
+ elif annotation_origin is ReadOnly:
910
+ yield ReadOnly
911
+ annotation_type, = get_args(annotation_type)
912
+ else:
913
+ break
978
914
 
979
915
  class _TypedDictMeta(type):
980
- def __new__(cls, name, bases, ns, total=True):
916
+ def __new__(cls, name, bases, ns, *, total=True, closed=False):
981
917
  """Create new typed dict class object.
982
918
 
983
919
  This method is called when TypedDict is subclassed,
@@ -996,17 +932,23 @@ else:
996
932
  generic_base = ()
997
933
 
998
934
  # typing.py generally doesn't let you inherit from plain Generic, unless
999
- # the name of the class happens to be "Protocol" (or "_Protocol" on 3.7).
1000
- tp_dict = type.__new__(_TypedDictMeta, _fake_name, (*generic_base, dict), ns)
935
+ # the name of the class happens to be "Protocol"
936
+ tp_dict = type.__new__(_TypedDictMeta, "Protocol", (*generic_base, dict), ns)
1001
937
  tp_dict.__name__ = name
1002
- if tp_dict.__qualname__ == _fake_name:
938
+ if tp_dict.__qualname__ == "Protocol":
1003
939
  tp_dict.__qualname__ = name
1004
940
 
1005
941
  if not hasattr(tp_dict, '__orig_bases__'):
1006
942
  tp_dict.__orig_bases__ = bases
1007
943
 
1008
944
  annotations = {}
1009
- own_annotations = ns.get('__annotations__', {})
945
+ if "__annotations__" in ns:
946
+ own_annotations = ns["__annotations__"]
947
+ elif "__annotate__" in ns:
948
+ # TODO: Use inspect.VALUE here, and make the annotations lazily evaluated
949
+ own_annotations = ns["__annotate__"](1)
950
+ else:
951
+ own_annotations = {}
1010
952
  msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
1011
953
  if _TAKES_MODULE:
1012
954
  own_annotations = {
@@ -1020,35 +962,67 @@ else:
1020
962
  }
1021
963
  required_keys = set()
1022
964
  optional_keys = set()
965
+ readonly_keys = set()
966
+ mutable_keys = set()
967
+ extra_items_type = None
1023
968
 
1024
969
  for base in bases:
1025
- annotations.update(base.__dict__.get('__annotations__', {}))
1026
- required_keys.update(base.__dict__.get('__required_keys__', ()))
1027
- optional_keys.update(base.__dict__.get('__optional_keys__', ()))
970
+ base_dict = base.__dict__
971
+
972
+ annotations.update(base_dict.get('__annotations__', {}))
973
+ required_keys.update(base_dict.get('__required_keys__', ()))
974
+ optional_keys.update(base_dict.get('__optional_keys__', ()))
975
+ readonly_keys.update(base_dict.get('__readonly_keys__', ()))
976
+ mutable_keys.update(base_dict.get('__mutable_keys__', ()))
977
+ base_extra_items_type = base_dict.get('__extra_items__', None)
978
+ if base_extra_items_type is not None:
979
+ extra_items_type = base_extra_items_type
980
+
981
+ if closed and extra_items_type is None:
982
+ extra_items_type = Never
983
+ if closed and "__extra_items__" in own_annotations:
984
+ annotation_type = own_annotations.pop("__extra_items__")
985
+ qualifiers = set(_get_typeddict_qualifiers(annotation_type))
986
+ if Required in qualifiers:
987
+ raise TypeError(
988
+ "Special key __extra_items__ does not support "
989
+ "Required"
990
+ )
991
+ if NotRequired in qualifiers:
992
+ raise TypeError(
993
+ "Special key __extra_items__ does not support "
994
+ "NotRequired"
995
+ )
996
+ extra_items_type = annotation_type
1028
997
 
1029
998
  annotations.update(own_annotations)
1030
999
  for annotation_key, annotation_type in own_annotations.items():
1031
- annotation_origin = get_origin(annotation_type)
1032
- if annotation_origin is Annotated:
1033
- annotation_args = get_args(annotation_type)
1034
- if annotation_args:
1035
- annotation_type = annotation_args[0]
1036
- annotation_origin = get_origin(annotation_type)
1037
-
1038
- if annotation_origin is Required:
1000
+ qualifiers = set(_get_typeddict_qualifiers(annotation_type))
1001
+
1002
+ if Required in qualifiers:
1039
1003
  required_keys.add(annotation_key)
1040
- elif annotation_origin is NotRequired:
1004
+ elif NotRequired in qualifiers:
1041
1005
  optional_keys.add(annotation_key)
1042
1006
  elif total:
1043
1007
  required_keys.add(annotation_key)
1044
1008
  else:
1045
1009
  optional_keys.add(annotation_key)
1010
+ if ReadOnly in qualifiers:
1011
+ mutable_keys.discard(annotation_key)
1012
+ readonly_keys.add(annotation_key)
1013
+ else:
1014
+ mutable_keys.add(annotation_key)
1015
+ readonly_keys.discard(annotation_key)
1046
1016
 
1047
1017
  tp_dict.__annotations__ = annotations
1048
1018
  tp_dict.__required_keys__ = frozenset(required_keys)
1049
1019
  tp_dict.__optional_keys__ = frozenset(optional_keys)
1020
+ tp_dict.__readonly_keys__ = frozenset(readonly_keys)
1021
+ tp_dict.__mutable_keys__ = frozenset(mutable_keys)
1050
1022
  if not hasattr(tp_dict, '__total__'):
1051
1023
  tp_dict.__total__ = total
1024
+ tp_dict.__closed__ = closed
1025
+ tp_dict.__extra_items__ = extra_items_type
1052
1026
  return tp_dict
1053
1027
 
1054
1028
  __call__ = dict # static method
@@ -1059,7 +1033,10 @@ else:
1059
1033
 
1060
1034
  __instancecheck__ = __subclasscheck__
1061
1035
 
1062
- def TypedDict(__typename, __fields=_marker, *, total=True, **kwargs):
1036
+ _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
1037
+
1038
+ @_ensure_subclassable(lambda bases: (_TypedDict,))
1039
+ def TypedDict(typename, fields=_marker, /, *, total=True, closed=False, **kwargs):
1063
1040
  """A simple typed namespace. At runtime it is equivalent to a plain dict.
1064
1041
 
1065
1042
  TypedDict creates a dictionary type such that a type checker will expect all
@@ -1106,24 +1083,29 @@ else:
1106
1083
 
1107
1084
  See PEP 655 for more details on Required and NotRequired.
1108
1085
  """
1109
- if __fields is _marker or __fields is None:
1110
- if __fields is _marker:
1086
+ if fields is _marker or fields is None:
1087
+ if fields is _marker:
1111
1088
  deprecated_thing = "Failing to pass a value for the 'fields' parameter"
1112
1089
  else:
1113
1090
  deprecated_thing = "Passing `None` as the 'fields' parameter"
1114
1091
 
1115
- example = f"`{__typename} = TypedDict({__typename!r}, {{}})`"
1092
+ example = f"`{typename} = TypedDict({typename!r}, {{}})`"
1116
1093
  deprecation_msg = (
1117
1094
  f"{deprecated_thing} is deprecated and will be disallowed in "
1118
1095
  "Python 3.15. To create a TypedDict class with 0 fields "
1119
1096
  "using the functional syntax, pass an empty dictionary, e.g. "
1120
1097
  ) + example + "."
1121
1098
  warnings.warn(deprecation_msg, DeprecationWarning, stacklevel=2)
1122
- __fields = kwargs
1099
+ if closed is not False and closed is not True:
1100
+ kwargs["closed"] = closed
1101
+ closed = False
1102
+ fields = kwargs
1123
1103
  elif kwargs:
1124
1104
  raise TypeError("TypedDict takes either a dict or keyword arguments,"
1125
1105
  " but not both")
1126
1106
  if kwargs:
1107
+ if sys.version_info >= (3, 13):
1108
+ raise TypeError("TypedDict takes no keyword arguments")
1127
1109
  warnings.warn(
1128
1110
  "The kwargs-based syntax for TypedDict definitions is deprecated "
1129
1111
  "in Python 3.11, will be removed in Python 3.13, and may not be "
@@ -1132,19 +1114,16 @@ else:
1132
1114
  stacklevel=2,
1133
1115
  )
1134
1116
 
1135
- ns = {'__annotations__': dict(__fields)}
1117
+ ns = {'__annotations__': dict(fields)}
1136
1118
  module = _caller()
1137
1119
  if module is not None:
1138
1120
  # Setting correct module is necessary to make typed dict classes pickleable.
1139
1121
  ns['__module__'] = module
1140
1122
 
1141
- td = _TypedDictMeta(__typename, (), ns, total=total)
1123
+ td = _TypedDictMeta(typename, (), ns, total=total, closed=closed)
1142
1124
  td.__orig_bases__ = (TypedDict,)
1143
1125
  return td
1144
1126
 
1145
- _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
1146
- TypedDict.__mro_entries__ = lambda bases: (_TypedDict,)
1147
-
1148
1127
  if hasattr(typing, "_TypedDictMeta"):
1149
1128
  _TYPEDDICT_TYPES = (typing._TypedDictMeta, _TypedDictMeta)
1150
1129
  else:
@@ -1171,7 +1150,7 @@ if hasattr(typing, "assert_type"):
1171
1150
  assert_type = typing.assert_type
1172
1151
 
1173
1152
  else:
1174
- def assert_type(__val, __typ):
1153
+ def assert_type(val, typ, /):
1175
1154
  """Assert (to the type checker) that the value is of the given type.
1176
1155
 
1177
1156
  When the type checker encounters a call to assert_type(), it
@@ -1184,18 +1163,18 @@ else:
1184
1163
  At runtime this returns the first argument unchanged and otherwise
1185
1164
  does nothing.
1186
1165
  """
1187
- return __val
1166
+ return val
1188
1167
 
1189
1168
 
1190
- if hasattr(typing, "Required"):
1169
+ if hasattr(typing, "ReadOnly"): # 3.13+
1191
1170
  get_type_hints = typing.get_type_hints
1192
- else:
1171
+ else: # <=3.13
1193
1172
  # replaces _strip_annotations()
1194
1173
  def _strip_extras(t):
1195
1174
  """Strips Annotated, Required and NotRequired from a given type."""
1196
1175
  if isinstance(t, _AnnotatedAlias):
1197
1176
  return _strip_extras(t.__origin__)
1198
- if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired):
1177
+ if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired, ReadOnly):
1199
1178
  return _strip_extras(t.__args__[0])
1200
1179
  if isinstance(t, typing._GenericAlias):
1201
1180
  stripped_args = tuple(_strip_extras(a) for a in t.__args__)
@@ -1247,11 +1226,11 @@ else:
1247
1226
  - If two dict arguments are passed, they specify globals and
1248
1227
  locals, respectively.
1249
1228
  """
1250
- if hasattr(typing, "Annotated"):
1229
+ if hasattr(typing, "Annotated"): # 3.9+
1251
1230
  hint = typing.get_type_hints(
1252
1231
  obj, globalns=globalns, localns=localns, include_extras=True
1253
1232
  )
1254
- else:
1233
+ else: # 3.8
1255
1234
  hint = typing.get_type_hints(obj, globalns=globalns, localns=localns)
1256
1235
  if include_extras:
1257
1236
  return hint
@@ -1264,7 +1243,7 @@ if hasattr(typing, 'Annotated'):
1264
1243
  # Not exported and not a public API, but needed for get_origin() and get_args()
1265
1244
  # to work.
1266
1245
  _AnnotatedAlias = typing._AnnotatedAlias
1267
- # 3.7-3.8
1246
+ # 3.8
1268
1247
  else:
1269
1248
  class _AnnotatedAlias(typing._GenericAlias, _root=True):
1270
1249
  """Runtime representation of an annotated type.
@@ -1292,7 +1271,7 @@ else:
1292
1271
 
1293
1272
  def __reduce__(self):
1294
1273
  return operator.getitem, (
1295
- Annotated, (self.__origin__,) + self.__metadata__
1274
+ Annotated, (self.__origin__, *self.__metadata__)
1296
1275
  )
1297
1276
 
1298
1277
  def __eq__(self, other):
@@ -1369,7 +1348,7 @@ else:
1369
1348
  if sys.version_info[:2] >= (3, 10):
1370
1349
  get_origin = typing.get_origin
1371
1350
  get_args = typing.get_args
1372
- # 3.7-3.9
1351
+ # 3.8-3.9
1373
1352
  else:
1374
1353
  try:
1375
1354
  # 3.9+
@@ -1418,7 +1397,7 @@ else:
1418
1397
  get_args(Callable[[], T][int]) == ([], int)
1419
1398
  """
1420
1399
  if isinstance(tp, _AnnotatedAlias):
1421
- return (tp.__origin__,) + tp.__metadata__
1400
+ return (tp.__origin__, *tp.__metadata__)
1422
1401
  if isinstance(tp, (typing._GenericAlias, _typing_GenericAlias)):
1423
1402
  if getattr(tp, "_special", False):
1424
1403
  return ()
@@ -1447,7 +1426,7 @@ elif sys.version_info[:2] >= (3, 9):
1447
1426
  It's invalid when used anywhere except as in the example above.
1448
1427
  """
1449
1428
  raise TypeError(f"{self} is not subscriptable")
1450
- # 3.7-3.8
1429
+ # 3.8
1451
1430
  else:
1452
1431
  TypeAlias = _ExtensionsSpecialForm(
1453
1432
  'TypeAlias',
@@ -1464,14 +1443,37 @@ else:
1464
1443
  )
1465
1444
 
1466
1445
 
1446
+ if hasattr(typing, "NoDefault"):
1447
+ NoDefault = typing.NoDefault
1448
+ else:
1449
+ class NoDefaultTypeMeta(type):
1450
+ def __setattr__(cls, attr, value):
1451
+ # TypeError is consistent with the behavior of NoneType
1452
+ raise TypeError(
1453
+ f"cannot set {attr!r} attribute of immutable type {cls.__name__!r}"
1454
+ )
1455
+
1456
+ class NoDefaultType(metaclass=NoDefaultTypeMeta):
1457
+ """The type of the NoDefault singleton."""
1458
+
1459
+ __slots__ = ()
1460
+
1461
+ def __new__(cls):
1462
+ return globals().get("NoDefault") or object.__new__(cls)
1463
+
1464
+ def __repr__(self):
1465
+ return "typing_extensions.NoDefault"
1466
+
1467
+ def __reduce__(self):
1468
+ return "NoDefault"
1469
+
1470
+ NoDefault = NoDefaultType()
1471
+ del NoDefaultType, NoDefaultTypeMeta
1472
+
1473
+
1467
1474
  def _set_default(type_param, default):
1468
- if isinstance(default, (tuple, list)):
1469
- type_param.__default__ = tuple((typing._type_check(d, "Default must be a type")
1470
- for d in default))
1471
- elif default != _marker:
1472
- type_param.__default__ = typing._type_check(default, "Default must be a type")
1473
- else:
1474
- type_param.__default__ = None
1475
+ type_param.has_default = lambda: default is not NoDefault
1476
+ type_param.__default__ = default
1475
1477
 
1476
1478
 
1477
1479
  def _set_module(typevarlike):
@@ -1494,39 +1496,53 @@ class _TypeVarLikeMeta(type):
1494
1496
  return isinstance(__instance, cls._backported_typevarlike)
1495
1497
 
1496
1498
 
1497
- # Add default and infer_variance parameters from PEP 696 and 695
1498
- class TypeVar(metaclass=_TypeVarLikeMeta):
1499
- """Type variable."""
1499
+ if _PEP_696_IMPLEMENTED:
1500
+ from typing import TypeVar
1501
+ else:
1502
+ # Add default and infer_variance parameters from PEP 696 and 695
1503
+ class TypeVar(metaclass=_TypeVarLikeMeta):
1504
+ """Type variable."""
1500
1505
 
1501
- _backported_typevarlike = typing.TypeVar
1506
+ _backported_typevarlike = typing.TypeVar
1502
1507
 
1503
- def __new__(cls, name, *constraints, bound=None,
1504
- covariant=False, contravariant=False,
1505
- default=_marker, infer_variance=False):
1506
- if hasattr(typing, "TypeAliasType"):
1507
- # PEP 695 implemented, can pass infer_variance to typing.TypeVar
1508
- typevar = typing.TypeVar(name, *constraints, bound=bound,
1509
- covariant=covariant, contravariant=contravariant,
1510
- infer_variance=infer_variance)
1511
- else:
1512
- typevar = typing.TypeVar(name, *constraints, bound=bound,
1513
- covariant=covariant, contravariant=contravariant)
1514
- if infer_variance and (covariant or contravariant):
1515
- raise ValueError("Variance cannot be specified with infer_variance.")
1516
- typevar.__infer_variance__ = infer_variance
1517
- _set_default(typevar, default)
1518
- _set_module(typevar)
1519
- return typevar
1508
+ def __new__(cls, name, *constraints, bound=None,
1509
+ covariant=False, contravariant=False,
1510
+ default=NoDefault, infer_variance=False):
1511
+ if hasattr(typing, "TypeAliasType"):
1512
+ # PEP 695 implemented (3.12+), can pass infer_variance to typing.TypeVar
1513
+ typevar = typing.TypeVar(name, *constraints, bound=bound,
1514
+ covariant=covariant, contravariant=contravariant,
1515
+ infer_variance=infer_variance)
1516
+ else:
1517
+ typevar = typing.TypeVar(name, *constraints, bound=bound,
1518
+ covariant=covariant, contravariant=contravariant)
1519
+ if infer_variance and (covariant or contravariant):
1520
+ raise ValueError("Variance cannot be specified with infer_variance.")
1521
+ typevar.__infer_variance__ = infer_variance
1522
+
1523
+ _set_default(typevar, default)
1524
+ _set_module(typevar)
1525
+
1526
+ def _tvar_prepare_subst(alias, args):
1527
+ if (
1528
+ typevar.has_default()
1529
+ and alias.__parameters__.index(typevar) == len(args)
1530
+ ):
1531
+ args += (typevar.__default__,)
1532
+ return args
1520
1533
 
1521
- def __init_subclass__(cls) -> None:
1522
- raise TypeError(f"type '{__name__}.TypeVar' is not an acceptable base type")
1534
+ typevar.__typing_prepare_subst__ = _tvar_prepare_subst
1535
+ return typevar
1536
+
1537
+ def __init_subclass__(cls) -> None:
1538
+ raise TypeError(f"type '{__name__}.TypeVar' is not an acceptable base type")
1523
1539
 
1524
1540
 
1525
1541
  # Python 3.10+ has PEP 612
1526
1542
  if hasattr(typing, 'ParamSpecArgs'):
1527
1543
  ParamSpecArgs = typing.ParamSpecArgs
1528
1544
  ParamSpecKwargs = typing.ParamSpecKwargs
1529
- # 3.7-3.9
1545
+ # 3.8-3.9
1530
1546
  else:
1531
1547
  class _Immutable:
1532
1548
  """Mixin to indicate that object should not be copied."""
@@ -1584,8 +1600,12 @@ else:
1584
1600
  return NotImplemented
1585
1601
  return self.__origin__ == other.__origin__
1586
1602
 
1603
+
1604
+ if _PEP_696_IMPLEMENTED:
1605
+ from typing import ParamSpec
1606
+
1587
1607
  # 3.10+
1588
- if hasattr(typing, 'ParamSpec'):
1608
+ elif hasattr(typing, 'ParamSpec'):
1589
1609
 
1590
1610
  # Add default parameter - PEP 696
1591
1611
  class ParamSpec(metaclass=_TypeVarLikeMeta):
@@ -1595,7 +1615,7 @@ if hasattr(typing, 'ParamSpec'):
1595
1615
 
1596
1616
  def __new__(cls, name, *, bound=None,
1597
1617
  covariant=False, contravariant=False,
1598
- infer_variance=False, default=_marker):
1618
+ infer_variance=False, default=NoDefault):
1599
1619
  if hasattr(typing, "TypeAliasType"):
1600
1620
  # PEP 695 implemented, can pass infer_variance to typing.TypeVar
1601
1621
  paramspec = typing.ParamSpec(name, bound=bound,
@@ -1610,12 +1630,30 @@ if hasattr(typing, 'ParamSpec'):
1610
1630
 
1611
1631
  _set_default(paramspec, default)
1612
1632
  _set_module(paramspec)
1633
+
1634
+ def _paramspec_prepare_subst(alias, args):
1635
+ params = alias.__parameters__
1636
+ i = params.index(paramspec)
1637
+ if i == len(args) and paramspec.has_default():
1638
+ args = [*args, paramspec.__default__]
1639
+ if i >= len(args):
1640
+ raise TypeError(f"Too few arguments for {alias}")
1641
+ # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612.
1642
+ if len(params) == 1 and not typing._is_param_expr(args[0]):
1643
+ assert i == 0
1644
+ args = (args,)
1645
+ # Convert lists to tuples to help other libraries cache the results.
1646
+ elif isinstance(args[i], list):
1647
+ args = (*args[:i], tuple(args[i]), *args[i + 1:])
1648
+ return args
1649
+
1650
+ paramspec.__typing_prepare_subst__ = _paramspec_prepare_subst
1613
1651
  return paramspec
1614
1652
 
1615
1653
  def __init_subclass__(cls) -> None:
1616
1654
  raise TypeError(f"type '{__name__}.ParamSpec' is not an acceptable base type")
1617
1655
 
1618
- # 3.7-3.9
1656
+ # 3.8-3.9
1619
1657
  else:
1620
1658
 
1621
1659
  # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
@@ -1678,8 +1716,8 @@ else:
1678
1716
  return ParamSpecKwargs(self)
1679
1717
 
1680
1718
  def __init__(self, name, *, bound=None, covariant=False, contravariant=False,
1681
- infer_variance=False, default=_marker):
1682
- super().__init__([self])
1719
+ infer_variance=False, default=NoDefault):
1720
+ list.__init__(self, [self])
1683
1721
  self.__name__ = name
1684
1722
  self.__covariant__ = bool(covariant)
1685
1723
  self.__contravariant__ = bool(contravariant)
@@ -1720,7 +1758,7 @@ else:
1720
1758
  pass
1721
1759
 
1722
1760
 
1723
- # 3.7-3.9
1761
+ # 3.8-3.9
1724
1762
  if not hasattr(typing, 'Concatenate'):
1725
1763
  # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
1726
1764
  class _ConcatenateGenericAlias(list):
@@ -1755,7 +1793,7 @@ if not hasattr(typing, 'Concatenate'):
1755
1793
  )
1756
1794
 
1757
1795
 
1758
- # 3.7-3.9
1796
+ # 3.8-3.9
1759
1797
  @typing._tp_cache
1760
1798
  def _concatenate_getitem(self, parameters):
1761
1799
  if parameters == ():
@@ -1773,7 +1811,7 @@ def _concatenate_getitem(self, parameters):
1773
1811
  # 3.10+
1774
1812
  if hasattr(typing, 'Concatenate'):
1775
1813
  Concatenate = typing.Concatenate
1776
- _ConcatenateGenericAlias = typing._ConcatenateGenericAlias # noqa: F811
1814
+ _ConcatenateGenericAlias = typing._ConcatenateGenericAlias
1777
1815
  # 3.9
1778
1816
  elif sys.version_info[:2] >= (3, 9):
1779
1817
  @_ExtensionsSpecialForm
@@ -1789,7 +1827,7 @@ elif sys.version_info[:2] >= (3, 9):
1789
1827
  See PEP 612 for detailed information.
1790
1828
  """
1791
1829
  return _concatenate_getitem(self, parameters)
1792
- # 3.7-8
1830
+ # 3.8
1793
1831
  else:
1794
1832
  class _ConcatenateForm(_ExtensionsSpecialForm, _root=True):
1795
1833
  def __getitem__(self, parameters):
@@ -1859,7 +1897,7 @@ elif sys.version_info[:2] >= (3, 9):
1859
1897
  """
1860
1898
  item = typing._type_check(parameters, f'{self} accepts only a single type.')
1861
1899
  return typing._GenericAlias(self, (item,))
1862
- # 3.7-3.8
1900
+ # 3.8
1863
1901
  else:
1864
1902
  class _TypeGuardForm(_ExtensionsSpecialForm, _root=True):
1865
1903
  def __getitem__(self, parameters):
@@ -1912,6 +1950,98 @@ else:
1912
1950
  PEP 647 (User-Defined Type Guards).
1913
1951
  """)
1914
1952
 
1953
+ # 3.13+
1954
+ if hasattr(typing, 'TypeIs'):
1955
+ TypeIs = typing.TypeIs
1956
+ # 3.9
1957
+ elif sys.version_info[:2] >= (3, 9):
1958
+ @_ExtensionsSpecialForm
1959
+ def TypeIs(self, parameters):
1960
+ """Special typing form used to annotate the return type of a user-defined
1961
+ type narrower function. ``TypeIs`` only accepts a single type argument.
1962
+ At runtime, functions marked this way should return a boolean.
1963
+
1964
+ ``TypeIs`` aims to benefit *type narrowing* -- a technique used by static
1965
+ type checkers to determine a more precise type of an expression within a
1966
+ program's code flow. Usually type narrowing is done by analyzing
1967
+ conditional code flow and applying the narrowing to a block of code. The
1968
+ conditional expression here is sometimes referred to as a "type guard".
1969
+
1970
+ Sometimes it would be convenient to use a user-defined boolean function
1971
+ as a type guard. Such a function should use ``TypeIs[...]`` as its
1972
+ return type to alert static type checkers to this intention.
1973
+
1974
+ Using ``-> TypeIs`` tells the static type checker that for a given
1975
+ function:
1976
+
1977
+ 1. The return value is a boolean.
1978
+ 2. If the return value is ``True``, the type of its argument
1979
+ is the intersection of the type inside ``TypeGuard`` and the argument's
1980
+ previously known type.
1981
+
1982
+ For example::
1983
+
1984
+ def is_awaitable(val: object) -> TypeIs[Awaitable[Any]]:
1985
+ return hasattr(val, '__await__')
1986
+
1987
+ def f(val: Union[int, Awaitable[int]]) -> int:
1988
+ if is_awaitable(val):
1989
+ assert_type(val, Awaitable[int])
1990
+ else:
1991
+ assert_type(val, int)
1992
+
1993
+ ``TypeIs`` also works with type variables. For more information, see
1994
+ PEP 742 (Narrowing types with TypeIs).
1995
+ """
1996
+ item = typing._type_check(parameters, f'{self} accepts only a single type.')
1997
+ return typing._GenericAlias(self, (item,))
1998
+ # 3.8
1999
+ else:
2000
+ class _TypeIsForm(_ExtensionsSpecialForm, _root=True):
2001
+ def __getitem__(self, parameters):
2002
+ item = typing._type_check(parameters,
2003
+ f'{self._name} accepts only a single type')
2004
+ return typing._GenericAlias(self, (item,))
2005
+
2006
+ TypeIs = _TypeIsForm(
2007
+ 'TypeIs',
2008
+ doc="""Special typing form used to annotate the return type of a user-defined
2009
+ type narrower function. ``TypeIs`` only accepts a single type argument.
2010
+ At runtime, functions marked this way should return a boolean.
2011
+
2012
+ ``TypeIs`` aims to benefit *type narrowing* -- a technique used by static
2013
+ type checkers to determine a more precise type of an expression within a
2014
+ program's code flow. Usually type narrowing is done by analyzing
2015
+ conditional code flow and applying the narrowing to a block of code. The
2016
+ conditional expression here is sometimes referred to as a "type guard".
2017
+
2018
+ Sometimes it would be convenient to use a user-defined boolean function
2019
+ as a type guard. Such a function should use ``TypeIs[...]`` as its
2020
+ return type to alert static type checkers to this intention.
2021
+
2022
+ Using ``-> TypeIs`` tells the static type checker that for a given
2023
+ function:
2024
+
2025
+ 1. The return value is a boolean.
2026
+ 2. If the return value is ``True``, the type of its argument
2027
+ is the intersection of the type inside ``TypeGuard`` and the argument's
2028
+ previously known type.
2029
+
2030
+ For example::
2031
+
2032
+ def is_awaitable(val: object) -> TypeIs[Awaitable[Any]]:
2033
+ return hasattr(val, '__await__')
2034
+
2035
+ def f(val: Union[int, Awaitable[int]]) -> int:
2036
+ if is_awaitable(val):
2037
+ assert_type(val, Awaitable[int])
2038
+ else:
2039
+ assert_type(val, int)
2040
+
2041
+ ``TypeIs`` also works with type variables. For more information, see
2042
+ PEP 742 (Narrowing types with TypeIs).
2043
+ """)
2044
+
1915
2045
 
1916
2046
  # Vendored from cpython typing._SpecialFrom
1917
2047
  class _SpecialForm(typing._Final, _root=True):
@@ -1957,7 +2087,7 @@ class _SpecialForm(typing._Final, _root=True):
1957
2087
  return self._getitem(self, parameters)
1958
2088
 
1959
2089
 
1960
- if hasattr(typing, "LiteralString"):
2090
+ if hasattr(typing, "LiteralString"): # 3.11+
1961
2091
  LiteralString = typing.LiteralString
1962
2092
  else:
1963
2093
  @_SpecialForm
@@ -1980,7 +2110,7 @@ else:
1980
2110
  raise TypeError(f"{self} is not subscriptable")
1981
2111
 
1982
2112
 
1983
- if hasattr(typing, "Self"):
2113
+ if hasattr(typing, "Self"): # 3.11+
1984
2114
  Self = typing.Self
1985
2115
  else:
1986
2116
  @_SpecialForm
@@ -2001,7 +2131,7 @@ else:
2001
2131
  raise TypeError(f"{self} is not subscriptable")
2002
2132
 
2003
2133
 
2004
- if hasattr(typing, "Never"):
2134
+ if hasattr(typing, "Never"): # 3.11+
2005
2135
  Never = typing.Never
2006
2136
  else:
2007
2137
  @_SpecialForm
@@ -2031,10 +2161,10 @@ else:
2031
2161
  raise TypeError(f"{self} is not subscriptable")
2032
2162
 
2033
2163
 
2034
- if hasattr(typing, 'Required'):
2164
+ if hasattr(typing, 'Required'): # 3.11+
2035
2165
  Required = typing.Required
2036
2166
  NotRequired = typing.NotRequired
2037
- elif sys.version_info[:2] >= (3, 9):
2167
+ elif sys.version_info[:2] >= (3, 9): # 3.9-3.10
2038
2168
  @_ExtensionsSpecialForm
2039
2169
  def Required(self, parameters):
2040
2170
  """A special typing construct to mark a key of a total=False TypedDict
@@ -2072,7 +2202,7 @@ elif sys.version_info[:2] >= (3, 9):
2072
2202
  item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
2073
2203
  return typing._GenericAlias(self, (item,))
2074
2204
 
2075
- else:
2205
+ else: # 3.8
2076
2206
  class _RequiredForm(_ExtensionsSpecialForm, _root=True):
2077
2207
  def __getitem__(self, parameters):
2078
2208
  item = typing._type_check(parameters,
@@ -2112,6 +2242,53 @@ else:
2112
2242
  """)
2113
2243
 
2114
2244
 
2245
+ if hasattr(typing, 'ReadOnly'):
2246
+ ReadOnly = typing.ReadOnly
2247
+ elif sys.version_info[:2] >= (3, 9): # 3.9-3.12
2248
+ @_ExtensionsSpecialForm
2249
+ def ReadOnly(self, parameters):
2250
+ """A special typing construct to mark an item of a TypedDict as read-only.
2251
+
2252
+ For example:
2253
+
2254
+ class Movie(TypedDict):
2255
+ title: ReadOnly[str]
2256
+ year: int
2257
+
2258
+ def mutate_movie(m: Movie) -> None:
2259
+ m["year"] = 1992 # allowed
2260
+ m["title"] = "The Matrix" # typechecker error
2261
+
2262
+ There is no runtime checking for this property.
2263
+ """
2264
+ item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
2265
+ return typing._GenericAlias(self, (item,))
2266
+
2267
+ else: # 3.8
2268
+ class _ReadOnlyForm(_ExtensionsSpecialForm, _root=True):
2269
+ def __getitem__(self, parameters):
2270
+ item = typing._type_check(parameters,
2271
+ f'{self._name} accepts only a single type.')
2272
+ return typing._GenericAlias(self, (item,))
2273
+
2274
+ ReadOnly = _ReadOnlyForm(
2275
+ 'ReadOnly',
2276
+ doc="""A special typing construct to mark a key of a TypedDict as read-only.
2277
+
2278
+ For example:
2279
+
2280
+ class Movie(TypedDict):
2281
+ title: ReadOnly[str]
2282
+ year: int
2283
+
2284
+ def mutate_movie(m: Movie) -> None:
2285
+ m["year"] = 1992 # allowed
2286
+ m["title"] = "The Matrix" # typechecker error
2287
+
2288
+ There is no runtime checking for this propery.
2289
+ """)
2290
+
2291
+
2115
2292
  _UNPACK_DOC = """\
2116
2293
  Type unpack operator.
2117
2294
 
@@ -2160,7 +2337,7 @@ if sys.version_info >= (3, 12): # PEP 692 changed the repr of Unpack[]
2160
2337
  def _is_unpack(obj):
2161
2338
  return get_origin(obj) is Unpack
2162
2339
 
2163
- elif sys.version_info[:2] >= (3, 9):
2340
+ elif sys.version_info[:2] >= (3, 9): # 3.9+
2164
2341
  class _UnpackSpecialForm(_ExtensionsSpecialForm, _root=True):
2165
2342
  def __init__(self, getitem):
2166
2343
  super().__init__(getitem)
@@ -2169,6 +2346,17 @@ elif sys.version_info[:2] >= (3, 9):
2169
2346
  class _UnpackAlias(typing._GenericAlias, _root=True):
2170
2347
  __class__ = typing.TypeVar
2171
2348
 
2349
+ @property
2350
+ def __typing_unpacked_tuple_args__(self):
2351
+ assert self.__origin__ is Unpack
2352
+ assert len(self.__args__) == 1
2353
+ arg, = self.__args__
2354
+ if isinstance(arg, (typing._GenericAlias, _types.GenericAlias)):
2355
+ if arg.__origin__ is not tuple:
2356
+ raise TypeError("Unpack[...] must be used with a tuple type")
2357
+ return arg.__args__
2358
+ return None
2359
+
2172
2360
  @_UnpackSpecialForm
2173
2361
  def Unpack(self, parameters):
2174
2362
  item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
@@ -2177,7 +2365,7 @@ elif sys.version_info[:2] >= (3, 9):
2177
2365
  def _is_unpack(obj):
2178
2366
  return isinstance(obj, _UnpackAlias)
2179
2367
 
2180
- else:
2368
+ else: # 3.8
2181
2369
  class _UnpackAlias(typing._GenericAlias, _root=True):
2182
2370
  __class__ = typing.TypeVar
2183
2371
 
@@ -2193,7 +2381,20 @@ else:
2193
2381
  return isinstance(obj, _UnpackAlias)
2194
2382
 
2195
2383
 
2196
- if hasattr(typing, "TypeVarTuple"): # 3.11+
2384
+ if _PEP_696_IMPLEMENTED:
2385
+ from typing import TypeVarTuple
2386
+
2387
+ elif hasattr(typing, "TypeVarTuple"): # 3.11+
2388
+
2389
+ def _unpack_args(*args):
2390
+ newargs = []
2391
+ for arg in args:
2392
+ subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)
2393
+ if subargs is not None and not (subargs and subargs[-1] is ...):
2394
+ newargs.extend(subargs)
2395
+ else:
2396
+ newargs.append(arg)
2397
+ return newargs
2197
2398
 
2198
2399
  # Add default parameter - PEP 696
2199
2400
  class TypeVarTuple(metaclass=_TypeVarLikeMeta):
@@ -2201,16 +2402,63 @@ if hasattr(typing, "TypeVarTuple"): # 3.11+
2201
2402
 
2202
2403
  _backported_typevarlike = typing.TypeVarTuple
2203
2404
 
2204
- def __new__(cls, name, *, default=_marker):
2405
+ def __new__(cls, name, *, default=NoDefault):
2205
2406
  tvt = typing.TypeVarTuple(name)
2206
2407
  _set_default(tvt, default)
2207
2408
  _set_module(tvt)
2409
+
2410
+ def _typevartuple_prepare_subst(alias, args):
2411
+ params = alias.__parameters__
2412
+ typevartuple_index = params.index(tvt)
2413
+ for param in params[typevartuple_index + 1:]:
2414
+ if isinstance(param, TypeVarTuple):
2415
+ raise TypeError(
2416
+ f"More than one TypeVarTuple parameter in {alias}"
2417
+ )
2418
+
2419
+ alen = len(args)
2420
+ plen = len(params)
2421
+ left = typevartuple_index
2422
+ right = plen - typevartuple_index - 1
2423
+ var_tuple_index = None
2424
+ fillarg = None
2425
+ for k, arg in enumerate(args):
2426
+ if not isinstance(arg, type):
2427
+ subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)
2428
+ if subargs and len(subargs) == 2 and subargs[-1] is ...:
2429
+ if var_tuple_index is not None:
2430
+ raise TypeError(
2431
+ "More than one unpacked "
2432
+ "arbitrary-length tuple argument"
2433
+ )
2434
+ var_tuple_index = k
2435
+ fillarg = subargs[0]
2436
+ if var_tuple_index is not None:
2437
+ left = min(left, var_tuple_index)
2438
+ right = min(right, alen - var_tuple_index - 1)
2439
+ elif left + right > alen:
2440
+ raise TypeError(f"Too few arguments for {alias};"
2441
+ f" actual {alen}, expected at least {plen - 1}")
2442
+ if left == alen - right and tvt.has_default():
2443
+ replacement = _unpack_args(tvt.__default__)
2444
+ else:
2445
+ replacement = args[left: alen - right]
2446
+
2447
+ return (
2448
+ *args[:left],
2449
+ *([fillarg] * (typevartuple_index - left)),
2450
+ replacement,
2451
+ *([fillarg] * (plen - right - left - typevartuple_index - 1)),
2452
+ *args[alen - right:],
2453
+ )
2454
+
2455
+ tvt.__typing_prepare_subst__ = _typevartuple_prepare_subst
2208
2456
  return tvt
2209
2457
 
2210
2458
  def __init_subclass__(self, *args, **kwds):
2211
2459
  raise TypeError("Cannot subclass special typing classes")
2212
2460
 
2213
- else:
2461
+ else: # <=3.10
2214
2462
  class TypeVarTuple(_DefaultMixin):
2215
2463
  """Type variable tuple.
2216
2464
 
@@ -2261,7 +2509,7 @@ else:
2261
2509
  def __iter__(self):
2262
2510
  yield self.__unpacked__
2263
2511
 
2264
- def __init__(self, name, *, default=_marker):
2512
+ def __init__(self, name, *, default=NoDefault):
2265
2513
  self.__name__ = name
2266
2514
  _DefaultMixin.__init__(self, default)
2267
2515
 
@@ -2289,10 +2537,10 @@ else:
2289
2537
  raise TypeError("Cannot subclass special typing classes")
2290
2538
 
2291
2539
 
2292
- if hasattr(typing, "reveal_type"):
2540
+ if hasattr(typing, "reveal_type"): # 3.11+
2293
2541
  reveal_type = typing.reveal_type
2294
- else:
2295
- def reveal_type(__obj: T) -> T:
2542
+ else: # <=3.10
2543
+ def reveal_type(obj: T, /) -> T:
2296
2544
  """Reveal the inferred type of a variable.
2297
2545
 
2298
2546
  When a static type checker encounters a call to ``reveal_type()``,
@@ -2308,14 +2556,20 @@ else:
2308
2556
  argument and returns it unchanged.
2309
2557
 
2310
2558
  """
2311
- print(f"Runtime type is {type(__obj).__name__!r}", file=sys.stderr)
2312
- return __obj
2559
+ print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr)
2560
+ return obj
2313
2561
 
2314
2562
 
2315
- if hasattr(typing, "assert_never"):
2563
+ if hasattr(typing, "_ASSERT_NEVER_REPR_MAX_LENGTH"): # 3.11+
2564
+ _ASSERT_NEVER_REPR_MAX_LENGTH = typing._ASSERT_NEVER_REPR_MAX_LENGTH
2565
+ else: # <=3.10
2566
+ _ASSERT_NEVER_REPR_MAX_LENGTH = 100
2567
+
2568
+
2569
+ if hasattr(typing, "assert_never"): # 3.11+
2316
2570
  assert_never = typing.assert_never
2317
- else:
2318
- def assert_never(__arg: Never) -> Never:
2571
+ else: # <=3.10
2572
+ def assert_never(arg: Never, /) -> Never:
2319
2573
  """Assert to the type checker that a line of code is unreachable.
2320
2574
 
2321
2575
  Example::
@@ -2335,13 +2589,16 @@ else:
2335
2589
  At runtime, this throws an exception when called.
2336
2590
 
2337
2591
  """
2338
- raise AssertionError("Expected code to be unreachable")
2592
+ value = repr(arg)
2593
+ if len(value) > _ASSERT_NEVER_REPR_MAX_LENGTH:
2594
+ value = value[:_ASSERT_NEVER_REPR_MAX_LENGTH] + '...'
2595
+ raise AssertionError(f"Expected code to be unreachable, but got: {value}")
2339
2596
 
2340
2597
 
2341
- if sys.version_info >= (3, 12):
2598
+ if sys.version_info >= (3, 12): # 3.12+
2342
2599
  # dataclass_transform exists in 3.11 but lacks the frozen_default parameter
2343
2600
  dataclass_transform = typing.dataclass_transform
2344
- else:
2601
+ else: # <=3.11
2345
2602
  def dataclass_transform(
2346
2603
  *,
2347
2604
  eq_default: bool = True,
@@ -2428,18 +2685,18 @@ else:
2428
2685
  return decorator
2429
2686
 
2430
2687
 
2431
- if hasattr(typing, "override"):
2688
+ if hasattr(typing, "override"): # 3.12+
2432
2689
  override = typing.override
2433
- else:
2690
+ else: # <=3.11
2434
2691
  _F = typing.TypeVar("_F", bound=typing.Callable[..., typing.Any])
2435
2692
 
2436
- def override(__arg: _F) -> _F:
2693
+ def override(arg: _F, /) -> _F:
2437
2694
  """Indicate that a method is intended to override a method in a base class.
2438
2695
 
2439
2696
  Usage:
2440
2697
 
2441
2698
  class Base:
2442
- def method(self) -> None: ...
2699
+ def method(self) -> None:
2443
2700
  pass
2444
2701
 
2445
2702
  class Child(Base):
@@ -2460,28 +2717,26 @@ else:
2460
2717
 
2461
2718
  """
2462
2719
  try:
2463
- __arg.__override__ = True
2720
+ arg.__override__ = True
2464
2721
  except (AttributeError, TypeError):
2465
2722
  # Skip the attribute silently if it is not writable.
2466
2723
  # AttributeError happens if the object has __slots__ or a
2467
2724
  # read-only property, TypeError if it's a builtin class.
2468
2725
  pass
2469
- return __arg
2726
+ return arg
2470
2727
 
2471
2728
 
2472
- if hasattr(typing, "deprecated"):
2473
- deprecated = typing.deprecated
2729
+ if hasattr(warnings, "deprecated"):
2730
+ deprecated = warnings.deprecated
2474
2731
  else:
2475
2732
  _T = typing.TypeVar("_T")
2476
2733
 
2477
- def deprecated(
2478
- __msg: str,
2479
- *,
2480
- category: typing.Optional[typing.Type[Warning]] = DeprecationWarning,
2481
- stacklevel: int = 1,
2482
- ) -> typing.Callable[[_T], _T]:
2734
+ class deprecated:
2483
2735
  """Indicate that a class, function or overload is deprecated.
2484
2736
 
2737
+ When this decorator is applied to an object, the type checker
2738
+ will generate a diagnostic on usage of the deprecated object.
2739
+
2485
2740
  Usage:
2486
2741
 
2487
2742
  @deprecated("Use B instead")
@@ -2498,64 +2753,113 @@ else:
2498
2753
  @overload
2499
2754
  def g(x: str) -> int: ...
2500
2755
 
2501
- When this decorator is applied to an object, the type checker
2502
- will generate a diagnostic on usage of the deprecated object.
2503
-
2504
- The warning specified by ``category`` will be emitted on use
2505
- of deprecated objects. For functions, that happens on calls;
2506
- for classes, on instantiation. If the ``category`` is ``None``,
2507
- no warning is emitted. The ``stacklevel`` determines where the
2756
+ The warning specified by *category* will be emitted at runtime
2757
+ on use of deprecated objects. For functions, that happens on calls;
2758
+ for classes, on instantiation and on creation of subclasses.
2759
+ If the *category* is ``None``, no warning is emitted at runtime.
2760
+ The *stacklevel* determines where the
2508
2761
  warning is emitted. If it is ``1`` (the default), the warning
2509
2762
  is emitted at the direct caller of the deprecated object; if it
2510
2763
  is higher, it is emitted further up the stack.
2764
+ Static type checker behavior is not affected by the *category*
2765
+ and *stacklevel* arguments.
2511
2766
 
2512
- The decorator sets the ``__deprecated__``
2513
- attribute on the decorated object to the deprecation message
2514
- passed to the decorator. If applied to an overload, the decorator
2767
+ The deprecation message passed to the decorator is saved in the
2768
+ ``__deprecated__`` attribute on the decorated object.
2769
+ If applied to an overload, the decorator
2515
2770
  must be after the ``@overload`` decorator for the attribute to
2516
2771
  exist on the overload as returned by ``get_overloads()``.
2517
2772
 
2518
2773
  See PEP 702 for details.
2519
2774
 
2520
2775
  """
2521
- def decorator(__arg: _T) -> _T:
2776
+ def __init__(
2777
+ self,
2778
+ message: str,
2779
+ /,
2780
+ *,
2781
+ category: typing.Optional[typing.Type[Warning]] = DeprecationWarning,
2782
+ stacklevel: int = 1,
2783
+ ) -> None:
2784
+ if not isinstance(message, str):
2785
+ raise TypeError(
2786
+ "Expected an object of type str for 'message', not "
2787
+ f"{type(message).__name__!r}"
2788
+ )
2789
+ self.message = message
2790
+ self.category = category
2791
+ self.stacklevel = stacklevel
2792
+
2793
+ def __call__(self, arg: _T, /) -> _T:
2794
+ # Make sure the inner functions created below don't
2795
+ # retain a reference to self.
2796
+ msg = self.message
2797
+ category = self.category
2798
+ stacklevel = self.stacklevel
2522
2799
  if category is None:
2523
- __arg.__deprecated__ = __msg
2524
- return __arg
2525
- elif isinstance(__arg, type):
2526
- original_new = __arg.__new__
2527
- has_init = __arg.__init__ is not object.__init__
2800
+ arg.__deprecated__ = msg
2801
+ return arg
2802
+ elif isinstance(arg, type):
2803
+ import functools
2804
+ from types import MethodType
2805
+
2806
+ original_new = arg.__new__
2528
2807
 
2529
2808
  @functools.wraps(original_new)
2530
2809
  def __new__(cls, *args, **kwargs):
2531
- warnings.warn(__msg, category=category, stacklevel=stacklevel + 1)
2810
+ if cls is arg:
2811
+ warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
2532
2812
  if original_new is not object.__new__:
2533
2813
  return original_new(cls, *args, **kwargs)
2534
2814
  # Mirrors a similar check in object.__new__.
2535
- elif not has_init and (args or kwargs):
2815
+ elif cls.__init__ is object.__init__ and (args or kwargs):
2536
2816
  raise TypeError(f"{cls.__name__}() takes no arguments")
2537
2817
  else:
2538
2818
  return original_new(cls)
2539
2819
 
2540
- __arg.__new__ = staticmethod(__new__)
2541
- __arg.__deprecated__ = __new__.__deprecated__ = __msg
2542
- return __arg
2543
- elif callable(__arg):
2544
- @functools.wraps(__arg)
2820
+ arg.__new__ = staticmethod(__new__)
2821
+
2822
+ original_init_subclass = arg.__init_subclass__
2823
+ # We need slightly different behavior if __init_subclass__
2824
+ # is a bound method (likely if it was implemented in Python)
2825
+ if isinstance(original_init_subclass, MethodType):
2826
+ original_init_subclass = original_init_subclass.__func__
2827
+
2828
+ @functools.wraps(original_init_subclass)
2829
+ def __init_subclass__(*args, **kwargs):
2830
+ warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
2831
+ return original_init_subclass(*args, **kwargs)
2832
+
2833
+ arg.__init_subclass__ = classmethod(__init_subclass__)
2834
+ # Or otherwise, which likely means it's a builtin such as
2835
+ # object's implementation of __init_subclass__.
2836
+ else:
2837
+ @functools.wraps(original_init_subclass)
2838
+ def __init_subclass__(*args, **kwargs):
2839
+ warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
2840
+ return original_init_subclass(*args, **kwargs)
2841
+
2842
+ arg.__init_subclass__ = __init_subclass__
2843
+
2844
+ arg.__deprecated__ = __new__.__deprecated__ = msg
2845
+ __init_subclass__.__deprecated__ = msg
2846
+ return arg
2847
+ elif callable(arg):
2848
+ import functools
2849
+
2850
+ @functools.wraps(arg)
2545
2851
  def wrapper(*args, **kwargs):
2546
- warnings.warn(__msg, category=category, stacklevel=stacklevel + 1)
2547
- return __arg(*args, **kwargs)
2852
+ warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
2853
+ return arg(*args, **kwargs)
2548
2854
 
2549
- __arg.__deprecated__ = wrapper.__deprecated__ = __msg
2855
+ arg.__deprecated__ = wrapper.__deprecated__ = msg
2550
2856
  return wrapper
2551
2857
  else:
2552
2858
  raise TypeError(
2553
2859
  "@deprecated decorator with non-None category must be applied to "
2554
- f"a class or callable, not {__arg!r}"
2860
+ f"a class or callable, not {arg!r}"
2555
2861
  )
2556
2862
 
2557
- return decorator
2558
-
2559
2863
 
2560
2864
  # We have to do some monkey patching to deal with the dual nature of
2561
2865
  # Unpack/TypeVarTuple:
@@ -2565,11 +2869,223 @@ else:
2565
2869
  # counting generic parameters, so that when we subscript a generic,
2566
2870
  # the runtime doesn't try to substitute the Unpack with the subscripted type.
2567
2871
  if not hasattr(typing, "TypeVarTuple"):
2568
- typing._collect_type_vars = _collect_type_vars
2872
+ def _check_generic(cls, parameters, elen=_marker):
2873
+ """Check correct count for parameters of a generic cls (internal helper).
2874
+
2875
+ This gives a nice error message in case of count mismatch.
2876
+ """
2877
+ if not elen:
2878
+ raise TypeError(f"{cls} is not a generic class")
2879
+ if elen is _marker:
2880
+ if not hasattr(cls, "__parameters__") or not cls.__parameters__:
2881
+ raise TypeError(f"{cls} is not a generic class")
2882
+ elen = len(cls.__parameters__)
2883
+ alen = len(parameters)
2884
+ if alen != elen:
2885
+ expect_val = elen
2886
+ if hasattr(cls, "__parameters__"):
2887
+ parameters = [p for p in cls.__parameters__ if not _is_unpack(p)]
2888
+ num_tv_tuples = sum(isinstance(p, TypeVarTuple) for p in parameters)
2889
+ if (num_tv_tuples > 0) and (alen >= elen - num_tv_tuples):
2890
+ return
2891
+
2892
+ # deal with TypeVarLike defaults
2893
+ # required TypeVarLikes cannot appear after a defaulted one.
2894
+ if alen < elen:
2895
+ # since we validate TypeVarLike default in _collect_type_vars
2896
+ # or _collect_parameters we can safely check parameters[alen]
2897
+ if (
2898
+ getattr(parameters[alen], '__default__', NoDefault)
2899
+ is not NoDefault
2900
+ ):
2901
+ return
2902
+
2903
+ num_default_tv = sum(getattr(p, '__default__', NoDefault)
2904
+ is not NoDefault for p in parameters)
2905
+
2906
+ elen -= num_default_tv
2907
+
2908
+ expect_val = f"at least {elen}"
2909
+
2910
+ things = "arguments" if sys.version_info >= (3, 10) else "parameters"
2911
+ raise TypeError(f"Too {'many' if alen > elen else 'few'} {things}"
2912
+ f" for {cls}; actual {alen}, expected {expect_val}")
2913
+ else:
2914
+ # Python 3.11+
2915
+
2916
+ def _check_generic(cls, parameters, elen):
2917
+ """Check correct count for parameters of a generic cls (internal helper).
2918
+
2919
+ This gives a nice error message in case of count mismatch.
2920
+ """
2921
+ if not elen:
2922
+ raise TypeError(f"{cls} is not a generic class")
2923
+ alen = len(parameters)
2924
+ if alen != elen:
2925
+ expect_val = elen
2926
+ if hasattr(cls, "__parameters__"):
2927
+ parameters = [p for p in cls.__parameters__ if not _is_unpack(p)]
2928
+
2929
+ # deal with TypeVarLike defaults
2930
+ # required TypeVarLikes cannot appear after a defaulted one.
2931
+ if alen < elen:
2932
+ # since we validate TypeVarLike default in _collect_type_vars
2933
+ # or _collect_parameters we can safely check parameters[alen]
2934
+ if (
2935
+ getattr(parameters[alen], '__default__', NoDefault)
2936
+ is not NoDefault
2937
+ ):
2938
+ return
2939
+
2940
+ num_default_tv = sum(getattr(p, '__default__', NoDefault)
2941
+ is not NoDefault for p in parameters)
2942
+
2943
+ elen -= num_default_tv
2944
+
2945
+ expect_val = f"at least {elen}"
2946
+
2947
+ raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments"
2948
+ f" for {cls}; actual {alen}, expected {expect_val}")
2949
+
2950
+ if not _PEP_696_IMPLEMENTED:
2569
2951
  typing._check_generic = _check_generic
2570
2952
 
2571
2953
 
2572
- # Backport typing.NamedTuple as it exists in Python 3.12.
2954
+ def _has_generic_or_protocol_as_origin() -> bool:
2955
+ try:
2956
+ frame = sys._getframe(2)
2957
+ # - Catch AttributeError: not all Python implementations have sys._getframe()
2958
+ # - Catch ValueError: maybe we're called from an unexpected module
2959
+ # and the call stack isn't deep enough
2960
+ except (AttributeError, ValueError):
2961
+ return False # err on the side of leniency
2962
+ else:
2963
+ # If we somehow get invoked from outside typing.py,
2964
+ # also err on the side of leniency
2965
+ if frame.f_globals.get("__name__") != "typing":
2966
+ return False
2967
+ origin = frame.f_locals.get("origin")
2968
+ # Cannot use "in" because origin may be an object with a buggy __eq__ that
2969
+ # throws an error.
2970
+ return origin is typing.Generic or origin is Protocol or origin is typing.Protocol
2971
+
2972
+
2973
+ _TYPEVARTUPLE_TYPES = {TypeVarTuple, getattr(typing, "TypeVarTuple", None)}
2974
+
2975
+
2976
+ def _is_unpacked_typevartuple(x) -> bool:
2977
+ if get_origin(x) is not Unpack:
2978
+ return False
2979
+ args = get_args(x)
2980
+ return (
2981
+ bool(args)
2982
+ and len(args) == 1
2983
+ and type(args[0]) in _TYPEVARTUPLE_TYPES
2984
+ )
2985
+
2986
+
2987
+ # Python 3.11+ _collect_type_vars was renamed to _collect_parameters
2988
+ if hasattr(typing, '_collect_type_vars'):
2989
+ def _collect_type_vars(types, typevar_types=None):
2990
+ """Collect all type variable contained in types in order of
2991
+ first appearance (lexicographic order). For example::
2992
+
2993
+ _collect_type_vars((T, List[S, T])) == (T, S)
2994
+ """
2995
+ if typevar_types is None:
2996
+ typevar_types = typing.TypeVar
2997
+ tvars = []
2998
+
2999
+ # A required TypeVarLike cannot appear after a TypeVarLike with a default
3000
+ # if it was a direct call to `Generic[]` or `Protocol[]`
3001
+ enforce_default_ordering = _has_generic_or_protocol_as_origin()
3002
+ default_encountered = False
3003
+
3004
+ # Also, a TypeVarLike with a default cannot appear after a TypeVarTuple
3005
+ type_var_tuple_encountered = False
3006
+
3007
+ for t in types:
3008
+ if _is_unpacked_typevartuple(t):
3009
+ type_var_tuple_encountered = True
3010
+ elif isinstance(t, typevar_types) and t not in tvars:
3011
+ if enforce_default_ordering:
3012
+ has_default = getattr(t, '__default__', NoDefault) is not NoDefault
3013
+ if has_default:
3014
+ if type_var_tuple_encountered:
3015
+ raise TypeError('Type parameter with a default'
3016
+ ' follows TypeVarTuple')
3017
+ default_encountered = True
3018
+ elif default_encountered:
3019
+ raise TypeError(f'Type parameter {t!r} without a default'
3020
+ ' follows type parameter with a default')
3021
+
3022
+ tvars.append(t)
3023
+ if _should_collect_from_parameters(t):
3024
+ tvars.extend([t for t in t.__parameters__ if t not in tvars])
3025
+ return tuple(tvars)
3026
+
3027
+ typing._collect_type_vars = _collect_type_vars
3028
+ else:
3029
+ def _collect_parameters(args):
3030
+ """Collect all type variables and parameter specifications in args
3031
+ in order of first appearance (lexicographic order).
3032
+
3033
+ For example::
3034
+
3035
+ assert _collect_parameters((T, Callable[P, T])) == (T, P)
3036
+ """
3037
+ parameters = []
3038
+
3039
+ # A required TypeVarLike cannot appear after a TypeVarLike with default
3040
+ # if it was a direct call to `Generic[]` or `Protocol[]`
3041
+ enforce_default_ordering = _has_generic_or_protocol_as_origin()
3042
+ default_encountered = False
3043
+
3044
+ # Also, a TypeVarLike with a default cannot appear after a TypeVarTuple
3045
+ type_var_tuple_encountered = False
3046
+
3047
+ for t in args:
3048
+ if isinstance(t, type):
3049
+ # We don't want __parameters__ descriptor of a bare Python class.
3050
+ pass
3051
+ elif isinstance(t, tuple):
3052
+ # `t` might be a tuple, when `ParamSpec` is substituted with
3053
+ # `[T, int]`, or `[int, *Ts]`, etc.
3054
+ for x in t:
3055
+ for collected in _collect_parameters([x]):
3056
+ if collected not in parameters:
3057
+ parameters.append(collected)
3058
+ elif hasattr(t, '__typing_subst__'):
3059
+ if t not in parameters:
3060
+ if enforce_default_ordering:
3061
+ has_default = (
3062
+ getattr(t, '__default__', NoDefault) is not NoDefault
3063
+ )
3064
+
3065
+ if type_var_tuple_encountered and has_default:
3066
+ raise TypeError('Type parameter with a default'
3067
+ ' follows TypeVarTuple')
3068
+
3069
+ if has_default:
3070
+ default_encountered = True
3071
+ elif default_encountered:
3072
+ raise TypeError(f'Type parameter {t!r} without a default'
3073
+ ' follows type parameter with a default')
3074
+
3075
+ parameters.append(t)
3076
+ else:
3077
+ if _is_unpacked_typevartuple(t):
3078
+ type_var_tuple_encountered = True
3079
+ for x in getattr(t, '__parameters__', ()):
3080
+ if x not in parameters:
3081
+ parameters.append(x)
3082
+
3083
+ return tuple(parameters)
3084
+
3085
+ if not _PEP_696_IMPLEMENTED:
3086
+ typing._collect_parameters = _collect_parameters
3087
+
3088
+ # Backport typing.NamedTuple as it exists in Python 3.13.
2573
3089
  # In 3.11, the ability to define generic `NamedTuple`s was supported.
2574
3090
  # This was explicitly disallowed in 3.9-3.10, and only half-worked in <=3.8.
2575
3091
  # On 3.12, we added __orig_bases__ to call-based NamedTuples
@@ -2601,7 +3117,13 @@ else:
2601
3117
  raise TypeError(
2602
3118
  'can only inherit from a NamedTuple type and Generic')
2603
3119
  bases = tuple(tuple if base is _NamedTuple else base for base in bases)
2604
- types = ns.get('__annotations__', {})
3120
+ if "__annotations__" in ns:
3121
+ types = ns["__annotations__"]
3122
+ elif "__annotate__" in ns:
3123
+ # TODO: Use inspect.VALUE here, and make the annotations lazily evaluated
3124
+ types = ns["__annotate__"](1)
3125
+ else:
3126
+ types = {}
2605
3127
  default_names = []
2606
3128
  for field_name in types:
2607
3129
  if field_name in ns:
@@ -2624,16 +3146,47 @@ else:
2624
3146
  class_getitem = typing.Generic.__class_getitem__.__func__
2625
3147
  nm_tpl.__class_getitem__ = classmethod(class_getitem)
2626
3148
  # update from user namespace without overriding special namedtuple attributes
2627
- for key in ns:
3149
+ for key, val in ns.items():
2628
3150
  if key in _prohibited_namedtuple_fields:
2629
3151
  raise AttributeError("Cannot overwrite NamedTuple attribute " + key)
2630
- elif key not in _special_namedtuple_fields and key not in nm_tpl._fields:
2631
- setattr(nm_tpl, key, ns[key])
3152
+ elif key not in _special_namedtuple_fields:
3153
+ if key not in nm_tpl._fields:
3154
+ setattr(nm_tpl, key, ns[key])
3155
+ try:
3156
+ set_name = type(val).__set_name__
3157
+ except AttributeError:
3158
+ pass
3159
+ else:
3160
+ try:
3161
+ set_name(val, nm_tpl, key)
3162
+ except BaseException as e:
3163
+ msg = (
3164
+ f"Error calling __set_name__ on {type(val).__name__!r} "
3165
+ f"instance {key!r} in {typename!r}"
3166
+ )
3167
+ # BaseException.add_note() existed on py311,
3168
+ # but the __set_name__ machinery didn't start
3169
+ # using add_note() until py312.
3170
+ # Making sure exceptions are raised in the same way
3171
+ # as in "normal" classes seems most important here.
3172
+ if sys.version_info >= (3, 12):
3173
+ e.add_note(msg)
3174
+ raise
3175
+ else:
3176
+ raise RuntimeError(msg) from e
3177
+
2632
3178
  if typing.Generic in bases:
2633
3179
  nm_tpl.__init_subclass__()
2634
3180
  return nm_tpl
2635
3181
 
2636
- def NamedTuple(__typename, __fields=_marker, **kwargs):
3182
+ _NamedTuple = type.__new__(_NamedTupleMeta, 'NamedTuple', (), {})
3183
+
3184
+ def _namedtuple_mro_entries(bases):
3185
+ assert NamedTuple in bases
3186
+ return (_NamedTuple,)
3187
+
3188
+ @_ensure_subclassable(_namedtuple_mro_entries)
3189
+ def NamedTuple(typename, fields=_marker, /, **kwargs):
2637
3190
  """Typed version of namedtuple.
2638
3191
 
2639
3192
  Usage::
@@ -2653,7 +3206,7 @@ else:
2653
3206
 
2654
3207
  Employee = NamedTuple('Employee', [('name', str), ('id', int)])
2655
3208
  """
2656
- if __fields is _marker:
3209
+ if fields is _marker:
2657
3210
  if kwargs:
2658
3211
  deprecated_thing = "Creating NamedTuple classes using keyword arguments"
2659
3212
  deprecation_msg = (
@@ -2662,14 +3215,14 @@ else:
2662
3215
  )
2663
3216
  else:
2664
3217
  deprecated_thing = "Failing to pass a value for the 'fields' parameter"
2665
- example = f"`{__typename} = NamedTuple({__typename!r}, [])`"
3218
+ example = f"`{typename} = NamedTuple({typename!r}, [])`"
2666
3219
  deprecation_msg = (
2667
3220
  "{name} is deprecated and will be disallowed in Python {remove}. "
2668
3221
  "To create a NamedTuple class with 0 fields "
2669
3222
  "using the functional syntax, "
2670
3223
  "pass an empty list, e.g. "
2671
3224
  ) + example + "."
2672
- elif __fields is None:
3225
+ elif fields is None:
2673
3226
  if kwargs:
2674
3227
  raise TypeError(
2675
3228
  "Cannot pass `None` as the 'fields' parameter "
@@ -2677,7 +3230,7 @@ else:
2677
3230
  )
2678
3231
  else:
2679
3232
  deprecated_thing = "Passing `None` as the 'fields' parameter"
2680
- example = f"`{__typename} = NamedTuple({__typename!r}, [])`"
3233
+ example = f"`{typename} = NamedTuple({typename!r}, [])`"
2681
3234
  deprecation_msg = (
2682
3235
  "{name} is deprecated and will be disallowed in Python {remove}. "
2683
3236
  "To create a NamedTuple class with 0 fields "
@@ -2687,36 +3240,22 @@ else:
2687
3240
  elif kwargs:
2688
3241
  raise TypeError("Either list of fields or keywords"
2689
3242
  " can be provided to NamedTuple, not both")
2690
- if __fields is _marker or __fields is None:
3243
+ if fields is _marker or fields is None:
2691
3244
  warnings.warn(
2692
3245
  deprecation_msg.format(name=deprecated_thing, remove="3.15"),
2693
3246
  DeprecationWarning,
2694
3247
  stacklevel=2,
2695
3248
  )
2696
- __fields = kwargs.items()
2697
- nt = _make_nmtuple(__typename, __fields, module=_caller())
3249
+ fields = kwargs.items()
3250
+ nt = _make_nmtuple(typename, fields, module=_caller())
2698
3251
  nt.__orig_bases__ = (NamedTuple,)
2699
3252
  return nt
2700
3253
 
2701
- _NamedTuple = type.__new__(_NamedTupleMeta, 'NamedTuple', (), {})
2702
-
2703
- # On 3.8+, alter the signature so that it matches typing.NamedTuple.
2704
- # The signature of typing.NamedTuple on >=3.8 is invalid syntax in Python 3.7,
2705
- # so just leave the signature as it is on 3.7.
2706
- if sys.version_info >= (3, 8):
2707
- NamedTuple.__text_signature__ = '(typename, fields=None, /, **kwargs)'
2708
-
2709
- def _namedtuple_mro_entries(bases):
2710
- assert NamedTuple in bases
2711
- return (_NamedTuple,)
2712
-
2713
- NamedTuple.__mro_entries__ = _namedtuple_mro_entries
2714
-
2715
3254
 
2716
3255
  if hasattr(collections.abc, "Buffer"):
2717
3256
  Buffer = collections.abc.Buffer
2718
3257
  else:
2719
- class Buffer(abc.ABC):
3258
+ class Buffer(abc.ABC): # noqa: B024
2720
3259
  """Base class for classes that implement the buffer protocol.
2721
3260
 
2722
3261
  The buffer protocol allows Python objects to expose a low-level
@@ -2746,7 +3285,7 @@ else:
2746
3285
  if hasattr(_types, "get_original_bases"):
2747
3286
  get_original_bases = _types.get_original_bases
2748
3287
  else:
2749
- def get_original_bases(__cls):
3288
+ def get_original_bases(cls, /):
2750
3289
  """Return the class's "original" bases prior to modification by `__mro_entries__`.
2751
3290
 
2752
3291
  Examples::
@@ -2768,14 +3307,11 @@ else:
2768
3307
  assert get_original_bases(int) == (object,)
2769
3308
  """
2770
3309
  try:
2771
- return __cls.__orig_bases__
3310
+ return cls.__dict__.get("__orig_bases__", cls.__bases__)
2772
3311
  except AttributeError:
2773
- try:
2774
- return __cls.__bases__
2775
- except AttributeError:
2776
- raise TypeError(
2777
- f'Expected an instance of type, not {type(__cls).__name__!r}'
2778
- ) from None
3312
+ raise TypeError(
3313
+ f'Expected an instance of type, not {type(cls).__name__!r}'
3314
+ ) from None
2779
3315
 
2780
3316
 
2781
3317
  # NewType is a class on Python 3.10+, making it pickleable
@@ -2797,7 +3333,7 @@ else:
2797
3333
  num = UserId(5) + 1 # type: int
2798
3334
  """
2799
3335
 
2800
- def __call__(self, obj):
3336
+ def __call__(self, obj, /):
2801
3337
  return obj
2802
3338
 
2803
3339
  def __init__(self, name, tp):
@@ -2902,13 +3438,13 @@ else:
2902
3438
  # Setting this attribute closes the TypeAliasType from further modification
2903
3439
  self.__name__ = name
2904
3440
 
2905
- def __setattr__(self, __name: str, __value: object) -> None:
3441
+ def __setattr__(self, name: str, value: object, /) -> None:
2906
3442
  if hasattr(self, "__name__"):
2907
- self._raise_attribute_error(__name)
2908
- super().__setattr__(__name, __value)
3443
+ self._raise_attribute_error(name)
3444
+ super().__setattr__(name, value)
2909
3445
 
2910
- def __delattr__(self, __name: str) -> Never:
2911
- self._raise_attribute_error(__name)
3446
+ def __delattr__(self, name: str, /) -> Never:
3447
+ self._raise_attribute_error(name)
2912
3448
 
2913
3449
  def _raise_attribute_error(self, name: str) -> Never:
2914
3450
  # Match the Python 3.12 error messages exactly
@@ -2969,7 +3505,7 @@ if hasattr(typing, "is_protocol"):
2969
3505
  is_protocol = typing.is_protocol
2970
3506
  get_protocol_members = typing.get_protocol_members
2971
3507
  else:
2972
- def is_protocol(__tp: type) -> bool:
3508
+ def is_protocol(tp: type, /) -> bool:
2973
3509
  """Return True if the given type is a Protocol.
2974
3510
 
2975
3511
  Example::
@@ -2984,12 +3520,13 @@ else:
2984
3520
  False
2985
3521
  """
2986
3522
  return (
2987
- isinstance(__tp, type)
2988
- and getattr(__tp, '_is_protocol', False)
2989
- and __tp != Protocol
3523
+ isinstance(tp, type)
3524
+ and getattr(tp, '_is_protocol', False)
3525
+ and tp is not Protocol
3526
+ and tp is not typing.Protocol
2990
3527
  )
2991
3528
 
2992
- def get_protocol_members(__tp: type) -> typing.FrozenSet[str]:
3529
+ def get_protocol_members(tp: type, /) -> typing.FrozenSet[str]:
2993
3530
  """Return the set of members defined in a Protocol.
2994
3531
 
2995
3532
  Example::
@@ -3003,11 +3540,63 @@ else:
3003
3540
 
3004
3541
  Raise a TypeError for arguments that are not Protocols.
3005
3542
  """
3006
- if not is_protocol(__tp):
3007
- raise TypeError(f'{__tp!r} is not a Protocol')
3008
- if hasattr(__tp, '__protocol_attrs__'):
3009
- return frozenset(__tp.__protocol_attrs__)
3010
- return frozenset(_get_protocol_attrs(__tp))
3543
+ if not is_protocol(tp):
3544
+ raise TypeError(f'{tp!r} is not a Protocol')
3545
+ if hasattr(tp, '__protocol_attrs__'):
3546
+ return frozenset(tp.__protocol_attrs__)
3547
+ return frozenset(_get_protocol_attrs(tp))
3548
+
3549
+
3550
+ if hasattr(typing, "Doc"):
3551
+ Doc = typing.Doc
3552
+ else:
3553
+ class Doc:
3554
+ """Define the documentation of a type annotation using ``Annotated``, to be
3555
+ used in class attributes, function and method parameters, return values,
3556
+ and variables.
3557
+
3558
+ The value should be a positional-only string literal to allow static tools
3559
+ like editors and documentation generators to use it.
3560
+
3561
+ This complements docstrings.
3562
+
3563
+ The string value passed is available in the attribute ``documentation``.
3564
+
3565
+ Example::
3566
+
3567
+ >>> from typing_extensions import Annotated, Doc
3568
+ >>> def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: ...
3569
+ """
3570
+ def __init__(self, documentation: str, /) -> None:
3571
+ self.documentation = documentation
3572
+
3573
+ def __repr__(self) -> str:
3574
+ return f"Doc({self.documentation!r})"
3575
+
3576
+ def __hash__(self) -> int:
3577
+ return hash(self.documentation)
3578
+
3579
+ def __eq__(self, other: object) -> bool:
3580
+ if not isinstance(other, Doc):
3581
+ return NotImplemented
3582
+ return self.documentation == other.documentation
3583
+
3584
+
3585
+ _CapsuleType = getattr(_types, "CapsuleType", None)
3586
+
3587
+ if _CapsuleType is None:
3588
+ try:
3589
+ import _socket
3590
+ except ImportError:
3591
+ pass
3592
+ else:
3593
+ _CAPI = getattr(_socket, "CAPI", None)
3594
+ if _CAPI is not None:
3595
+ _CapsuleType = type(_CAPI)
3596
+
3597
+ if _CapsuleType is not None:
3598
+ CapsuleType = _CapsuleType
3599
+ __all__.append("CapsuleType")
3011
3600
 
3012
3601
 
3013
3602
  # Aliases for items that have always been in typing.
@@ -3023,7 +3612,6 @@ Container = typing.Container
3023
3612
  Dict = typing.Dict
3024
3613
  ForwardRef = typing.ForwardRef
3025
3614
  FrozenSet = typing.FrozenSet
3026
- Generator = typing.Generator
3027
3615
  Generic = typing.Generic
3028
3616
  Hashable = typing.Hashable
3029
3617
  IO = typing.IO