Skip to content

Fix class access to functools.cached_property attributes - #21858

Open
aryansk wants to merge 1 commit into
python:masterfrom
aryansk:fix-cached-property-class-access
Open

Fix class access to functools.cached_property attributes#21858
aryansk wants to merge 1 commit into
python:masterfrom
aryansk:fix-cached-property-class-access

Conversation

@aryansk

@aryansk aryansk commented Aug 16, 2026

Copy link
Copy Markdown

Fixes #21825.

What

Accessing a functools.cached_property through the class object was typed as the raw getter callable, so descriptor attributes were reported as missing:

from functools import cached_property

class A:
    @cached_property
    def value(self) -> int:
        return 1

    @classmethod
    def name(cls) -> str:
        return cls.value.attrname  # error: "Callable[[A], int]" has no attribute "attrname"

At runtime A.value is the cached_property instance itself (it has attrname, func, etc.). This PR types class access as the descriptor and lets the existing descriptor machinery apply typeshed's __get__(self, instance: None, ...) -> Self overload:

reveal_type(A.value)  # functools.cached_property[builtins.int]

How

In analyze_class_attribute_access, when the member is decorated with functools.cached_property and accessed as a value (not an lvalue), feed the descriptor instance type (cached_property[<getter return>]) into analyze_descriptor_access instead of the bare callable. Instance access is unchanged (already went through the descriptor path), and lvalue behavior (e.g. A.value = 5) is unchanged.

Test

Added testCachedPropertyClassAccess to test-data/unit/check-functools.test; it fails on main and passes with this change. Full testcheck suite passes (8178 passed, 33 skipped, 7 xfailed).

Accessing a functools.cached_property through the class object (e.g.
`cls.value.attrname` inside a classmethod) previously exposed the getter
as a bare callable, so descriptor attributes like `attrname` and `func`
were reported as missing. At runtime the value is the `cached_property`
instance itself, so type it as such and let the descriptor machinery
(`__get__(None, owner) -> Self`) apply.
@github-actions

Copy link
Copy Markdown
Contributor

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

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

Successfully merging this pull request may close these issues.

When accessing a functools.cached_property through the class, mypy incorrectly treats it as a Callable.

1 participant