Skip to content
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

Incorrect "redundant cast" for linked TypeVar T and type[T] variables #17045

Open
richardxia opened this issue Mar 18, 2024 · 0 comments
Open
Labels
bug mypy got something wrong

Comments

@richardxia
Copy link

Bug Report

Given a TypeVar T with multiple, concrete constraints, if you write a generic function that takes an argument of type T, another argument of type type[T], and return a value of type T, mypy does not seem to have consistent behavior when it comes to handling the return type of individual expressions. Attempting to return a value without casting hits an Incompatible return value type error, while attempting to cast causes a Redundant cast error.

To Reproduce

from decimal import Decimal
from typing import TypeVar, cast

T = TypeVar("T", Decimal, float)


def foo(x: T, x_type: type[T]) -> T:
    if x_type == float:
        return cast("T", 1.0)
    if x_type == Decimal:
        return cast("T", Decimal("2.0"))
    raise ValueError("unreachable")


def foo2(x: T, x_type: type[T]) -> T:
    if x_type == float:
        return 1.0
    if x_type == Decimal:
        return Decimal("2.0")
    raise ValueError("unreachable")

https://mypy-play.net/?mypy=1.9.0&python=3.12&flags=strict&gist=4a0bc37034dcbcd5a18fabebeb5cbff5

Expected Behavior

I expected either one of foo() or foo2() to be accepted by mypy. I don't necessarily expect mypy to be smart enough to infer the the linkage between narrowing the type of x_type and relating it to the type of x, but I at least expect to be able to explicitly cast the return expression without hitting a Redundant cast error.

Actual Behavior

main.py:9: error: Redundant cast to "float"  [redundant-cast]
main.py:11: error: Redundant cast to "Decimal"  [redundant-cast]
main.py:17: error: Incompatible return value type (got "float", expected "Decimal")  [return-value]
main.py:19: error: Incompatible return value type (got "Decimal", expected "float")  [return-value]
Found 4 errors in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 1.7.1 (but the mypy Playground I linked to above was 1.9.0)
  • Mypy command-line flags:
  • Mypy configuration options from mypy.ini (and other config files):
    warn_unused_ignores = true
    warn_redundant_casts = true
    warn_unused_configs = true
    warn_unreachable = true
    warn_return_any = true
    strict = true
    disallow_untyped_decorators = true
    disallow_any_generics = false
    implicit_reexport = false
    show_error_codes = true
  • Python version used: 3.11.6 (mypy Playground was 3.12)
@richardxia richardxia added the bug mypy got something wrong label Mar 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

1 participant