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