I have two functions like this. How would I type hint func()
such that mypy does not raise an error?
Right now it says
test.py:14: error: Argument 1 to "len" has incompatible type "str | None"; expected "Sized" [arg-type]
from typing import Optional
path = "path"
def func(path: str) -> Optional[str]:
s = "foo"
if True:
return s
return None
def func2() -> None:
if func(path) is not None:
if len(func(path)) > 0:
print("Yes")
else:
print("No")
I tried Optional[str]
and Union
but neither seems to work.
mypy can't know that both invocations of func
will yield the same result. It therefor can't know that if func(path) is not None
the first time, the second time func(path)
is called in len(func(path))
the return value being None
is not possible. mypy is correct in this conservative assumption.
You can bind the return value to a variable, which allows mypy to reason about the possible types of that variable across the type-narrowing if
.
def func2() -> None:
foo = func(path)
# `foo` can only be `None` or a `str`; but `foo` in `len(foo)` can't be None.
if foo is not None and len(foo) > 0:
print("Yes")
return
print("No")
As a side-note: The expression foo is not None and len(foo) > 0
can be shortened to just foo
. Both None
and the empty string evaluate false-ish.