Skip to content
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

mypy fails to recognize functions as generators when sys.platform is used in conditions #5678

Open
marcinsulikowski opened this issue Sep 26, 2018 · 2 comments
Labels
bug mypy got something wrong priority-1-normal topic-runtime-semantics mypy doesn't model runtime semantics correctly

Comments

@marcinsulikowski
Copy link

mypy seems to be too thorough when interpreting if sys.platform == ... conditions. Consider the following file:

import sys
from typing import Generator

def f() -> Generator[int, None, None]:
    if sys.platform == "darwin":
        yield 1

I'm trying to run mypy for this file on Linux using mypy gen.py

Expected behavior:
mypy test passes for this file on Linux

Actual behavior:
I get this on Linux:

$ mypy gen.py 
gen.py:4: error: Missing return statement

At the same time, mypy on macOS does not complain. I think that this is related to #698

Platform information:

$ uname -sr; mypy --version; python --version
Linux 4.15.0-34-generic
mypy 0.630
Python 2.7.15rc1
@marcinsulikowski marcinsulikowski changed the title mypy fails to recognize functions as generators when sys.platform condions are used mypy fails to recognize functions as generators when sys.platform is used in conditions Sep 26, 2018
@gvanrossum gvanrossum added the bug mypy got something wrong label Sep 26, 2018
@gvanrossum
Copy link
Member

Agreed. It looks like the analysis that determines whether a function body contains any yields runs after the version/platform-based dead code elimination; it ought to run before that. Are you interested in trying to fix this?

@marcinsulikowski
Copy link
Author

I could try although I'm not familiar with this codebase so I cannot guarantee anything.

After quick look into the source code, it seems to me that the following:

    def visit_block(self, b: Block) -> None:
        if b.is_unreachable:
            return
        self.block_depth[-1] += 1
        for s in b.body:
            self.accept(s)
        self.block_depth[-1] -= 1

in class SemanticAnalyzerPass2 probably needs some change in the if b.is_unreachable: case – unreachable blocks within a function scope may require a quick scan to look for yields instead of being skipped altogether.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong priority-1-normal topic-runtime-semantics mypy doesn't model runtime semantics correctly
Projects
None yet
Development

No branches or pull requests

4 participants