-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
"Missing return statement" error for functions having infinite loop unconditionally by looping on non-exhaustive generator #7374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The type system does not know whether a generator is finite (or exhaustive as you call it), so there's no way for mypy to know this. We could add a new type system feature, like an "infinite iterator" type, but I'm not sure that's worth the hassle. I would recommend putting something like |
Yes. The mitigation is what I'm currently doing. But, I think that for built-in infinite generators, at least white-listing is a possibility? |
This is actually a duplicate of #5992 that was closed as wont fix. So I would propose to close this as well, unless you want to provide a working patch. |
@ilevkivskyi I actually saw that issue when I was creating this. However, I didn't see this as a duplicate because that issue mentioned creating new types for infinite generator while this describes false-positive for the no return statement rule. But, #5992 indeed partially covers this issue. What do you think? |
It if fine to keep this open, but it I don't think it is high priority. PRs are welcome however. |
I am not familiar with mypy codebase and, unfortunately, my schedule doesn't allow me to master this codebase and do this... But, thanks for keeping this issue. How should we do about #7373 ? |
Honestly, I would just close that PR for now. Then later we can re-open it after this issue is fixed. |
Reading the typing module docs, I want to believe that infinite generators could be annotated as Is that a stupid idea? Or just stupid enough to work? 😄 |
@sbrudenell Why don't you try it and report back here? |
from typing import Generator
from typing import NoReturn
def inf() -> Generator[None, None, NoReturn]:
while True:
yield
def consume_inf() -> int:
for _ in inf():
return 0
def consume_while_true() -> int:
while True:
return 0 $ mypy --version
mypy 0.790
$ mypy test.py
test.py:8: error: Missing return statement
Found 1 error in 1 file (checked 1 source file) I'd expect (In real usage, my I'm trying to work out whether Pro:
Con:
I can't quite work out how to change mypy to implement this for further testing. I guess there ought to be some change around |
Adding to the Cons:
|
I would also like to add that while mypy correctly narrows the type of from typing import Generator, NoReturn, Union
def stop() -> NoReturn:
raise AssertionError("should not call me")
def raise_on_str(x: Union[str, int]) -> int:
if isinstance(x, str):
stop()
return x # mypy understands that x can only contain a value of type `int` by this point it fails to do the same when working with generators like this: from typing import Generator, NoReturn, Union
def inf() -> Generator[str, None, NoReturn]:
while True:
yield "xyz"
def generate(x: Union[str, int]) -> Generator[str, None, int]:
if isinstance(x, str):
yield from inf() # `yield from` will never return, because the generator never returns
return x # error: Incompatible return value type (got "Union[str, int]", expected "int") I am not familiar with mypy internals enough to know to what degree these cases are similar, but I feel like the usage pattern is the same and seems relevant to this issue. |
When having functions having infinite loop unconditionally by looping on non-exhaustive generator, there should be no
return
statements after the infinite looping block since all statements after the looping block are unreachable. Therefore, this "Missing return statement" error is a false-positive. The test case exposing this false-positive is implemented in #7373 .Thanks
The text was updated successfully, but these errors were encountered: