Skip to content

type of Union containing Any is incorrectly inferred after an isinstance check #1720

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
sharmaeklavya2 opened this issue Jun 18, 2016 · 3 comments · Fixed by #2446
Closed
Labels
bug mypy got something wrong

Comments

@sharmaeklavya2
Copy link

union_any.py:

from typing import Any, Union

def func(v):
    # type: (Union[int, Any]) -> str
    if isinstance(v, int):
        s = hex(v)
    else:
        s = str(v).lower()
    return "key:" + s

mypy union_any.py:

union_any.py: note: In function "func":
union_any.py:8: error: No overload variant of "str" matches argument types [Union[<ERROR>, void]]

mypy --py2 union_any.py:

union_any.py: note: In function "func":
union_any.py:8: error: Argument 1 to "str" has incompatible type "Union[object, None]"; expected "object"

I discovered this when I used a class which was defined in some library which did not have stubs and I was using --silent-imports.

@sharmaeklavya2 sharmaeklavya2 changed the title isinstance with Any fails type of Union containing Any is incorrectly inferred after an isinstance check Jun 18, 2016
@gvanrossum gvanrossum added the bug mypy got something wrong label Jun 23, 2016
@gvanrossum gvanrossum added this to the 0.4.x milestone Jun 23, 2016
@ddfisher
Copy link
Collaborator

In addition to being a Union[Any, ...] -> Any problem, I think this is at least vaguely related to #1691.

@sharmaeklavya2
Copy link
Author

Another case where I found this error is when 2 classes inherit from Any:

file1.py:

from typing import Any, Union

class B(Any): name = 'Bob'
class C(Any): name = 'Charlie'

def func(x):
    # type: (Union[B, C]) -> None
    reveal_type(x)
    if isinstance(x, B):
        reveal_type(x)
        print(x.name)
    else:
        reveal_type(x)
        print(x.name)

gives this output:

file1.py: note: In function "func":
file1.py:8: error: Revealed type is 'Union[file1.B, file1.C]'
file1.py:10: error: Revealed type is 'file1.B'
file1.py:13: error: Revealed type is 'Union[<ERROR>, <ERROR>]'
file1.py:14: error: Some element of union has no attribute "name"

It works fine when I replace Any by object.

@gvanrossum
Copy link
Member

On that second case: inheriting from Any is illegal (though it can happen legally when you inherit from a class whose import is suppressed by --silent-imports).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants