This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author ncoghlan
Recipients Mark.Shannon, arigo, belopolsky, benjamin.peterson, ncoghlan, njs, xgdomingo, yselivanov
Date 2017-06-26.03:39:12
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
Sorry, I wasn't clear: I don't see any problem for the cases that don't optimize local variable access, and don't think any of those should change.

Instead, I think we should tighten up the formal specification of locals() to better match how it is actually used in practice:

( is the corresponding issue, although I clearly got distracted by other things and never followed up with a patch for the language reference. is another issue lamenting the current underspecification in this area)

However, function bodiess are already inherently different from other execution namespaces, and that stems from a particular special case assumption that we don't make anywhere else: we assume that at compile time, the compiler can see all of the names added to the local namespace of a function.

That assumption wasn't quite valid in Python 2 (since unqualified exec statements and function level wildcard imports could mess with it), but it's much closer to being true in Python 3.

Checking the 3.7 code, the only remaining ways to trigger it are:

- via a tracing function (since LocalsToFast gets called after the tracing function runs)
- by injecting an IMPORT_STAR opcode into a function code object (the compiler disallows that in Python 3 and emits a SyntaxWarning for it in Python 2, but the LocalsToFast call is still there in the eval loop)

So I think an entirely valid way forward here would be to delete LocalsToFast in 3.7+, and say that if you want to write access to a function namespace from outside the function, you need to either implement an eval hook (not just a tracing hook), or else use a closure that closes over all the variables that you want write access to.

However, the less drastic way forward would be to make it so that writing a tracing function is the only way to get access to the FastToLocals result, and have locals() on a frame running a code object compiled for fast locals return f->f_locals.copy() rather than a direct reference to the original.
Date User Action Args
2017-06-26 03:39:15ncoghlansetrecipients: + ncoghlan, arigo, belopolsky, benjamin.peterson, njs, Mark.Shannon, yselivanov, xgdomingo
2017-06-26 03:39:14ncoghlansetmessageid: <>
2017-06-26 03:39:14ncoghlanlinkissue30744 messages
2017-06-26 03:39:12ncoghlancreate