Skip to content

@cache breaks type checking when used with @classmethod and typing.Self #19117

Closed as duplicate of#18993
@divya-e47

Description

@divya-e47

Title
@cache breaks type checking when used with @classmethod and typing.Self

Bug description

Using @functools.cache on a @classmethod that returns typing.Self breaks type inference in mypy and IntelliSense. mypy either falls back to Any or fails type inference entirely.

Illustrative repro

from functools import cache
from typing import Self

class MyProvider:
    @classmethod
    @cache
    def get_by_name(cls, name: str) -> Self:
        ...

provider = MyProvider.get_by_name("foo")
reveal_type(provider)  # mypy: Revealed type is "Any"

Without @cache (works as expected)

class MyProvider:
    @classmethod
    def get_by_name(cls, name: str) -> Self:
        ...

provider = MyProvider.get_by_name("foo")
reveal_type(provider)  # mypy: Revealed type is "MyProvider"

With @cache and concrete return type (also works)

class MyProvider:
    @classmethod
    @cache
    def get_by_name(cls, name: str) -> MyProvider:
        ...

provider = MyProvider.get_by_name("foo")
reveal_type(provider)  # mypy: Revealed type is "MyProvider"

Summary
This shows that Self return types on cached classmethods are not handled correctly by mypy. Replacing Self with the concrete class is a workaround, but sacrifices subclassing flexibility.

Environment
Python: 3.11 (per pyproject.toml)
mypy: 1.8+ (as specified in poetry.lock)
Flags: --strict
Editor: VSCode (optional, but IntelliSense also affected)

Related
Possibly related: python/typeshed#11280 (but that focuses on general decorator signature issues — this case seems specific to Self + @classmethod + @cache)

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