Skip to content

type narrowing leads to "unreachable" code being actually reachable #12598

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

Open
Akuli opened this issue Apr 16, 2022 · 2 comments
Open

type narrowing leads to "unreachable" code being actually reachable #12598

Akuli opened this issue Apr 16, 2022 · 2 comments
Labels
bug mypy got something wrong topic-reachability Detecting unreachable code

Comments

@Akuli
Copy link
Contributor

Akuli commented Apr 16, 2022

Bug Report

To Reproduce

class Foo:
    def foo(self) -> None:
        print("Foo!!!")

class Bar:
    def __init__(self) -> None:
        self.foo: Foo | None = Foo()

    def get_rid_of_foo(self) -> None:
        self.foo = None


bar = Bar()
if bar.foo is not None:
    bar.get_rid_of_foo()
    assert bar.foo is None
    print(1 + "lol")

Expected Behavior

An error for the obviously wrong print(1 + "lol"). It fails there at runtime.

Actual Behavior

no errors!

Your Environment

mypy 0.942 with --python-version 3.10

@Akuli Akuli added the bug mypy got something wrong label Apr 16, 2022
@AlexWaygood AlexWaygood added the topic-reachability Detecting unreachable code label Apr 16, 2022
@beauxq
Copy link

beauxq commented Apr 29, 2022

This is a section of my test suite code (not even a made up example):

    assert not vm.paused
    press_key(pygame.K_SPACE)
    assert vm.paused
    press_key(pygame.K_SPACE, True)
    assert not vm.paused

mypy is reporting unreachable code on the 4th line
That is wrong. That code is reachable and it is executed when I run it.

It is assuming that press_key can't change vm.paused, which is a false assumption.

@beauxq
Copy link

beauxq commented Apr 29, 2022

re: the "topic-reachability" tag

I think this is more of a type-narrowing issue, rather than reachability.

To narrow types, you have to look at the scope of the name being narrowed (the narrowee), and the scopes of all of the functions called during the narrowed time.
As soon as a function is called that could possibly access the scope of the narrowee, the narrowing is gone.

If someone wants to make sure their type gets narrowed, they can make a local variable, and then only call functions that are defined outside of the local scope.

@Akuli Akuli changed the title if statements type narrowing leads to "unreachable" code being actually reachable type narrowing leads to "unreachable" code being actually reachable Apr 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-reachability Detecting unreachable code
Projects
None yet
Development

No branches or pull requests

3 participants