Skip to content

chore(main): release 0.23.0 - #511

Open
cachekit-release-bot[bot] wants to merge 2 commits into
mainfrom
release-please--branches--main--components--cachekit
Open

cachekit-release-bot[bot] wants to merge 2 commits into
mainfrom
release-please--branches--main--components--cachekit

Conversation

@cachekit-release-bot

@cachekit-release-bot cachekit-release-bot Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

🤖 I have created a release beep boop

0.23.0 (2026-10-10)

⚠ BREAKING CHANGES

  • config: refuse an invalid assignment to the loaded settings and write nothing (LAB-8739) (#567)
  • decorators: share one call between concurrent misses on a key, run in its own task (LAB-7441) (#547)
  • redis: code that reads redis-py's exception off the error stops seeing it. BackendError.original_exception and __cause__ for a redis-py failure are now a RedisClientError, not redis-py's exception. Code that checked isinstance(err.original_exception, redis.exceptions.AuthenticationError) should check issubclass(err.original_exception.exc_type, ...). A RedisBackend error carried no original_exception before; it now carries the same RedisClientError. repr(RedisBackendConfig(...)) and str(...) no longer show redis_url; the attribute is unchanged.
  • observability: the tracing surface, which never traced, is removed: MonitoringConfig.enable_tracing (passing it raises TypeError), the enable_tracing key of DecoratorConfig.to_dict(), create_cache_wrapper(enable_tracing=), FeatureOrchestrator.create_span, FeatureOrchestrator.set_span_attributes, FeatureOrchestrator.record_exception, handle_cache_error(span=), and StructuredLogger.set_trace_id / clear_trace_id. A failed sync client creation or L2 GET no longer records a second cache_operations_total sample with operation="exception"; it records one failure sample, as the async paths do.
  • config: master_key= on @cache, @cache.secure, DecoratorConfig.secure(), EncryptionConfig, CacheSerializationHandler and validate_encryption_config raises TypeError for a bytes, bytearray or memoryview key: pass key.hex(). Only EncryptionWrapper takes raw key bytes. With encryption on, such a key already failed, with AttributeError. With encryption unset, the decorator raised ConfigurationError for it, and now raises TypeError. With encryption off (encryption=False, EncryptionConfig(enabled=False)) it was accepted, and failed only when an encrypted entry was read; it now raises where it is passed. On Python 3.14, CacheSerializationHandler read a bytes key holding ASCII hex digits as that hex; it now raises too.
  • decorators: @cache(config=..., encryption=...) raises ConfigurationError when the config is encrypted (DecoratorConfig.secure(...), or a config built with encryption=EncryptionConfig(enabled=True, ...)), and @cache(config=DecoratorConfig.io(...), backend=...) raises ConfigurationError. A keyword that names no DecoratorConfig field raises ConfigurationError, not TypeError, from @cache, from every preset but @cache.local, from the DecoratorConfig preset classmethods and beside config=; so does encryption= on @cache.secure and DecoratorConfig.secure(). EncryptionWrapper(master_key=...) raises EncryptionError, and previous_master_keys= raises KeyringConfigurationError, for a raw key that is not exactly 32 bytes: pass bytes.fromhex(hex_key), never hex_key.encode().
  • serializers: EncryptionWrapper now raises ConfigurationError at construction when its serializer's class does not declare cross_sdk_compatible = True. AutoSerializer and unmarked custom serializers are refused. This is a breaking change for code that builds the wrapper directly around AutoSerializer.
  • cachekitio: a subdomain of the two API hosts now needs CACHEKIT_ALLOW_CUSTOM_HOST=true. A custom host with non-ASCII characters must be given in its ASCII (xn--) form.
  • decorators: DecoratorConfig().backend is UNSET, not None. UNSET is falsy, so if config.backend: reads as before, and to_dict() still reports an unset backend as None. Code that tests config.backend is None on an unset backend must test is UNSET instead. Type checkers now see UNSET in the field's type, so narrowing with is not None and then using the value as a backend is flagged; narrow with if config.backend: or is not UNSET. DecoratorConfig(..., backend=None) and every preset with backend=None now mean L1-only instead of "resolve the default backend". To keep the old behaviour, omit backend from the config. DecoratorConfig.secure(..., backend=None) and an interop config with backend=None, which decorated before, now raise ConfigurationError at decoration.
  • encryption: encrypted entries written by earlier releases through a prefixing backend (MemcachedBackend with a key_prefix, the tenant-scoped Redis backend from env auto-detection or RedisBackendProvider, or a custom backend with a non-empty key_prefix) no longer authenticate. By default each one is read once as a miss, counted as auth_tamper, recomputed and overwritten. With fail_closed=True, every read of one raises DecryptionAuthenticationError until it expires or is deleted. Delete those entries, or move the cache to a fresh key space (a new namespace or Memcached key_prefix), rather than wait out the TTL. During a rolling upgrade, old and new processes read each other's writes as failed authentication, so give the new release a fresh key space or stop the old processes first. There is no fallback to the earlier AAD. Unaffected: a RedisBackend you construct yourself, FileBackend, CachekitIOBackend, and interop mode.

Bug Fixes

  • backends: declare with_timeout's decorated shape and restore the pool timeout after overlapping windows (LAB-4489) (#558) (93d4d93)
  • backends: drop with_timeout windows a forked child inherits (LAB-4489) (#559) (70ffd59)
  • cachekitio: hold a bytes api_key only wrapped when a later check raises (LAB-8288) (#529) (707aad2)
  • cachekitio: keep the API key off a failed request's exception chain (LAB-8304) (#539) (6919e13)
  • cachekitio: keep the API key off an interrupt raised mid-request (LAB-8339) (#541) (966f25f)
  • cachekitio: re-lease a client that close_http_clients() closed (LAB-8032) (#533) (f2bf102)
  • cachekitio: send X-CacheKit-TTL alone and ceil sub-second TTLs (LAB-8206) (#520) (ead1a09)
  • cachekitio: validate the host the HTTP client connects to (LAB-8207) (#519) (f38fd55)
  • circuit-breaker: count a probe's outcome only toward the cycle that admitted it (LAB-5374) (#565) (a2c5f2c)
  • config: refuse a bytes master_key where a hex string is taken (LAB-8281) (#526) (22d330b)
  • config: refuse an invalid assignment to the loaded settings and write nothing (LAB-8739) (#567) (29c6a59)
  • decorators: count the async backed miss in cache_info() (LAB-8298) (#538) (904e4bb)
  • decorators: keep backend=None L1-only on reused decorators and in DecoratorConfig (LAB-8059) (#515) (da70f3a)
  • decorators: refuse an out-of-model interop return on uncached calls (LAB-5375) (#530) (2e1fba5)
  • decorators: reject keywords a preset does not take, and raw keys that are not 32 bytes (LAB-8223) (#524) (9b3eb30)
  • decorators: restore the stats context on every sync exit, interrupts included (LAB-8741) (#568) (d2dc83a)
  • decorators: time each latency sample over the operation it names (LAB-7148) (#554) (e1a4f8f)
  • encryption: bind the backend key prefix into the AES-GCM AAD (LAB-8115) (#518) (30201ee)
  • encryption: refuse bare Arrow after decrypt and a non-bool compressed AAD token (LAB-8182) (#517) (256f01d)
  • encryption: refuse master_key= repeated in previous keys at decoration (LAB-8701) (#563) (97bc0b6)
  • file: expire a File-backend entry at its expiry second (LAB-8073) (#514) (9312ba7)
  • interop: decode non-string map keys; run interop-mode 1.3.0 and decode-bounds 1.2.0 vectors (LAB-8307) (#537) (819460b)
  • observability: remove the no-op tracing surface (LAB-6369) (#546) (ba6368b)
  • redis: clear an interrupt's frames on its way out of a Redis operation (LAB-8396) (#564) (09c2b8a)
  • redis: free a failed op's frames on LOADING/WRONGPASS, and log a release failure after the lock block raised (LAB-8383) (#551) (67006b5)
  • redis: keep the Redis password off a failed operation's traceback (LAB-8338) (#542) (84ec76c)
  • serializers: EncryptionWrapper refuses a serializer that is not cross-SDK (LAB-8195) (#521) (fc45785)
  • serializers: raise SerializationError when numpy or pandas cannot load on decode (LAB-8131) (#534) (7aeb26c)
  • serializers: skip the envelope probe on decrypted StandardSerializer reads (LAB-8371) (#544) (1e779a0)
  • tests: draw redis_proc ports below the Kubernetes NodePort range (LAB-8072) (#516) (78d1fa6)

Performance Improvements

  • cachekitio: free a failed request's frames without the cyclic GC (LAB-8378) (#552) (c0b5cab)
  • decorators: build the L2 cache handler once per backend; class-based backpressure permit (LAB-7112) (#553) (25bbabe)
  • decorators: share one call between concurrent misses on a key, run in its own task (LAB-7441) (#547) (b8967d3)
  • file: keep entry count and bytes in counters instead of two directory scans per set (LAB-7107) (#512) (b1cfc89)
  • file: narrow the FileBackend lock to the rename commit and resolve cache_dir once (LAB-7076) (#535) (6ad08ae)
  • ir: ratchet four stale perf-ir budgets to main's cost (LAB-8629) (#556) (1c049a1)
  • serializers: load numpy, pandas and pyarrow on first use, not at import cachekit (LAB-7093) (#509) (9533b55)
  • serializers: skip the standard object_hook's .get() calls on non-marker maps (LAB-7113) (#508) (3db2941)
  • telemetry: skip disabled cache-op logging and bind each Prometheus series once (LAB-7067) (#555) (fef0bb1)

This PR was generated with Release Please. See documentation.

@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: cachekit-io/cachekit-py/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: c4c0168f-ad7b-4791-9528-9dcd99621d79

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@cachekit-release-bot cachekit-release-bot Bot changed the title chore(main): release 0.22.1 chore(main): release 0.23.0 Oct 5, 2026
@cachekit-release-bot
cachekit-release-bot Bot force-pushed the release-please--branches--main--components--cachekit branch 25 times, most recently from 916adcb to cf1103e Compare October 6, 2026 03:16
@cachekit-release-bot
cachekit-release-bot Bot force-pushed the release-please--branches--main--components--cachekit branch 25 times, most recently from c46ff09 to d6bbf5f Compare October 10, 2026 02:47
@cachekit-release-bot
cachekit-release-bot Bot force-pushed the release-please--branches--main--components--cachekit branch from d6bbf5f to 16d2298 Compare October 10, 2026 04:40

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant