Skip to content

a second TypeVar confuses mypy in @overload return types #11159

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
finite-state-machine opened this issue Sep 21, 2021 · 2 comments
Closed

a second TypeVar confuses mypy in @overload return types #11159

finite-state-machine opened this issue Sep 21, 2021 · 2 comments
Labels
bug mypy got something wrong topic-type-variables

Comments

@finite-state-machine
Copy link

finite-state-machine commented Sep 21, 2021

Bug Report

When an overloaded function implementation returns a Union, mypy becomes confused when that Union contains two TypeVars.

The following code works as expected (i.e., there are no errors):

from typing import (
        Generic,
        Literal,
        Optional,
        overload,
        TypeVar,
        Union,
        )

T1 = TypeVar('T1')
T2 = TypeVar('T2')

# first example, works as expected:

U1 = Union[None, T1]

@overload
def works1(number: Literal[1]) -> T1: ...
@overload
def works1(number: Literal[2]) -> Optional[T1]: ...
def works1(number: int) -> U1:
    pass

# second example, also works as expected:

U2 = Union[None, int, T2]

@overload
def works2(number: Literal[1]) -> int: ...
@overload
def works2(number: Literal[2]) -> Optional[int]: ...
def works2(number: int) -> U2:
    pass

Adding T2 to U1 in the first example, or changing int to T1 in the second example, produces this third example, which exhibits the problem in question:

from typing import (
        Generic,
        Literal,
        Optional,
        overload,
        TypeVar,
        Union,
        )

T1 = TypeVar('T1')
T2 = TypeVar('T2')

# third example, does not work as expected:

U3 = Union[None, T1, T2]

@overload
def function(number: Literal[1]) -> T1: ...
@overload
def function(number: Literal[2]) -> Optional[T1]: ...
def function(number: int) -> U3:
    pass
# error: Overloaded function implementation cannot produce return type of signature 1  [misc]
# error: Overloaded function implementation cannot produce return type of signature 2  [misc]

To Reproduce

Run the "third example" code through mypy.

Expected Behavior

There should be no errors when processing the third example.

Actual Behavior

These errors are produced:

# error: Overloaded function implementation cannot produce return type of signature 1  [misc]
# error: Overloaded function implementation cannot produce return type of signature 2  [misc]

Further information

This may be related to #9023.

It may be helpful to know that the same problem still occurs if function is a method of a type which inherits from Generic[T2] (i.e., binding T2 doesn't help):

class SomeClass(Generic[T2]):
    @overload
    def method(self, number: Literal[1]) -> T1: ...
    @overload
    def method(self, number: Literal[2]) -> Optional[T1]: ...
    def method(self, number: int) -> Union[None, T1, T2]:
        pass

Your Environment

  • Mypy version used: 0.910 (installed via pip)
  • Mypy command-line flags: (none necessary to reproduce the issue)
  • Mypy configuration options from mypy.ini (and other config files): (none necessary to reproduce the issue)
  • Python version used: 3.8.3 as installed by pyenv
  • Operating system and version: macOS 10.14.6
@finite-state-machine finite-state-machine added the bug mypy got something wrong label Sep 21, 2021
@A5rocks
Copy link
Collaborator

A5rocks commented Nov 28, 2021

This works on mypy master, by the way.

@hauntsaninja
Copy link
Collaborator

I can't reproduce on any recent version of mypy

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

No branches or pull requests

4 participants