Dan Gittik
Dan Gittik

Reputation: 3850

Map Logic with TypeVarTuple

I have a rather simple function that accepts a sequence of classes and returns a tuple of their respective instances:

def f(*classes):
    return tuple(cls() for cls in classes)

Is there any way to annotate it so that mypy (and more importantly, Intellisense) understands this relation? For example:

a, b, c = f(A, B, C)
# reveal_type(a) is A
# reveal_type(b) is B
# reveal_type(c) is C

I feel like TypeVarTuple is a step in the right direction, but I'm struggling to inject the type[] logic that would make it work. As in:

def f[*Ts](
    *classes: type[*Ts] # this; as in, tuple[type[T] for T in Ts]
) -> tuple[*Ts]:
    return tuple(cls() for cls in classes)

The type[*Ts] bit doesn't work (Unpack is only valid in a variadic position), and I can't seem to figure out how (or whether it's even possible) to express my typing logic properly in this case.

Edit

So far, the only solution I could come up with is something along the lines of:

@overload
def f[T1](cls1: type[T1]) -> tuple[T1]: ...

@overload
def f[T1, T2](cls1: type[T1], cls2: type[T2]) -> tuple[T1, T2]: ...

@overload
def f[T1, T2, T3](cls1: type[T1], cls2: type[T2], cls3: type[T3]) -> tuple[T1, T2, T3]: ...

# 10 suchoverloads, assuming nobody is going to call the function with 11 classes or more...

But it's... you know. Posting it for reference, in case others are struggling with something similar and no better solution crops up.

Upvotes: 2

Views: 34

Answers (0)

Related Questions