Skip to content

When a has type Any, after assert a is None, the rest of the block is considered dead code #2970

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

Closed
benkuhn opened this issue Mar 6, 2017 · 7 comments · Fixed by #2973
Closed
Labels
bug mypy got something wrong topic-strict-optional

Comments

@benkuhn
Copy link
Contributor

benkuhn commented Mar 6, 2017

Steps to reproduce:

  1. Check out this repo
  2. Install the packages from requirements.txt
  3. Run mypy repro.py from the repo root.

Expected output:

repro.py:4: error: Revealed type is 'Any'
repro.py:6: error: Revealed type is 'builtins.None'

Actual output:

repro.py:4: error: Revealed type is 'Any'

The issue goes away if you disable strict Optional checking.

This is preventing a significant amount of our codebase from being checked right now, so I would appreciate any suggestions for a workaround!

@benkuhn benkuhn changed the title Mypy seems not to analyze code after assert x is None if x is Any? Mypy thinks assert x is None is dead code if x is Any, or something? Mar 6, 2017
@gvanrossum
Copy link
Member

gvanrossum commented Mar 6, 2017

So the crux of the repro is simply (with --strict-optional):

from typing import Any, Optional

def foo(a: Any) -> None:
    reveal_type(a)
    assert a is None
    reveal_type(None)  # This line is not analyzed

Thanks for reporting. This definitely is a bug. It seems related to (but is not a duplicate of) #2776.

@gvanrossum gvanrossum added bug mypy got something wrong topic-strict-optional labels Mar 6, 2017
@gvanrossum
Copy link
Member

Adding a strict-optional label since this is only a problem with strict-optional. @ddfisher any idea?

@benkuhn
Copy link
Contributor Author

benkuhn commented Mar 6, 2017

As a workaround/general safety measure, is there a way to force mypy to analyze all "dead" code after asserts? Our codebase has very little actual dead code, and comparatively many places where I'm worried that mypy would erroneously declare the code dead due to an assert like this.

@gvanrossum
Copy link
Member

I'm not aware of any. Note that it's not every assert, only very specific asserts. You could also refrain from using strict-optional for now (it's still very much experimental).

@benkuhn
Copy link
Contributor Author

benkuhn commented Mar 7, 2017

OK, I couldn't help poking around to see what the issue was, and I think I may have found the right place to fix it--let me know what you think!

@benkuhn
Copy link
Contributor Author

benkuhn commented Mar 9, 2017

Any thoughts on the pull request I submitted?

@gvanrossum
Copy link
Member

gvanrossum commented Mar 9, 2017 via email

@gvanrossum gvanrossum changed the title Mypy thinks assert x is None is dead code if x is Any, or something? When a has type Any, after assert a is None, the rest of the block is considered dead code Mar 13, 2017
ddfisher pushed a commit that referenced this issue Mar 15, 2017
`Any` is now properly special-cased to potentially overlap with all other types.  Fixes #2970.
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-strict-optional
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants