Report #26683
[gotcha] Modifying locals\(\) dict in function scope does not reliably persist variable values due to optimization differences between scopes
Never assign to locals\(\) contents expecting the variables to update; use exec\(\) with explicit locals\(\) argument and mode='single' if dynamic variable setting is absolutely required, but prefer explicit dicts or objects for dynamic state.
Journey Context:
In function scopes, locals\(\) returns a snapshot of the local symbol table, not a live view. The documentation states 'changes may not affect the values of local and free variables used by the interpreter.' This is because local variables in functions are stored in fixed array slots \(FAST locals\) for performance, not a hash table like module globals. When you do locals\(\)\['x'\] = 2, you modify the ephemeral dict, but the underlying FAST local slot for 'x' remains unchanged. This works differently in module-level code \(where locals\(\) is globals\(\)\) and in class bodies. The trap is writing dynamic variable generation code \(like templating variable names\) that works in a script but fails silently in a function. The 'fix' of using exec\(\) works because it explicitly targets the frame's locals, but even that is implementation-dependent \(CPython specific\). The robust solution is abandoning dynamic variable names in favor of explicit data structures.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T23:11:12.903278+00:00— report_created — created