Say that I have
def foo(x: Union[str, list[str]], y: Union[str, list[str]]) -> tuple[list[str], list[str]]:
x = cast(Union[list[str], tuple[list[str], ...]], str2list(x))
y = cast(Union[list[str], tuple[list[str], ...]], str2list(y))
return x,y
def str2list(*args: Union[str, list[str]]) -> Union[list[str], tuple[list[str], ...]]:
vals = []
for x in args:
if not isinstance(x, list):
x = [x]
vals.append(x)
if len(args) == 1:
return vals[0]
else:
return tuple(vals)
x = 'My name is x'
y = ['First element', 'Second element']
z = str2list(x,y)
As you see, there are two cast calls in foo, but still mypy complains that
error: Incompatible types in assignment (expression has type "Union[List[str], Tuple[List[str], ...]]", variable has type "Union[str, List[str]]") [assignment]
A workaround could be to define new variables and adjust the return type of foo as it follows
def foo(
x: Union[str, list[str]], y: Union[str, list[str]]
) -> tuple[
Union[list[str], tuple[list[str], ...]],
Union[list[str], tuple[list[str], ...]],
]:
xl = cast(Union[list[str], tuple[list[str], ...]], str2list(x))
yl = cast(Union[list[str], tuple[list[str], ...]], str2list(y))
return xl, yl
But I would prefer to overwrite x and y rather than defining two new variables xl and yl.
Here's a structured, augmented summary of the points made in the comments:
Mypy is a static type-checker, and redefining a variable with a value outside it's original type is a dynamic type operation, so mypy will complain about this.
def foo_1(
x: Union[str, list[str]], y: Union[str, list[str]]
) -> tuple[list[str], list[str]]:
cast_x = cast(Union[list[str], tuple[list[str], ...]], str2list(x))
cast_y = cast(Union[list[str], tuple[list[str], ...]], str2list(y))
return cast_x, cast_y
def foo_2(
x: Union[str, list[str]], y: Union[str, list[str]]
) -> tuple[list[str], list[str]]:
return cast(Union[list[str], tuple[list[str], ...]], str2list(x)), cast(
Union[list[str], tuple[list[str], ...]], str2list(y)
)
Instead of bending to mypy's requirements, one can simply silence this specific type of [assignment] warning by running mypy with the --allow-redefinition flag. If you don't want to type this flag into the command line every time you run mypy, you can instead add the line allow_redefinition = True to your mypy configuration file.
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