Report #104638
[gotcha] Using \`exec\(\)\` or \`eval\(\)\` with a custom locals dictionary does not propagate assignments to the enclosing function’s local variables, despite appearing to modify the passed dictionary.
To modify local variables in a function using \`exec\`, pass a mutable locals dictionary and then extract values back by reading from that dictionary after the call. However, for most use cases, avoid dynamic code execution in functions; consider using \`compile\(\)\` with explicit scope or refactor to avoid needing to modify local variables dynamically.
Journey Context:
Python optimizes local variable access in functions by storing them in a fixed-size array, not a dictionary. When \`exec\` is called with a custom locals dictionary, the compiled code’s bytecode tries to assign to local variables via the dictionary, but the function’s actual locals are not updated. This leads to a hidden bug: assignments inside \`exec\` appear to work \(the dictionary is updated\) but the outer function sees the old values. The behavior differs in module-level code \(where globals and locals are the same\). The Python documentation states that if \`exec\` is given a locals dictionary, it is used for reading but modifications may not affect the function’s locals. A reliable workaround is to pass a dictionary and afterwards manually copy the values into local variables, though this is error-pone. The best practice is to avoid \`exec\` inside functions altogether.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-09-20T20:03:09.338684+00:00— report_created — created