bpo-46622: Async support for cached_property#31314
Conversation
The functools.cached_property can now decorate an async function. It would cache a wrapper to the coroutine returned by the function, and await it when the wrapper is first awaited.
| val = cache.get(self.attrname, _NOT_FOUND) | ||
| if val is _NOT_FOUND: | ||
| val = self.func(instance) | ||
| if inspect.iscoroutinefunction(self.func): |
There was a problem hiding this comment.
inspect.isawaitable(val) check covers more cases, please use it.
There was a problem hiding this comment.
This would change the behaviour of
class MyAwaitable:
def __await__(self):
print("called")
class Foo:
@cached_property
def get_awaitable(self):
return MyAwaitable()Currently this would cache the MyAwaitable object and calls __await__. If we use isawaitable here, MyAwaitable would be wrapped and only awaited once.
IMO iscoroutinefunction is more correct here.
| ) | ||
|
|
||
| def __get__(self, instance, owner=None): | ||
| import inspect |
There was a problem hiding this comment.
Please move the import just before usage, when the attribute name is not in cache yet.
The import instruction is not for free, it requires a lock at least IIRC.
The move allows returning cached results as fast as possible.
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
|
|
||
|
|
||
| class _CachedAwaitable: | ||
| """Wrapper to return if @cached_proeprty is used on a coroutine function. |
There was a problem hiding this comment.
spelling: cached_property
|
|
||
| A coroutine shouldn't simply be cached since it can only be awaited once. | ||
| This wrapper is cached instead, which awaits the underlying coroutine at | ||
| most once and cache the result for subsequent calls. |
|
Closing for now to work on |
The functools.cached_property can now decorate an async function. It would cache a wrapper to the coroutine returned by the function, and await it when the wrapper is first awaited.
https://bugs.python.org/issue46622