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

Failure to detect non-None Optional type in conditional expression #6755

Closed
jonafato opened this issue May 2, 2019 · 6 comments
Closed

Failure to detect non-None Optional type in conditional expression #6755

jonafato opened this issue May 2, 2019 · 6 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-strict-optional

Comments

@jonafato
Copy link

jonafato commented May 2, 2019

  • Are you reporting a bug, or opening a feature request?
    Bug

  • Please insert below the code you are checking with mypy, or a mock-up repro if the source is private. We would appreciate if you try to simplify your case to a minimal repro.

from typing import Mapping, Optional

names_to_numbers: Mapping[str, Optional[int]] = {
    'one': 1,
    'two': 2,
    'foo': None,
}

squares = {
    1: 1,
    2: 4,
    3: 9,
}

squares[names_to_numbers['foo']] if names_to_numbers['foo'] else None
  • What is the actual behavior/output?
bug.py:15: error: Invalid index type "Optional[int]" for "Dict[int, int]"; expected type "int"

This error is only thrown for conditional expressions of the form if container[index] else None. Changing it to any of the following works as expected:

squares[names_to_numbers['foo']] if names_to_numbers['foo'] is not None else None
squares[names_to_numbers['foo']] if isinstance(names_to_numbers['foo'], int) else None
foo = names_to_numbers['foo']
squares[foo] if foo else None
  • What is the behavior/output you expect?
    No errors reported.

  • What are the versions of mypy and Python you are using?
    mypy 0.701, reproducible on at least Python 2.7 and 3.7.

  • Do you see the same issue after installing mypy from Git master?
    Yes

@ilevkivskyi
Copy link
Member

I agree this behavior is inconsistent. Mypy already allows (on purpose) some code that may be technically unsafe (e.g. __getitem__() call is not guaranteed to return same return with same arguments every time) but are practically useful. We already allow this in other circumstances as you noticed. We should probably to update the branch in find_isinstance_check() (not the best name, I know) where we test for if isinstance(node, RefExpr) to accept any BindableExpression with a correct literal level.

Btw, the same same happens in normal if statement, not only in a ternary expression:

if names_to_numbers['foo']:  # error also disappears if I add 'is not None'
    squares[names_to_numbers['foo']]  # same error here

@ilevkivskyi ilevkivskyi added bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-strict-optional labels May 7, 2019
@mbdevpl

This comment has been minimized.

@mbdevpl

This comment has been minimized.

@JelleZijlstra
Copy link
Member

@mbdevpl that's a separate issue with the ternary expression, similar to #4134.

@mbdevpl
Copy link

mbdevpl commented Feb 4, 2020

@JelleZijlstra OK, migrated there! Thanks!

@AlexWaygood
Copy link
Member

This is no longer reproducible on mypy 0.930+

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-strict-optional
Projects
None yet
Development

No branches or pull requests

5 participants