You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf: replace defensive deepcopy with deep_freeze immutability
expand_language_extensions was deep-copying the template 4-10 times per
invocation for defensive isolation (cache put, cache get, no-LE path,
LE path). For large templates this is measurable overhead.
Replace with a one-time deep_freeze that converts dicts to
MappingProxyType and lists to tuples. Frozen templates are truly
immutable — any mutation attempt raises TypeError immediately instead
of silently corrupting shared state. Callers that need mutable copies
use deep_thaw (not copy.deepcopy which cannot pickle MappingProxyType
on Python 3.13).
Savings:
- No-LE fast path: 4 deepcopies -> 1 deep_freeze (same O(n) cost)
- Cache hit: 2 deepcopies -> 0 (return cached frozen result directly)
- Cold LE path: 3 deepcopies -> 2 deep_freezes (expanded + original)
- Cache put: 2 deepcopies -> 0 (frozen values are safe to share)
Also:
- Fixed isinstance(x, dict) check in build_context to accept Mapping
so frozen MappingProxyType templates pass the type check.
- Updated callers (build_context, package_context, artifact_exporter,
language_extensions_packaging, wrapper) to use deep_thaw instead of
copy.deepcopy when they need mutable copies.
- Updated tests to verify immutability contract (TypeError on mutation)
instead of asserting independent mutable copies.
0 commit comments