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

Type constraints on self are not correctly checked #1686

Open
SquidDev opened this issue Jul 15, 2024 · 1 comment
Open

Type constraints on self are not correctly checked #1686

SquidDev opened this issue Jul 15, 2024 · 1 comment

Comments

@SquidDev
Copy link

SquidDev commented Jul 15, 2024

Version Info

  • Python 3.10.12
  • pytype 2024.04.11

Details

Consider the following code:

from typing import Generic, TypeVar

T = TypeVar("T", int, str)

class Example(Generic[T]):
    value: T

    def as_str(self: "Example[str]") -> str:
        return self.value # <- errors

The type annotation on self should constrain the type variable T to be a str. However, this constraint is not applied, and instead T is assumed to be int | str:

File "example.py", line 9, in as_str: bad option 'int' in return type [bad-return-type]
           Expected: str
  Actually returned: Union[int, str]

This only happens when T has constraints defined. If T is left unconstrained (T = TypeVar("T")), then this code checks as expected.

@SquidDev
Copy link
Author

A somewhat similar bug can be seen when using Any1 as one of the constraints to TypeVar. Happy to report this as a separate issue, but it's possible the root cause is the same so wanted to check first:


from typing import Generic, TypeVar, Any

T = TypeVar("T", str, Any)

class Example(Generic[T]):
    value: T

def get_value(x: Example[Any]) -> int:
    return x.value # <- errors

The above code fails to type check with the following error:

File "example.py", line 9, in get_value: bad option 'str' in return type [bad-return-type]
           Expected: int
  Actually returned: Any

If we replace x.value with an actual Any value, then this code will type check.

Footnotes

  1. To clarify, we're not actually using Any here (that would be a bit silly!), but a type in an external (untyped) Python module. From my understanding, this then gets replaced with Any.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant