metaflow 2.15.5__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.
- metaflow/_vendor/typeguard/_checkers.py +259 -95
- metaflow/_vendor/typeguard/_config.py +4 -4
- metaflow/_vendor/typeguard/_decorators.py +8 -12
- metaflow/_vendor/typeguard/_functions.py +33 -32
- metaflow/_vendor/typeguard/_pytest_plugin.py +40 -13
- metaflow/_vendor/typeguard/_suppression.py +3 -5
- metaflow/_vendor/typeguard/_transformer.py +84 -48
- metaflow/_vendor/typeguard/_union_transformer.py +1 -0
- metaflow/_vendor/typeguard/_utils.py +13 -9
- metaflow/_vendor/typing_extensions.py +1088 -500
- metaflow/_vendor/v3_7/__init__.py +1 -0
- metaflow/_vendor/v3_7/importlib_metadata/__init__.py +1063 -0
- metaflow/_vendor/v3_7/importlib_metadata/_adapters.py +68 -0
- metaflow/_vendor/v3_7/importlib_metadata/_collections.py +30 -0
- metaflow/_vendor/v3_7/importlib_metadata/_compat.py +71 -0
- metaflow/_vendor/v3_7/importlib_metadata/_functools.py +104 -0
- metaflow/_vendor/v3_7/importlib_metadata/_itertools.py +73 -0
- metaflow/_vendor/v3_7/importlib_metadata/_meta.py +48 -0
- metaflow/_vendor/v3_7/importlib_metadata/_text.py +99 -0
- metaflow/_vendor/v3_7/importlib_metadata/py.typed +0 -0
- metaflow/_vendor/v3_7/typeguard/__init__.py +48 -0
- metaflow/_vendor/v3_7/typeguard/_checkers.py +906 -0
- metaflow/_vendor/v3_7/typeguard/_config.py +108 -0
- metaflow/_vendor/v3_7/typeguard/_decorators.py +237 -0
- metaflow/_vendor/v3_7/typeguard/_exceptions.py +42 -0
- metaflow/_vendor/v3_7/typeguard/_functions.py +310 -0
- metaflow/_vendor/v3_7/typeguard/_importhook.py +213 -0
- metaflow/_vendor/v3_7/typeguard/_memo.py +48 -0
- metaflow/_vendor/v3_7/typeguard/_pytest_plugin.py +100 -0
- metaflow/_vendor/v3_7/typeguard/_suppression.py +88 -0
- metaflow/_vendor/v3_7/typeguard/_transformer.py +1207 -0
- metaflow/_vendor/v3_7/typeguard/_union_transformer.py +54 -0
- metaflow/_vendor/v3_7/typeguard/_utils.py +169 -0
- metaflow/_vendor/v3_7/typeguard/py.typed +0 -0
- metaflow/_vendor/v3_7/typing_extensions.py +3072 -0
- metaflow/_vendor/v3_7/zipp.py +329 -0
- metaflow/cmd/develop/stubs.py +1 -1
- metaflow/extension_support/__init__.py +1 -1
- metaflow/plugins/pypi/utils.py +4 -0
- metaflow/runner/click_api.py +7 -2
- metaflow/vendor.py +1 -0
- metaflow/version.py +1 -1
- {metaflow-2.15.5.dist-info → metaflow-2.15.6.dist-info}/METADATA +2 -2
- {metaflow-2.15.5.dist-info → metaflow-2.15.6.dist-info}/RECORD +51 -25
- {metaflow-2.15.5.data → metaflow-2.15.6.data}/data/share/metaflow/devtools/Makefile +0 -0
- {metaflow-2.15.5.data → metaflow-2.15.6.data}/data/share/metaflow/devtools/Tiltfile +0 -0
- {metaflow-2.15.5.data → metaflow-2.15.6.data}/data/share/metaflow/devtools/pick_services.sh +0 -0
- {metaflow-2.15.5.dist-info → metaflow-2.15.6.dist-info}/LICENSE +0 -0
- {metaflow-2.15.5.dist-info → metaflow-2.15.6.dist-info}/WHEEL +0 -0
- {metaflow-2.15.5.dist-info → metaflow-2.15.6.dist-info}/entry_points.txt +0 -0
- {metaflow-2.15.5.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
|
-
|
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
|
-
"
|
505
|
-
"
|
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
|
-
#
|
586
|
-
#
|
587
|
-
if sys.version_info >= (3,
|
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
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
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
|
-
|
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,
|
582
|
+
elif {Protocol, typing.Protocol} & set(bases):
|
622
583
|
for base in bases:
|
623
584
|
if not (
|
624
|
-
base in {object, typing.Generic, 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
|
-
|
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
|
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
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
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
|
-
|
751
|
-
|
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
|
-
|
755
|
-
|
756
|
-
|
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
|
-
|
759
|
-
|
760
|
-
|
710
|
+
# Set (or override) the protocol subclass hook.
|
711
|
+
if '__subclasshook__' not in cls.__dict__:
|
712
|
+
cls.__subclasshook__ = _proto_hook
|
761
713
|
|
762
|
-
|
763
|
-
|
764
|
-
|
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
|
-
|
774
|
-
|
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
|
-
|
777
|
-
|
778
|
-
|
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
|
-
|
781
|
-
return x.meth()
|
730
|
+
For example::
|
782
731
|
|
783
|
-
|
732
|
+
@runtime_checkable
|
733
|
+
class Closable(Protocol):
|
734
|
+
def close(self): ...
|
784
735
|
|
785
|
-
|
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
|
-
|
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
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
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"
|
813
|
-
|
814
|
-
|
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
|
-
|
829
|
-
|
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
|
-
#
|
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.
|
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
|
-
|
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
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
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"
|
1000
|
-
tp_dict = type.__new__(_TypedDictMeta,
|
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__ ==
|
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
|
-
|
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
|
-
|
1026
|
-
|
1027
|
-
|
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
|
-
|
1032
|
-
|
1033
|
-
|
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
|
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
|
-
|
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
|
1110
|
-
if
|
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"`{
|
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
|
-
|
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(
|
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(
|
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(
|
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
|
1166
|
+
return val
|
1188
1167
|
|
1189
1168
|
|
1190
|
-
if hasattr(typing, "
|
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.
|
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__,
|
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.
|
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__,
|
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.
|
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
|
-
|
1469
|
-
|
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
|
-
|
1498
|
-
|
1499
|
-
|
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
|
-
|
1506
|
+
_backported_typevarlike = typing.TypeVar
|
1502
1507
|
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
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
|
-
|
1522
|
-
|
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.
|
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
|
-
|
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=
|
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.
|
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=
|
1682
|
-
|
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.
|
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.
|
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
|
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.
|
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.
|
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
|
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=
|
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=
|
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(
|
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(
|
2312
|
-
return
|
2559
|
+
print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr)
|
2560
|
+
return obj
|
2313
2561
|
|
2314
2562
|
|
2315
|
-
if hasattr(typing, "
|
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(
|
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
|
-
|
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(
|
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
|
-
|
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
|
2726
|
+
return arg
|
2470
2727
|
|
2471
2728
|
|
2472
|
-
if hasattr(
|
2473
|
-
deprecated =
|
2729
|
+
if hasattr(warnings, "deprecated"):
|
2730
|
+
deprecated = warnings.deprecated
|
2474
2731
|
else:
|
2475
2732
|
_T = typing.TypeVar("_T")
|
2476
2733
|
|
2477
|
-
|
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
|
-
|
2502
|
-
|
2503
|
-
|
2504
|
-
|
2505
|
-
|
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
|
2513
|
-
attribute on the decorated object
|
2514
|
-
|
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
|
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
|
-
|
2524
|
-
return
|
2525
|
-
elif isinstance(
|
2526
|
-
|
2527
|
-
|
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
|
-
|
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
|
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
|
-
|
2541
|
-
|
2542
|
-
|
2543
|
-
|
2544
|
-
|
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(
|
2547
|
-
return
|
2852
|
+
warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
|
2853
|
+
return arg(*args, **kwargs)
|
2548
2854
|
|
2549
|
-
|
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 {
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
2631
|
-
|
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
|
-
|
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
|
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"`{
|
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
|
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"`{
|
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
|
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
|
-
|
2697
|
-
nt = _make_nmtuple(
|
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(
|
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
|
3310
|
+
return cls.__dict__.get("__orig_bases__", cls.__bases__)
|
2772
3311
|
except AttributeError:
|
2773
|
-
|
2774
|
-
|
2775
|
-
|
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,
|
3441
|
+
def __setattr__(self, name: str, value: object, /) -> None:
|
2906
3442
|
if hasattr(self, "__name__"):
|
2907
|
-
self._raise_attribute_error(
|
2908
|
-
super().__setattr__(
|
3443
|
+
self._raise_attribute_error(name)
|
3444
|
+
super().__setattr__(name, value)
|
2909
3445
|
|
2910
|
-
def __delattr__(self,
|
2911
|
-
self._raise_attribute_error(
|
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(
|
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(
|
2988
|
-
and getattr(
|
2989
|
-
and
|
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(
|
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(
|
3007
|
-
raise TypeError(f'{
|
3008
|
-
if hasattr(
|
3009
|
-
return frozenset(
|
3010
|
-
return frozenset(_get_protocol_attrs(
|
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
|