Protection against using Result with `if`
Hello, i'm doing some refactoring of my app, and wanted to use result.
Old code uses if some_func(): ... constructions, and now they're returning Result(), and this should not be treated as error in type checker.
After some testing, i found this:
from typing import NoReturn
class NoIf:
def __bool__(self) -> NoReturn:
raise RuntimeError()
if NoIf():
pass
This results in error in pyright (but not in mypy)
/tmp/test.py:6:4 - error: Invalid conditional operand of type "NoIf"
Method __bool__ for type "NoIf" returns type "NoReturn" rather than "bool" (reportGeneralTypeIssues)
Should i make a PR adding this __bool__ override, if you think this can be useful for everyone?
That's very cool, didn't know that could be done.
I have two concerns however,
- I'm not sure how many people would benefit from this if this only works with pyright. Many projects use mypy and other editors that may not support pyright (eg PyCharm).
- More so, the issue is we'd be introducing new runtime behavior and break existing code by making this change. We'd want to do this in a non-intrusive and opt-in way. Unfortunately there's no easy way to do this that works both at runtime and at type checker level -- the only solution I can think of is to make a new module,
from result.strict import Ok, Err(src/result/strict.py), where we expose a newOkandErrclasses with extend and override the__bool__.
I'm not sure if it makes sense to do this just yet. But definitely something we can look into in the future if something changes.
Yeah, you're right. Moving this into strict submodule is good idea.
In the meantime, i just added this temporarily to my local copy, to catch existing issues and it worked great.
Feel free to close this issue, or leave it open until "something changes" :)
You could guard the behavior of returning NoReturn through an if TYPE_CHECKING condition. This way runtime behavior wouldn't change, but users would see an error in their editor. (and potentially the CI pipeline or wherever else the type checker is run)