Skip to content

Commit d5946d4

Browse files
committed
Update typing.py from CPython 3.13.5
1 parent c764126 commit d5946d4

File tree

1 file changed

+85
-43
lines changed

1 file changed

+85
-43
lines changed

Lib/typing.py

Lines changed: 85 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ def _should_unflatten_callable_args(typ, args):
220220
>>> P = ParamSpec('P')
221221
>>> collections.abc.Callable[[int, int], str].__args__ == (int, int, str)
222222
True
223+
>>> collections.abc.Callable[P, str].__args__ == (P, str)
224+
True
223225
224226
As a result, if we need to reconstruct the Callable from its __args__,
225227
we need to unflatten it.
@@ -263,6 +265,8 @@ def _collect_type_parameters(args, *, enforce_default_ordering: bool = True):
263265
264266
>>> P = ParamSpec('P')
265267
>>> T = TypeVar('T')
268+
>>> _collect_type_parameters((T, Callable[P, T]))
269+
(~T, ~P)
266270
"""
267271
# required type parameter cannot appear after parameter with default
268272
default_encountered = False
@@ -2090,11 +2094,11 @@ def __subclasscheck__(cls, other):
20902094
and cls.__dict__.get("__subclasshook__") is _proto_hook
20912095
):
20922096
_type_check_issubclass_arg_1(other)
2093-
# non_method_attrs = sorted(cls.__non_callable_proto_members__)
2094-
# raise TypeError(
2095-
# "Protocols with non-method members don't support issubclass()."
2096-
# f" Non-method members: {str(non_method_attrs)[1:-1]}."
2097-
# )
2097+
non_method_attrs = sorted(cls.__non_callable_proto_members__)
2098+
raise TypeError(
2099+
"Protocols with non-method members don't support issubclass()."
2100+
f" Non-method members: {str(non_method_attrs)[1:-1]}."
2101+
)
20982102
return _abc_subclasscheck(cls, other)
20992103

21002104
def __instancecheck__(cls, instance):
@@ -2526,6 +2530,18 @@ def get_origin(tp):
25262530
25272531
This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar,
25282532
Annotated, and others. Return None for unsupported types.
2533+
2534+
Examples::
2535+
2536+
>>> P = ParamSpec('P')
2537+
>>> assert get_origin(Literal[42]) is Literal
2538+
>>> assert get_origin(int) is None
2539+
>>> assert get_origin(ClassVar[int]) is ClassVar
2540+
>>> assert get_origin(Generic) is Generic
2541+
>>> assert get_origin(Generic[T]) is Generic
2542+
>>> assert get_origin(Union[T, int]) is Union
2543+
>>> assert get_origin(List[Tuple[T, T]][int]) is list
2544+
>>> assert get_origin(P.args) is P
25292545
"""
25302546
if isinstance(tp, _AnnotatedAlias):
25312547
return Annotated
@@ -2548,6 +2564,10 @@ def get_args(tp):
25482564
25492565
>>> T = TypeVar('T')
25502566
>>> assert get_args(Dict[str, int]) == (str, int)
2567+
>>> assert get_args(int) == ()
2568+
>>> assert get_args(Union[int, Union[T, int], str][int]) == (int, str)
2569+
>>> assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
2570+
>>> assert get_args(Callable[[], T][int]) == ([], int)
25512571
"""
25522572
if isinstance(tp, _AnnotatedAlias):
25532573
return (tp.__origin__,) + tp.__metadata__
@@ -3225,6 +3245,18 @@ def TypedDict(typename, fields=_sentinel, /, *, total=True):
32253245
associated with a value of a consistent type. This expectation
32263246
is not checked at runtime.
32273247
3248+
Usage::
3249+
3250+
>>> class Point2D(TypedDict):
3251+
... x: int
3252+
... y: int
3253+
... label: str
3254+
...
3255+
>>> a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK
3256+
>>> b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check
3257+
>>> Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
3258+
True
3259+
32283260
The type info can be accessed via the Point2D.__annotations__ dict, and
32293261
the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets.
32303262
TypedDict supports an additional equivalent form::
@@ -3680,44 +3712,43 @@ def decorator(cls_or_fn):
36803712
return cls_or_fn
36813713
return decorator
36823714

3683-
# TODO: RUSTPYTHON
3684-
3685-
# type _Func = Callable[..., Any]
3686-
3687-
3688-
# def override[F: _Func](method: F, /) -> F:
3689-
# """Indicate that a method is intended to override a method in a base class.
3690-
#
3691-
# Usage::
3692-
#
3693-
# class Base:
3694-
# def method(self) -> None:
3695-
# pass
3696-
#
3697-
# class Child(Base):
3698-
# @override
3699-
# def method(self) -> None:
3700-
# super().method()
3701-
#
3702-
# When this decorator is applied to a method, the type checker will
3703-
# validate that it overrides a method or attribute with the same name on a
3704-
# base class. This helps prevent bugs that may occur when a base class is
3705-
# changed without an equivalent change to a child class.
3706-
#
3707-
# There is no runtime checking of this property. The decorator attempts to
3708-
# set the ``__override__`` attribute to ``True`` on the decorated object to
3709-
# allow runtime introspection.
3710-
#
3711-
# See PEP 698 for details.
3712-
# """
3713-
# try:
3714-
# method.__override__ = True
3715-
# except (AttributeError, TypeError):
3716-
# # Skip the attribute silently if it is not writable.
3717-
# # AttributeError happens if the object has __slots__ or a
3718-
# # read-only property, TypeError if it's a builtin class.
3719-
# pass
3720-
# return method
3715+
3716+
type _Func = Callable[..., Any]
3717+
3718+
3719+
def override[F: _Func](method: F, /) -> F:
3720+
"""Indicate that a method is intended to override a method in a base class.
3721+
3722+
Usage::
3723+
3724+
class Base:
3725+
def method(self) -> None:
3726+
pass
3727+
3728+
class Child(Base):
3729+
@override
3730+
def method(self) -> None:
3731+
super().method()
3732+
3733+
When this decorator is applied to a method, the type checker will
3734+
validate that it overrides a method or attribute with the same name on a
3735+
base class. This helps prevent bugs that may occur when a base class is
3736+
changed without an equivalent change to a child class.
3737+
3738+
There is no runtime checking of this property. The decorator attempts to
3739+
set the ``__override__`` attribute to ``True`` on the decorated object to
3740+
allow runtime introspection.
3741+
3742+
See PEP 698 for details.
3743+
"""
3744+
try:
3745+
method.__override__ = True
3746+
except (AttributeError, TypeError):
3747+
# Skip the attribute silently if it is not writable.
3748+
# AttributeError happens if the object has __slots__ or a
3749+
# read-only property, TypeError if it's a builtin class.
3750+
pass
3751+
return method
37213752

37223753

37233754
def is_protocol(tp: type, /) -> bool:
@@ -3740,8 +3771,19 @@ def is_protocol(tp: type, /) -> bool:
37403771
and tp != Protocol
37413772
)
37423773

3774+
37433775
def get_protocol_members(tp: type, /) -> frozenset[str]:
37443776
"""Return the set of members defined in a Protocol.
3777+
3778+
Example::
3779+
3780+
>>> from typing import Protocol, get_protocol_members
3781+
>>> class P(Protocol):
3782+
... def a(self) -> str: ...
3783+
... b: int
3784+
>>> get_protocol_members(P) == frozenset({'a', 'b'})
3785+
True
3786+
37453787
Raise a TypeError for arguments that are not Protocols.
37463788
"""
37473789
if not is_protocol(tp):

0 commit comments

Comments
 (0)