@@ -220,6 +220,8 @@ def _should_unflatten_callable_args(typ, args):
220
220
>>> P = ParamSpec('P')
221
221
>>> collections.abc.Callable[[int, int], str].__args__ == (int, int, str)
222
222
True
223
+ >>> collections.abc.Callable[P, str].__args__ == (P, str)
224
+ True
223
225
224
226
As a result, if we need to reconstruct the Callable from its __args__,
225
227
we need to unflatten it.
@@ -263,6 +265,8 @@ def _collect_type_parameters(args, *, enforce_default_ordering: bool = True):
263
265
264
266
>>> P = ParamSpec('P')
265
267
>>> T = TypeVar('T')
268
+ >>> _collect_type_parameters((T, Callable[P, T]))
269
+ (~T, ~P)
266
270
"""
267
271
# required type parameter cannot appear after parameter with default
268
272
default_encountered = False
@@ -1983,7 +1987,8 @@ def _allow_reckless_class_checks(depth=2):
1983
1987
The abc and functools modules indiscriminately call isinstance() and
1984
1988
issubclass() on the whole MRO of a user class, which may contain protocols.
1985
1989
"""
1986
- return _caller (depth ) in {'abc' , 'functools' , None }
1990
+ # XXX: RUSTPYTHON; https://github.com/python/cpython/pull/136115
1991
+ return _caller (depth ) in {'abc' , '_py_abc' , 'functools' , None }
1987
1992
1988
1993
1989
1994
_PROTO_ALLOWLIST = {
@@ -2090,11 +2095,11 @@ def __subclasscheck__(cls, other):
2090
2095
and cls .__dict__ .get ("__subclasshook__" ) is _proto_hook
2091
2096
):
2092
2097
_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
- # )
2098
+ non_method_attrs = sorted (cls .__non_callable_proto_members__ )
2099
+ raise TypeError (
2100
+ "Protocols with non-method members don't support issubclass()."
2101
+ f" Non-method members: { str (non_method_attrs )[1 :- 1 ]} ."
2102
+ )
2098
2103
return _abc_subclasscheck (cls , other )
2099
2104
2100
2105
def __instancecheck__ (cls , instance ):
@@ -2526,6 +2531,18 @@ def get_origin(tp):
2526
2531
2527
2532
This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar,
2528
2533
Annotated, and others. Return None for unsupported types.
2534
+
2535
+ Examples::
2536
+
2537
+ >>> P = ParamSpec('P')
2538
+ >>> assert get_origin(Literal[42]) is Literal
2539
+ >>> assert get_origin(int) is None
2540
+ >>> assert get_origin(ClassVar[int]) is ClassVar
2541
+ >>> assert get_origin(Generic) is Generic
2542
+ >>> assert get_origin(Generic[T]) is Generic
2543
+ >>> assert get_origin(Union[T, int]) is Union
2544
+ >>> assert get_origin(List[Tuple[T, T]][int]) is list
2545
+ >>> assert get_origin(P.args) is P
2529
2546
"""
2530
2547
if isinstance (tp , _AnnotatedAlias ):
2531
2548
return Annotated
@@ -2548,6 +2565,10 @@ def get_args(tp):
2548
2565
2549
2566
>>> T = TypeVar('T')
2550
2567
>>> assert get_args(Dict[str, int]) == (str, int)
2568
+ >>> assert get_args(int) == ()
2569
+ >>> assert get_args(Union[int, Union[T, int], str][int]) == (int, str)
2570
+ >>> assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
2571
+ >>> assert get_args(Callable[[], T][int]) == ([], int)
2551
2572
"""
2552
2573
if isinstance (tp , _AnnotatedAlias ):
2553
2574
return (tp .__origin__ ,) + tp .__metadata__
@@ -3225,6 +3246,18 @@ def TypedDict(typename, fields=_sentinel, /, *, total=True):
3225
3246
associated with a value of a consistent type. This expectation
3226
3247
is not checked at runtime.
3227
3248
3249
+ Usage::
3250
+
3251
+ >>> class Point2D(TypedDict):
3252
+ ... x: int
3253
+ ... y: int
3254
+ ... label: str
3255
+ ...
3256
+ >>> a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK
3257
+ >>> b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check
3258
+ >>> Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
3259
+ True
3260
+
3228
3261
The type info can be accessed via the Point2D.__annotations__ dict, and
3229
3262
the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets.
3230
3263
TypedDict supports an additional equivalent form::
@@ -3680,44 +3713,43 @@ def decorator(cls_or_fn):
3680
3713
return cls_or_fn
3681
3714
return decorator
3682
3715
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
3716
+
3717
+ type _Func = Callable [..., Any ]
3718
+
3719
+
3720
+ def override [F : _Func ](method : F , / ) -> F :
3721
+ """Indicate that a method is intended to override a method in a base class.
3722
+
3723
+ Usage::
3724
+
3725
+ class Base:
3726
+ def method(self) -> None:
3727
+ pass
3728
+
3729
+ class Child(Base):
3730
+ @override
3731
+ def method(self) -> None:
3732
+ super().method()
3733
+
3734
+ When this decorator is applied to a method, the type checker will
3735
+ validate that it overrides a method or attribute with the same name on a
3736
+ base class. This helps prevent bugs that may occur when a base class is
3737
+ changed without an equivalent change to a child class.
3738
+
3739
+ There is no runtime checking of this property. The decorator attempts to
3740
+ set the ``__override__`` attribute to ``True`` on the decorated object to
3741
+ allow runtime introspection.
3742
+
3743
+ See PEP 698 for details.
3744
+ """
3745
+ try :
3746
+ method .__override__ = True
3747
+ except (AttributeError , TypeError ):
3748
+ # Skip the attribute silently if it is not writable.
3749
+ # AttributeError happens if the object has __slots__ or a
3750
+ # read-only property, TypeError if it's a builtin class.
3751
+ pass
3752
+ return method
3721
3753
3722
3754
3723
3755
def is_protocol (tp : type , / ) -> bool :
@@ -3740,8 +3772,19 @@ def is_protocol(tp: type, /) -> bool:
3740
3772
and tp != Protocol
3741
3773
)
3742
3774
3775
+
3743
3776
def get_protocol_members (tp : type , / ) -> frozenset [str ]:
3744
3777
"""Return the set of members defined in a Protocol.
3778
+
3779
+ Example::
3780
+
3781
+ >>> from typing import Protocol, get_protocol_members
3782
+ >>> class P(Protocol):
3783
+ ... def a(self) -> str: ...
3784
+ ... b: int
3785
+ >>> get_protocol_members(P) == frozenset({'a', 'b'})
3786
+ True
3787
+
3745
3788
Raise a TypeError for arguments that are not Protocols.
3746
3789
"""
3747
3790
if not is_protocol (tp ):
0 commit comments