Closed
Description
i am working on annotation for a 3rd package. For simplicity let's say we have a function like this one:
def foo(x=0, f=None):
return f(x) if f else x + 1
I would like to express, that the return type of the function is
int
iff
is missing.- The same as
f
return type otherwise.
So conceptually I would like to see something like this:
from typing import Callable, TypeVar, overload
T = TypeVar("T")
@overload
def foo(x: int = ..., f: Callable[[int], T]) -> T: ...
@overload
def foo(x: int = ...) -> int: ...
Of course, it is not valid, as non-default argument follows default argument. Similarly (as imprecise as it would be) we cannot use the following
from typing import Callable, TypeVar
from typing import overload
T = TypeVar("T")
@overload
def foo(x: int = ..., f: Callable[[int], T] = ...) -> T: ...
@overload
def foo(x: int = ...) -> int: ...
because the optional argument, makes the first signature broader than the second one.
A workaround is to split the first signature into two separate cases:
from typing import Callable, TypeVar
from typing import overload
T = TypeVar("T")
@overload
def foo(x: int, f: Callable[[int], T] = ...) -> T: ...
@overload
def foo(f: Callable[[int], T] = ...) -> T: ...
@overload
def foo(x: int = ...) -> int: ...
but it doesn't scale when the number of preceding optional arguments grows:
def bar(x=0, y=0, z=0, f=None):
return f(x + y + z) if f else x + y + z + 1
Is there any other solution here?