Skip to content

the possibility that isinstance(some_var, (A, B)) causes mypy to forget about a some_var's type #10835

Closed

Description

@finite-state-machine

Bug Report

Certain patterns of if isinstance(...) cause mypy to forget that a variable has a particular generic type.

To Reproduce

Run the following Python code through mypy with --strict:

from typing import TypeVar

# context:
T = TypeVar('T')
class A: pass
class B: pass


def function1(obj: T) -> T:  # expected behaviour:
    if isinstance(obj, A):
        pass
    elif isinstance(obj, B):
        pass
    return obj  # no problem here

def function2(obj: T) -> T:  # unexpected behaviour:
    if isinstance(obj, (A, B)):
        pass
    return obj  # mypy has forgotten that obj is of type T

The issue also reproduces with this alternate definition of function2:

def function2(obj: T) -> T:  # unexpected behaviour:
    if isinstance(obj, A) or isinstance(obj, B):
        pass
    return obj  # mypy has forgotten that obj is of type T

Expected Behavior

mypy should issue no errors.

Actual Behavior

<last line of function2>: error: Returning Any from function declared to return "T" 
[no-any-return]
        return obj  # mypy has forgotten that 'obj' is of type 'T'
        ^
Found 1 error in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: mypy 0.910
  • Mypy command-line flags: --strict
  • Mypy configuration options from mypy.ini (and other config files): no additional flags are necessary to reproduce the issue
  • Python version used: CPython 3.8.3 (from pyenv)
  • Operating system and version: macOS 10.14

Activity

  1. erictraut commented on Jul 17, 2021

    @erictraut

    This appears to be the same issue as #10817.

  2. finite-state-machine commented on Jul 17, 2021

    @finite-state-machine
    Author

    It could very well be the same root cause; given my lack of knowledge of mypy internals, I can't say. If there is a distinction, it's this: in #10817, it appears that the type of the variable is being positively inferred, overriding the already-known generic type. In this issue, no inference is possible, but the type somehow changes from the generic T to Any.

  3. finite-state-machine commented on Jul 17, 2021

    @finite-state-machine
    Author

    I also note that in this issue, testing against one class (at a time) is not sufficient to trigger the problem; testing against two classes is required. (See function1, which behaves as expected.)

  4. finite-state-machine commented on Dec 8, 2022

    @finite-state-machine
    Author
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