The chaotic locals() and how we fixed it
summary
Python changes local-variable semantics with PEP 667: locals() returns a fresh snapshot dict so reads never implicitly mutate fast locals and repeated calls return new dicts, while frame.f_locals becomes a write-through proxy that immediately updates the underlying C-array locals so debuggers can exec and mutate reliably. The implementation replaces ad hoc fast-to-locals hacks that caused PDB commands like ll to revert edits and it lands in CPython, removing the surprising behaviors that broke real debugger workflows.
AI-written summary · about
chapters (13)
- 0:00Introduction
- 1:10First bug in CPython
- 3:21Python local scope history
- 5:50Fast locals in CPython
- 8:03Broken locals and fast locals
- 11:15Exec and locals behavior
- 14:26Debugger challenges
- 18:23Locals behavior needs fixing
- 19:45PEP 667 goals
- 20:26PEP 667 semantics
- 21:11Frame.f locals proxy
- 23:21Debugger improvements
- 24:50Q&A with Mark Shannon
related talks
26mWhat not to do, and how to do it
28mWhat makes a Python debugger possible and how can we make it 100x faster
52mCombining Embedded and Interactive Python in a Debugger: A Case Study
24mPython Peculiarities
52mCombining Embedded and Interactive Python in a Debugger: A Case Study
42mOptimizing Code Performance for Python Internals
05mThe Craziest fn Thing I've Ever Seen (and It Lives in CPython!!!)
27mPython Oddities Explained
