Skip to content

Class factory with type[TypeVar] with upper bound not checked correctly (false positive) #14790

Open

Description

@sterliakov

Bug Report
Class factory, that uses TypeVar with upper bound as a type, suffers from over-inference, thinking that type[SomeTypeVar] gives its upper bound on instantiation.

To Reproduce

from typing import TypeVar, Type, Union

class A:
    def __init__(self, x: str) -> None: pass
class B:
    def __init__(self, x: int) -> None: pass
class C:
    def __init__(self, x: int) -> None: pass

T = TypeVar('T', bound=Union[A, B])

def f(x: Type[T]) -> T:
    return x(1)  \
        # E: Incompatible return value type (got "Union[A, B]", expected "T") \
        # E: Argument 1 to "A" has incompatible type "int"; expected "str"

T2 = TypeVar('T2', bound=Union[B, C])

def f2(x: Type[T2]) -> T2:
    return x(1)  # E: Incompatible return value type (got "Union[B, C]", expected "T2")

Gist

Expected Behavior

I expect only 2nd error (invalid constructor arg) to be reported, without replacing a TypeVar with Union bound.

Actual Behavior

main.py:13: error: Incompatible return value type (got "Union[A, B]", expected "T")  [return-value]
main.py:13: error: Argument 1 to "A" has incompatible type "int"; expected "str"  [arg-type]
main.py:20: error: Incompatible return value type (got "Union[B, C]", expected "T2")  [return-value]
Found 3 errors in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 1.0.1 and master, repro's on older versions too
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.8-3.11 tested, irrelevant

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