@@ -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
37233754def is_protocol (tp : type , / ) -> bool :
@@ -3740,8 +3771,19 @@ def is_protocol(tp: type, /) -> bool:
37403771 and tp != Protocol
37413772 )
37423773
3774+
37433775def 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