-
Notifications
You must be signed in to change notification settings - Fork 266
Description
It would be useful to be able to apply type transformations to TypeVarTuple
's types. Some motivating examples:
Ts = TypeVarTuple('Ts')
class Example(Generic[*Ts]):
def __init__(self, *types: *type[Ts]) -> None:
self.types = types
def create_defaults(self) -> tuple[*Ts]:
return tuple(t() for t in self.types)
def create_lists(self) -> tuple[*list[Ts]]:
return tuple([t()] for t in self.types)
def create_callables(self) -> tuple[*Callable[[], Ts]]:
return tuple(lambda: t() for t in self.types)
e = Example(int, str)
assert_type(e.create_defaults(), tuple[int, str])
assert_type(e.create_lists(), tuple[list[int], list[str]])
assert_type(e.create_callables(), tuple[Callable[[], int], Callable[[], str]])
At a high level, everything between the *
and the TypeVarTuple
it expands would be applied per type in the tuple before it's unpacked.
There are some decisions to be made about how the expansion is done if there are multiple TypeVarTuple
s in the expand expression, but I think it can be supported and I think the intuitive thing would be to zip up all the TypeVarTuple
s. For example,
tuple[*tuple[Ts, Us]]
with Ts = (int, str)
and Us = (float, bytes)
would be tuple[tuple[int, float], tuple[str, bytes]]
, with the implementation enforcing equal-length TypeVarTuple
s.
If there's a workaround for this using the existing logic, let me know. My current use case involves keeping a reference to the runtime types, so *type[Ts]
is what I'm looking for at the moment.