-
I'm trying to recreate a drop-in replacement of import typing as tp
FirstT = tp.TypeVar("FirstT")
CallableT = tp.TypeVar("CallableT", bound=tp.Callable[..., tp.Any])
P = tp.ParamSpec("P")
R = tp.TypeVar("R")
S = tp.TypeVar("S")
class nothing: ...
class MethodType_(tp.Generic[CallableT, FirstT, P, R]):
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: ...
# Actually `types.MemberDescriptorType`s
__self__: FirstT
__func__: CallableT
class FunctionType_(tp.Generic[FirstT, P, R]):
def __call__(self, __first: FirstT, *args: P.args, **kwargs: P.kwargs) -> R: ...
@tp.overload
def __get__(self, __instance: None, __type: type) -> FunctionType_[FirstT, P, R]: ...
@tp.overload
def __get__(self: CallableT, __instance: S, __type: type[S]) -> MethodType_[CallableT, S, P, R]: ...
@tp.overload
def function_(callable_: tp.Callable[tp.Concatenate[FirstT, P], R], /) -> FunctionType_[FirstT, P, R]: ...
@tp.overload
def function_(callable_: tp.Callable[P, R], /) -> FunctionType_[nothing, P, R]: ... @function_
def my_func(a: int, b: str) -> None: pass
class C:
@function_
def my_method(self, a: int, b: str) -> None: pass
>>> my_func(8, b="") # OK
>>> my_func(a=8, b="") # Bad - `a` is positional-only
>>> C().my_method(a=8, b="") # OK
>>> C.my_method(C(), a=8, b="") # OK
>>> C.my_method(self=C(), a=8, b="") # Bad - `self` is positional-only I have three related questions:
I know that you can instead implement the behaviour separately in two different decorators, e.g. pure function behaviour in |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Does this meet your needs? from typing import Callable, Generic, ParamSpec, Protocol, TypeVar, overload
SelfT = TypeVar("SelfT", contravariant=True)
P = ParamSpec("P")
R = TypeVar("R", covariant=True)
S = TypeVar("S")
class MethodProto(Protocol[SelfT, P, R]):
def __call__(_self, self: SelfT, *args: P.args, **kwargs: P.kwargs) -> R:
...
class MethodType_(Generic[SelfT, P, R]):
__self__: SelfT
__func__: Callable[P, R]
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: ...
@overload
def __get__(self, __instance: None, __type: type) -> "MethodProto[SelfT, P, R]": ...
@overload
def __get__(self: Callable[P, R], __instance: S, __type: type[S]) -> "Callable[P, R]": ...
class FunctionType_(Generic[P, R]):
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: ...
@overload
def function_(callable_: MethodProto[SelfT, P, R]) -> MethodType_[SelfT, P, R]: ...
@overload
def function_(callable_: Callable[P, R], /) -> FunctionType_[P, R]: ... |
Beta Was this translation helpful? Give feedback.
Does this meet your needs?