mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Function return type TypeVar is assumed to be base class for TypeVar bound to UnionType

Open kopp opened this issue 2 years ago • 1 comments

Bug Report

A function defined as

def assert_not_none(x: Optional[T]) -> T:
    assert x is not None
    return x

used with an input Optional[Union[A, B]] should return a type Union[A, B], but mypy 1.3.0 currently assumes that it returns the base class of A and B (or builtins.object if there is no other common base). (Note: pylance correctly identifies the return type as Union[A, B].)

To Reproduce

run mypy on the following file.

from typing import Literal, Optional, TypeVar, Union

from pydantic import BaseModel

T = TypeVar("T")


def assert_not_none(x: Optional[T]) -> T:
    assert x is not None
    return x


class Foo(BaseModel):
    foo: Literal[True]


class Bar(BaseModel):
    bar: Literal[True]


FooOrBar = Union[Foo, Bar]


def validate(input: Optional[FooOrBar]):
    reveal_type(input)  # as expected: Union[Foo, Bar, None]
    reveal_type(assert_not_none(input))  # expected: Union[Foo, Bar], actual: pydantic.main.BaseModel
    assert input is not None
    reveal_type(input)  # as expected: Union[Foo, Bar]

Expected Behavior

reveal_type(assert_not_none(input)) should be Union[Foo, Bar]

Actual Behavior

reveal_type(assert_not_none(input)) actually is pydantic.main.BaseModel.

Your Environment

  • Mypy version used: 1.3.0 (compiled: yes)
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.8.10

kopp avatar Jun 20 '23 09:06 kopp

this might be related to #15467

kopp avatar Jun 20 '23 09:06 kopp

Duplicate of https://github.com/python/mypy/issues/17383

hauntsaninja avatar Jul 03 '24 07:07 hauntsaninja