I have a problem with my TypeVar definition.
My function requires a tuple of tuples as a parameter. The main tuple can have as many as tuples as components but they don't have to share the same type between them.
But the component of the tuple inside the main tuple have to share the same type.
Here a simplified example of code:
The following code work in python but I have a warning in Pycharm
form((("prompt", str, "default"),
("prompt", int, 10),
("prompt", str, "default"),
("prompt", float, .5)))

I defined my function like that:
ValueType = TypeVar('ValueType', str, int, float, bool)
InputDefinitionType = Tuple[str, Type[ValueType], ValueType]
def form(input_def: Tuple[InputDefinitionType, ...])
...
How can I 'reset' the TypeVar group to only match the types inside the tuple contained inside the main tuple but not across the main tuple itself?
tl;dr: The way you're implementing it is wrong, but there's a workaround at the bottom of this answer.
Unfortunately, your code does not type-check. A constrained type variable must refer to the same type within a given "scope" (PEP 484 has some definitions on scope but it's not too precise).
In your case, ValueType must refer to a single type within the form function, so your call is not valid.
As to why the code seems to type-check in mypy, it's because InputDefinitionType is a generic type alias, but you're using it without parameterization, which is then equivalent to parameterizing with Any. Put simply:
def form(input_def: Tuple[InputDefinitionType, ...]) -> None: ...
is equivalent to
def form(input_def: Tuple[InputDefinitionType[Any], ...]) -> None: ...
You can see this in mypy-play, where the final reveal_type(form) shows the inferred type of the function to be:
main.py:15: note: Revealed type is "def (input_def: builtins.tuple[Tuple[builtins.str, Type[Any], Any]])"
A workaround for this is to turn it into a Union type:
ValueType = TypeVar('ValueType')
InputDef = Tuple[str, Type[ValueType], ValueType] # name shortened for conciseness
InputDefConcrete = Union[
InputDef[float], InputDef[str], InputDef[bool], InputDef[int]
]
def form(input_def: Tuple[InputDefConcrete, ...]) -> None: ...
See it in action on mypy-play.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With