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

Naively implemented "Addable" Protocol does not throw Error for Tuples #14679

Closed
notatallshaw opened this issue Feb 11, 2023 · 2 comments
Closed
Labels
bug mypy got something wrong

Comments

@notatallshaw
Copy link

Bug Report

In attempting to create an "Addable Protocol" I messed up and it does not work for Tuples, but mypy does not give me an error where as pyright does.

To Reproduce

Create the Python file:

from typing import Protocol, TypeVar, Any

T = TypeVar("T")

class Addable(Protocol):
    def __add__(self: T, other: T, /) -> T:
        ...

x1: Addable = (1,)  # Expected No Error
x2: Addable = (1, 2)  # Expected Error

And run mypy --strict on this file.

Expected Behavior

Should throw an error because in some sense the return type of adding the tuple x2 will not be the same type when you add it, as the Addable Protocol would indicate. pyright gives the following error:

Expression of type "tuple[Literal[1], Literal[2]]" cannot be assigned to declared type "Addable"
  "tuple[Literal[1], Literal[2]]" is incompatible with protocol "Addable"
    "__add__" is an incompatible type
      No overloaded function matches type "(other: tuple[Literal[1], Literal[2]], /) -> tuple[Literal[1], Literal[2]]"
        Type "(__x: tuple[Literal[1, 2], ...], /) -> tuple[Literal[1, 2], ...]" cannot be assigned to type "(other: tuple[Literal[1], Literal[2]], /) -> tuple[Literal[1], Literal[2]]"
          Function return type "tuple[Literal[1, 2], ...]" is incompatible with type "tuple[Literal[1], Literal[2]]"
        Type "(__x: tuple[_T@__add__, ...], /) -> tuple[_T@__add__ | Literal[1, 2], ...]" cannot be assigned to type "(other: tuple[Literal[1], Literal[2]], /) -> tuple[Literal[1], Literal[2]]"
          Function return type "tuple[Literal[1, 2], ...]" is incompatible with type "tuple[Literal[1], 

One of the pyright maintainers kindly gave a detailed explanation here: microsoft/pyright#4613 (comment)

Actual Behavior

mypy outputs that everything is fine:

Success: no issues found in 1 source file

Your Environment

  • Mypy version used: 1.0.0
  • Mypy command-line flags: --strict
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.11.1
@notatallshaw notatallshaw added the bug mypy got something wrong label Feb 11, 2023
@JelleZijlstra
Copy link
Member

I don't think this is incorrect; it just depends on how the type of these tuple is inferred. Pyright infers the type as tuple[Literal[1], Literal[2]], which is valid, but another valid type for these tuples is tuple[int, ...], which does indeed follow the Addable protocol.

@notatallshaw
Copy link
Author

I don't think this is incorrect; it just depends on how the type of these tuple is inferred. Pyright infers the type as tuple[Literal[1], Literal[2]], which is valid, but another valid type for these tuples is tuple[int, ...], which does indeed follow the Addable protocol.

Yup, I'm better understanding the design choices here of the different type checkers. Thanks for your time replying.

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

2 participants