Problem description
Suppose a following test
class Foo:
def __init__(self):
self.value: int | None = None
def set_value(self, value: int | None):
self.value = value
def test_foo():
foo = Foo()
assert foo.value is None
foo.set_value(1)
assert isinstance(foo.value, int)
assert foo.value == 1 # unreachable
The test:
- First, checks that
foo.valueis something - Then, sets the value using a method.
- Then it checks that the
foo.valuehas changed.
When running the test with mypy version 1.9.0 (latest at the time of writing), and having warn_unreachable set to True, one gets:
(venv) niko@niko-ubuntu-home:~/code/myproj$ python -m mypy tests/test_foo.py
tests/test_foo.py:16: error: Statement is unreachable [unreachable]
Found 1 error in 1 file (checked 1 source file)
What I have found
- There is an open issue in the mypy GitHub: https://github.com/python/mypy/issues/11969 One comment said to use safe-assert, but after rewriting the test as
from safe_assert import safe_assert
def test_foo():
foo = Foo()
safe_assert(foo.value is None)
foo.set_value(1)
safe_assert(isinstance(foo.value, int))
assert foo.value == 1
the problem persists (safe-assert 0.4.0)[1]. This time, both mypy and VS Code Pylance think that foo.set_value(1) two lines above is not reachable.
Question
How can I say to mypy that the foo.value has changed to int and that it should continue checking also everything under the assert isinstance(foo.value, int) line?
[1] UPDATE: The safe_assert v. 0.5.0 has fixed the issue