-
-
Notifications
You must be signed in to change notification settings - Fork 31.2k
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
gh-106292: restore checking __dict__ in cached_property.__get__ #106380
Conversation
* main: pythongh-106368: Increase Argument Clinic test coverage (python#106389) pythongh-106320: Fix _PyImport_GetModuleAttr() declaration (python#106386) pythongh-106368: Harden Argument Clinic parser tests (python#106384) pythongh-106320: Remove private _PyImport C API functions (python#106383) pythongh-86085: Remove _PyCodec_Forget() declaration (python#106377) pythongh-106320: Remove more private _PyUnicode C API functions (python#106382) pythongh-104050: Annotate more Argument Clinic DSLParser state methods (python#106376) pythongh-106368: Clean up Argument Clinic tests (python#106373)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some nit comments.
Misc/NEWS.d/next/Library/2023-07-03-15-09-44.gh-issue-106292.3npldV.rst
Outdated
Show resolved
Hide resolved
Misc/NEWS.d/next/Library/2023-07-03-15-09-44.gh-issue-106292.3npldV.rst
Outdated
Show resolved
Hide resolved
Co-authored-by: Dong-hee Na <donghee.na92@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
Thanks @carljm for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12. |
…pythonGH-106380) * pythongh-106292: restore checking __dict__ in cached_property.__get__ (cherry picked from commit 838406b) Co-authored-by: Carl Meyer <carl@oddbird.net> Co-authored-by: Dong-hee Na <donghee.na92@gmail.com>
GH-106469 is a backport of this pull request to the 3.12 branch. |
When locking was removed from
functools.cached_property
in #101890, the__get__
method also stopped pre-checking the instance dictionary for a cached value.This removed pre-check is not necessary for the correct behavior of
cached_property
in and of itself: since it's a non-data descriptor (does not define__set__
or__delete__
), the instance dictionary takes precedence over__get__
, so__get__
should never be reached if a cached value is set in the instance dictionary.But it seems that some users (including at least one popular library; see issue for details) are subclassing
cached_property
and adding a__set__
method, turning it into a data descriptor, which takes precedence over the instance dictionary. Prior to 3.12, this still worked OK (did not recompute the value on every access) because of the additional check for cached value in__get__
. But with 3.12 as it currently stands, this code would silently stop caching the value due to the added__set__
method.Although it's nice and clever for
cached_property
to be maximally efficient by taking advantage of being a non-data descriptor, I think in this case backwards-compatibility and avoiding a footgun is more important. Clearly some people are subclassingcached_property
and adding__set__
methods, and it's not realistic to expect every Python user to understand the subtleties of data vs non-data descriptors and how this could breakcached_property
. The cost here is also minimal: just one dictionary lookup, that should only occur once per instance (not on repeated access of the cached property).