-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Consider changing NoReturn to not be a bottom type #4116
Comments
I think it makes sense to keep it as is, but perhaps emit a warning if you assign eg |
Use case is practically every function. Assume that def div(a: float, b:float) -> float:
if b == 0:
raise ZeroDivisionError
else:
return a / b it should be: def div(a: float, b:float) -> Union[float, NoReturn]:
... And then this will propagate to all callers: def inv(x: float) -> float:
return div(1, x) # Incompatible return, expected 'float', got 'Union[float, NoReturn]' And if you take into account that practically every built-in and stdlib function can raise an exception for various reasons (index out of range, value less than zero, etc.), this means that every user function should be typed as returning @ethanhs I am OK with emitting a warning but it is not as simple to implement as it may seem, there are lots of cases to consider, unpacking |
Hm. We're using |
@ilevkivskyi this is true, I did not mean to make it seem like the changes for that are simple. I'm not particularly tied to it either, just something that might be useful. I think we are agreed that NoReturn should remain as-is, so I am going to close this. |
OK, that makes sense. Looking at other type systems that have a divergent type (e.g. Rust), they do exhibit the same behaviour of treating NoReturn as a bottom type. I wasn't advocating for a checked exception system. Is it worth opening an issue for assigning a value from a |
I think you can open an issue (at least to keep this idea on record), but it would be quite low priority. |
Opened #4179. |
Probably the type algebra does need a bottom type, but I'm not convinced that Let's consider the following code: from typing import NoReturn
def f() -> NoReturn:
while True:
pass
x = f() * 2 Because This example also shows that any use of the return value of Now let's introduce two new types: def f() -> Union[NoValue, Bottom]: And mypy would report:
Rename So I think it makes sense to make |
NoReturn
being a bottom type leads to mypy accepting code that I would consider to be invalid.For example, saving the result of a
NoReturn
function to a variable:If mypy infers a type of
NoReturn
on my function body, it seems that I can write anything as the return type without getting a type error:I'm struggling to think of any example where
NoReturn
being a bottom type allows me to do things that I couldn't otherwise do.What's the rationale? Would you be open to changing this?
Originally discussed in #4066.
The text was updated successfully, but these errors were encountered: