-
Notifications
You must be signed in to change notification settings - Fork 84
calls to functions returning Never
/NoReturn
are terminal
#180
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
Never
/NoReturn
Never
/NoReturn
Hi David, I would like to work on this. Would this be an OK first issue to pick up? |
You are certainly welcome to try! However, I do not think that this is a particularly beginner friendly task. We might have some issues labeled with "help wanted" that might be more suitable for a first contribution. |
Got it. I will try to find another issue, or another minor task in this area (I do see some TODOs in the tests, for example). However, one thing is not clear to me. You mention in the issue description that replacing However, the following also does not give any error: def f() -> int:
while True:
pass (Notice that I changed the return value to Here, if the " Moreover, the following gives an error: # "Object of type `Literal["foo"]` is not assignable to return type `int`"
def f() -> int:
while True:
pass
return "foo" ... which makes me wonder if Edit: looking at astral-sh/ruff#15676, which introduced the unreachability-detection, I don't see a " |
Never
/NoReturn
Never
/NoReturn
are terminal
Because there are no reachable However, in this case, the correct thing to do would be to enforce that the function's annotated return type is |
@abhijeetbodas2001 Sorry for responding so late, I must have missed the notification about your original message while I was out on vacation.
I don't think so. A function annotated with
Yes, we don't silence all errors in unreachable code. And in this case, it's arguable if that would be an improvement. If the loop were not endless, that return statement would be wrong. So flagging it does not seem like unwanted behavior to me. |
Ah! I missed this. That makes sense then. Thanks! |
Never
/NoReturn
are terminalNever
/NoReturn
are terminal
Currently NoReturn cannot be used to narrow a type. Which is a relatively common pattern in for example Flask examples. Where abort() can be used to return an error code early. This can be used to make sure that the request contains valid data. For reference here is another example that currently doesnt work. from typing import NoReturn, reveal_type
def raise_error() -> NoReturn:
raise Exception('test')
def test(x: str | None) -> None:
if x is None:
raise_error()
reveal_type(x)
# Should be "str" is "str | None" |
Same issue, different symptoms. I have this simplified example that's causing from PySide6 import QtGui
from PySide6.QtWidgets import QMainWindow
class MainWindow(QMainWindow):
def closeEvent(self, event: QtGui.QCloseEvent | None = None):
"""Exit safely when closing the window."""
if event is None or False: # `or False` is actually some other condition, simplified for this example
sys.exit(1) # Here ty should see that `event` can't be `None` if this branch wasn't taken
# ... some more checks and user prompts happened here
# Fallthrough case: Prevent program from closing.
event.ignore() |
Also for Funcs in def restartLow() -> typing.NoReturn:
"""Will not return from the function."""
os.execl(
sys.executable,
sys.executable,
*sys.argv,
) def execl(file, *args):
"""execl(file, *args)
Execute the executable file with argument list args, replacing the
current process. """
execv(file, args) |
Uh oh!
There was an error while loading. Please reload this page.
Summary
The following code emits a
invalid-return-type
diagnostic, but shouldn't:sys.exit
is annotated with returningNoReturn
, but the problem is that we don't have an explicitreturn
statement here.This is related to unreachable code analysis. We already have some special handling for detecting whether or not the end of scope is reachable (i.e. replacing
sys.exit(1)
withwhile True: pass
works fine), but this does not take calls to functions returningNever
/NoReturn
into account.The text was updated successfully, but these errors were encountered: