mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Not evaluating Union[X, Y] from Type[Union[X, Y]] over (Type[T]) -> T function

Open ericbn opened this issue 3 years ago • 1 comments

Bug Report

Mypy is evaluating builtins.object instead of Union[X, Y] as the returned type when passing an argument of type Type[Union[X, Y]] to a def [T] (cl: Type[T']) -> T' function.

To Reproduce

  1. Check this code with mypy:
    from typing import TypeVar, Union
    
    T = TypeVar('T')
    
    
    def _structure(cl: type[T]) -> T:
        return cl()
    
    
    def structure(cl: type[Union[int, str]]) -> Union[int, str]:
        reveal_type(cl)
        reveal_type(_structure)
        data = _structure(cl)
        reveal_type(data)
        return data
    
    

Expected Behavior

Output:

scratch.py:11: note: Revealed type is "Union[Type[builtins.int], Type[builtins.str]]"
scratch.py:12: note: Revealed type is "def [T] (cl: Type[T`-1]) -> T`-1"
scratch.py:14: note: Revealed type is "Union[builtins.int, builtins.str]"
Success: no issues found in 1 source file

or

scratch.py:11: note: Revealed type is "Type[Union[builtins.int, builtins.str]]"
scratch.py:12: note: Revealed type is "def [T] (cl: Type[T`-1]) -> T`-1"
scratch.py:14: note: Revealed type is "Union[builtins.int, builtins.str]"
Success: no issues found in 1 source file

(Type[Union[X, Y]] instead of Union[Type[X], Type[Y]] in line 11)

Actual Behavior

Output:

scratch.py:11: note: Revealed type is "Union[Type[builtins.int], Type[builtins.str]]"
scratch.py:12: note: Revealed type is "def [T] (cl: Type[T`-1]) -> T`-1"
scratch.py:14: note: Revealed type is "builtins.object"
scratch.py:15: error: Incompatible return value type (got "object", expected "Union[int, str]")
Found 1 error in 1 file (checked 1 source file)

(revealed type in line 14 is "builtins.object" instead of "Union[builtins.int, builtins.str]")

The error looks like might be because of the covariance of Union.

Your Environment

  • Mypy version used: 0.971
  • Mypy command-line flags: just the file name, no extra flags.
  • Mypy configuration options from mypy.ini (and other config files): no config file.
  • Python version used: 3.9.13
  • Operating system and version: macOS 12.5.1

ericbn avatar Sep 03 '22 20:09 ericbn

Replacing Union[int, str] by just int or str in the code above works as expected.

ericbn avatar Sep 03 '22 20:09 ericbn

Updated the issue description. It was initially reported using mypy version 0.971 and it's still present in mypy 1.4.1.

ericbn avatar Jul 22 '23 13:07 ericbn