-
from collections.abc import Callable
from typing import Any, overload
def signature_from[**P, T](_original: Callable[P, T]) -> Callable[[Callable[P, T]], Callable[P, T]]:
"""Copies the signature of a function to another function."""
def decorator(func: Callable[P, T]) -> Callable[P, T]:
return func
return decorator
@overload
def f(x: int) -> int: ...
@overload
def f(x: str) -> str: ...
@overload
def f(x: Any) -> Any: ...
def f(x: Any) -> Any:
return x
# Expected
y1 = f(1) # int
y2 = f("1") # str
y3 = f(1.0) # Any
@signature_from(f)
def g(*args, **kwargs) -> Any:
if (len(args) + len(kwargs)) != 1:
raise ValueError
x = args[0] if len(args) == 1 else kwargs["x"]
return f(x)
# y5, y6 unexpected
y4 = g(1) # int
y5 = g("1")
# ^^^
#Argument of type "Literal['1']" cannot be assigned to parameter "x" of type "int"
# "Literal['1']" is not assignable to "int" (reportArgumentType)
y6 = g(1.0)
# ^^^
#Argument of type "float" cannot be assigned to parameter "x" of type "int"
# "float" is not assignable to "int" (reportArgumentType) |
Beta Was this translation helpful? Give feedback.
Answered by
Glinte
Jul 20, 2025
Replies: 1 comment
-
|
This works though from collections.abc import Callable
from typing import Any, overload
def signature_from[F: Callable](_original: F) -> Callable[[F], F]:
"""Copies the signature of a function to another function."""
def decorator(func: F) -> F:
return func
return decorator
@overload
def f(x: int) -> int: ...
@overload
def f(x: str) -> str: ...
@overload
def f(x: Any) -> Any: ...
def f(x: Any) -> Any:
return x
# Expected
y1 = f(1) # int
y2 = f("1") # str
y3 = f(1.0) # Any
@signature_from(f)
def g(*args, **kwargs) -> Any:
if (len(args) + len(kwargs)) != 1:
raise ValueError
x = args[0] if len(args) == 1 else kwargs["x"]
return f(x)
y4 = g(1) # int
y5 = g("1") # str
y6 = g(1.0) # Any |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
Glinte
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This works though