Skip to content

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

Closed

Description

@sharmaeklavya2

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.

Activity

  1. changed the title [-]isinstance with Any fails[/-] [+]type of Union containing Any is incorrectly inferred after an isinstance check[/+] on Jun 18, 2016
  2. added this to the milestone on Jun 23, 2016
  3. ddfisher commented on Jun 23, 2016

    @ddfisher
    Collaborator

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

  4. sharmaeklavya2 commented on Jun 26, 2016

    @sharmaeklavya2
    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.

  5. gvanrossum commented on Jul 13, 2016

    @gvanrossum
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions