I want to write a pipeline function which takes an abritrary number of functions and forwards the input of the first to the second and so on up until the last. The output of pipeline is a Callable. The input of that Callable matches the first function given to pipeline. The output matches the last function given to pipeline. I would like to add type annotations to pipeline. This is what I came up with so far:
from typing import TypeVar
from typing_extensions import ParamSpec, Concatenate
P = ParamSpec("P")
Output = TypeVar("Output")
def pipeline(func: Callable[Concatenate[P], T], *funcs: Callable[..., Output]) -> Callable[Concatenate[P], Output]:
...
But this gives a Union of all Output types of *funcs. Example:
def double(x: int) -> Tuple[int, int]:
return x, x*2
def add(x: int, y: int) -> int:
return x + y
def to_string(x: int) -> str:
return str(x)
new_func = pipeline(add, double, add, to_string)
With the type annotation shown above the type / signature of new_func results in
new_func: (x: int, y: int) -> (Tuple[int, int] | int | str)
It's quite clear that pipeline should have the following signature:
new_func: (x: int, y: int) -> str
Is there a way to achieve this with type annotations?
from How to infer the type of last element passed to `*args` parameter in python?
No comments:
Post a Comment