mypy icon indicating copy to clipboard operation
mypy copied to clipboard

`issubclass()` assertions not narrowing types

Open jwodder opened this issue 4 years ago • 2 comments

Consider the following (contrived) code:

from typing import Type

def untyped_function():
    return int

def foo() -> Type[int]:
    x = untyped_function()
    assert issubclass(x, int)
    return x

Running mypy on this with the --warn-return-any option produces the error "Returning Any from function declared to return "Type[int]"", even though the assert issubclass should convince mypy that x is of type Type[int] and not an Any.

Your Environment

  • Mypy version used: 0.902
  • Mypy command-line flags: --warn-return-any
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: Python 3.9.5
  • Operating system and version: macOS 11.3.1

jwodder avatar Jun 20 '21 22:06 jwodder

We hit this issue in production code.

mypy Playground gist with repro and a workaround: https://mypy-play.net/?mypy=latest&python=3.10&gist=35deff0d7118af72d07a113a1f05c82b (mypy 0.961, Python 3.10)

kveretennicov avatar Jun 09 '22 21:06 kveretennicov

Just in case it's a useful test-case, I have a slight variation on this error, where it's clear from looking that we can deduce the narrowed return type in all conditional paths but where mypy complains that it thinks we could potentially be dealing with an 'Any' type -

def f(something: bool) -> dict:
    my_dict = None
    if something:
        exec('d = {}', globals(), locals())
        my_dict = locals()['d']
        assert isinstance(my_dict, dict)
        # ... No good if we use this assert.
    else:
        my_dict = {}
    # assert isinstance(my_dict, dict)
    # ... but all good if we use this assert
    return my_dict

GertyP avatar Jul 03 '23 14:07 GertyP