Skip to content

refactor(decoders): per-instance cache replaces module lru_cache#42

Merged
lesnik512 merged 5 commits into
mainfrom
refactor/decoder-instance-cache
Jun 10, 2026
Merged

refactor(decoders): per-instance cache replaces module lru_cache#42
lesnik512 merged 5 commits into
mainfrom
refactor/decoder-instance-cache

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Summary

  • PydanticDecoder._adapters and MsgspecDecoder._msgspec_decoders instance dicts replace module-level @functools.lru_cache factories. Cache lifetime now matches the decoder/client, not the process.
  • Two autouse cache-clear test fixtures deleted — _clear_adapter_cache (test_decoders_pydantic.py) and _clear_msgspec_cache (test_decoders_msgspec.py, added one PR ago in PR feat!: multi-decoder routing (decoders=[...]) #41).
  • Hot-path performance preserved for the common case (one client per process). Multi-client processes pay a small per-instance construction cost; spec calls this out as acceptable (YAGNI).

No public API change. Folded into 0.9.0 (untagged).

Spec: planning/specs/2026-06-10-decoder-instance-cache-design.md
Plan: planning/plans/2026-06-10-decoder-instance-cache-plan.md

Test plan

  • just lint clean (ruff format + ruff check + ty)
  • just test green — 485 passed, 100% coverage
  • Cache-invariance tests adapted in-place (spy-on-TypeAdapter / spy-on-msgspec.json.Decoder still works; the patch target was the imported symbol, unchanged by this refactor)
  • Unhashable-model fallback in decode() preserved; tests use patch.object(PydanticDecoder, '_get_adapter', ...) and patch.object(MsgspecDecoder, '_get_msgspec_decoder', ...) instead of patching module-level functions
  • can_decode_uses_cache assertions shifted from _get_adapter.cache_info() to introspecting decoder._adapters / decoder._msgspec_decoders dicts directly
  • MsgspecDecoder.can_decode's msgspec.inspect.type_info + CustomType filter preserved verbatim (orthogonal to cache mechanics)
  • planning/engineering.md Seam B description updated to reflect per-instance ownership

Move TypeAdapter / msgspec.json.Decoder caching from `@functools.lru_cache`
module-level functions onto per-instance dicts on each decoder. No public
API change; tied to decoder/client lifecycle; removes the autouse cache-clear
test fixtures and the implicit cross-test pollution risk they were guarding
against.
Three-task TDD sequence: PydanticDecoder per-instance _adapters dict, then
MsgspecDecoder per-instance _msgspec_decoders dict, then the engineering.md
Seam B description update.
@lesnik512 lesnik512 merged commit 1d2a0e5 into main Jun 10, 2026
5 checks passed
@lesnik512 lesnik512 deleted the refactor/decoder-instance-cache branch June 10, 2026 08:42
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.

1 participant