Hello everyone.
Imagine I define such function,
def f(
x: tuple[X, ...],
y: tuple[Y, ...],
z: tuple[Z, ...],
) -> tuple[tuple[tuple[T, ...], ...], ...]: ...
where f
applies some logic for every combination of elements from x
, y
and z
to return a T
element.
Now, I want to extend the API of f
by allowing, for each argument (e.g. x
), passing a single bare element – such as x: tuple[X, ...] | X
--, while the output will be squeezed accordingly to reflect this.
For example with X = Y = Z = T = int
, f(1, 2, 3)
would return a simple int
instead of a tuple[tuple[tuple[int, ...], ...], ...]
.
There are basically 8 possible signatures, that I can directly define with @overload
.
@overload
def f(x: X, y: Y, z: Z) -> T: ...
@overload
def f(x: tuple[X, ...], y: Y, z: Z) -> tuple[T, ...]: ...
# etc... 8 times
Is it possible to find a better way to “dynamically” emulate this overloading possibilities? Because in addition to be very ugly, it also becomes impractical very fast.
Thanks in advance!