Message296841
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: https://mail.python.org/pipermail/python-dev/2013-May/125917.html
(https://bugs.python.org/issue17960 is the corresponding issue, although I clearly got distracted by other things and never followed up with a patch for the language reference. https://bugs.python.org/issue17546 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:15 | ncoghlan | set | recipients:
+ ncoghlan, arigo, belopolsky, benjamin.peterson, njs, Mark.Shannon, yselivanov, xgdomingo |
2017-06-26 03:39:14 | ncoghlan | set | messageid: <1498448354.91.0.102551418553.issue30744@psf.upfronthosting.co.za> |
2017-06-26 03:39:14 | ncoghlan | link | issue30744 messages |
2017-06-26 03:39:12 | ncoghlan | create | |
|