Skip to content

fix(cache-manager): await an awaitable returned by the get_or_set factory - #133

Merged
allen0099 merged 1 commit into
masterfrom
fix/get-or-set-awaitable
Sep 25, 2026
Merged

allen0099 merged 1 commit into
masterfrom
fix/get-or-set-awaitable

Conversation

@allen0099

Copy link
Copy Markdown
Owner

Closes #101.

Problem

get_or_set() awaited the factory only when inspect.iscoroutinefunction(factory) was true. The example in docs/APP_CACHE.md, get_or_set("user:42", lambda: load_user(42), ttl=300), passes a lambda that returns a coroutine. That coroutine went to set(), which failed with TypeError: Object of type coroutine is not JSON serializable and emitted a "never awaited" warning.

Changes

  • get_or_set() calls the factory and awaits the result when inspect.isawaitable(result). This covers async functions, lambdas and functools.partial wrapping them, and async callables.
  • The factory docstring says so.
  • CHANGELOG [Unreleased] Fixed entry.

Tests

test_get_or_set_awaits_a_sync_callable_returning_an_awaitable is parametrized over a lambda and a functools.partial:

  • The lambda case fails on the old code and passes with the fix.
  • The partial case already passed, because iscoroutinefunction unwraps partials. It stays as a guard.

Local results:

  • ruff check/format: clean.
  • mypy (package strict, tests, scripts): clean.
  • zensical build --strict: passes.
  • Full suite with CACHEX_REQUIRE_LIVE_SERVERS=1 against Redis and Memcached: 720 passed, 100% coverage.

…tory

get_or_set() awaited the factory only when it was a coroutine function,
so the documented lambda: load_user(42) form stored the coroutine and
failed with TypeError. The factory is now called and its result awaited
whenever it is awaitable.

Closes #101
@allen0099
allen0099 force-pushed the fix/get-or-set-awaitable branch from 91dfcf2 to bc12389 Compare September 25, 2026 10:55
@allen0099
allen0099 merged commit a506e54 into master Sep 25, 2026
10 checks passed
@allen0099
allen0099 deleted the fix/get-or-set-awaitable branch September 26, 2026 11:49
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.

CacheManager.get_or_set stores the coroutine when a sync factory returns an awaitable

1 participant