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

'got "C[T]", expected "C[T]"' with staticmethod #16668

Closed
comex opened this issue Dec 15, 2023 · 1 comment · Fixed by #16670
Closed

'got "C[T]", expected "C[T]"' with staticmethod #16668

comex opened this issue Dec 15, 2023 · 1 comment · Fixed by #16670
Labels
bug mypy got something wrong

Comments

@comex
Copy link

comex commented Dec 15, 2023

Bug Report

In the below playground link, mypy gives this error:

main.py:10: error: Incompatible return value type (got "C[T]", expected "C[T]")  [return-value]

I think the program should pass type checking (it does with Pyright), but if there is some problem with it I'm not understanding, at least the error message should be better.

To Reproduce

https://mypy-play.net/?mypy=latest&python=3.12&gist=bcfed78680f130f0b4d87886bb196af7

from typing import Generic, TypeVar 
T = TypeVar('T')

class C(Generic[T]):
    @staticmethod
    def c() -> 'C[T]':
        return C()

def f(t: T) -> C[T]:
    return C[T].c()

Your Environment

  • Mypy version used: 1.7.1 on playground
  • Mypy command-line flags: -
  • Mypy configuration options from mypy.ini (and other config files): -
  • Python version used: 3.12
@comex comex added the bug mypy got something wrong label Dec 15, 2023
@kourbou
Copy link
Contributor

kourbou commented Dec 16, 2023

The error message is confusing because the type variable T is actually not the same in f and C. (Technically it is T`-1 and T`1 but mypy does not expose these names.) You can reproduce using two separate type variables as well:

T = TypeVar('T')
S = TypeVar('S')

class C(Generic[T]):
    @staticmethod
    def get() -> T: ...

def func(x: S) -> S:
    return C[S].get()  # E: Incompatible return value type (got "T", expected "S")  [return-value]

Generally you'd use @classmethod for this kind of thing, and mypy handles this edge case correctly:

T = TypeVar('T')

class C(Generic[T]):
    @classmethod
    def c(cls: 'type[C[T]]') -> 'C[T]':
        return cls()

def f(t: T) -> C[T]:
    return C[T].c()

kourbou added a commit to kourbou/mypy that referenced this issue Dec 16, 2023
`add_class_tvars` correctly instantiates type variables for class
methods but not for static methods. Check if the analyzed member is
a static method in `analyze_class_attribute_access` and substitute
the type variable in the return type in `add_class_tvars` accordingly.

Fixes python#16668.
kourbou added a commit to kourbou/mypy that referenced this issue Dec 16, 2023
`add_class_tvars` correctly instantiates type variables for class
methods but not for static methods. Check if the analyzed member is
a static method in `analyze_class_attribute_access` and substitute
the type variable in the return type in `add_class_tvars` accordingly.

Fixes python#16668.
kourbou added a commit to kourbou/mypy that referenced this issue Dec 16, 2023
`add_class_tvars` correctly instantiates type variables for class
methods but not for static methods. Check if the analyzed member is
a static method in `analyze_class_attribute_access` and substitute
the type variable in the return type in `add_class_tvars` accordingly.

Fixes python#16668.
kourbou added a commit to kourbou/mypy that referenced this issue Dec 16, 2023
`add_class_tvars` correctly instantiates type variables for class
methods but not for static methods. Check if the analyzed member is
a static method in `analyze_class_attribute_access` and substitute
the type variable in the return type in `add_class_tvars` accordingly.

Fixes python#16668.
hauntsaninja pushed a commit that referenced this issue Dec 17, 2023
`add_class_tvars` correctly instantiates type variables in the return
type for class methods but not for static methods. Check if the analyzed
member is a static method in `analyze_class_attribute_access` and
substitute the type variable in the return type in `add_class_tvars`
accordingly.

Fixes #16668.
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

Successfully merging a pull request may close this issue.

2 participants