I often see people use Never
or NoReturn
as a return type combined with overloading to express calling a function that way is not valid.
But isn’t that kind of abusing the feature for something it is not made for?
Never
(and NoReturn
) just indicate that something will never return (bottom type). This is all they tell us. We cannot judge whether calling a function with a Never
return is expected or supposed to be treated as an error, that should be outside of the scope of their usage.
That’s why I want to propose the Wrong
special form.
When the type checker gets Wrong
as an expression result, it errors.
Examples
Currently this errors in the line if a
for pyright, but not for mypy.
from typing import Never
class A:
def __bool__(self) -> Never:
raise RuntimeError
a = A()
if a:
print("I will never be reached")
I think mypy is correct in this case and pyright just specialized erroring in moments like this, because Never
is often ‘misused’ this way.
Who says I do not purposefully want to never return from this function?
Look at the following example:
from typing import Literal, Never
class A():
def __bool__(self) -> Literal[True]:
return True
class B():
def __bool__(self) -> Never:
raise RuntimeError
def get() -> A | B:
...
a_or_b = get()
if a_or_b:
print("I might be reached")
Pyright still errors here, even though I have practical reasons why I would do this and there is no technical reason this should be wrong.
If we add a Wrong
type, Never
can stay true to its real use case of just showing something does have no possible value, while Wrong
explicitly tells us that we indeed did something wrong.
Edit: Change typo Specia
to Special
, remove unused imports in coding examples