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, gvanrossum, ncoghlan, njs, xdegaye, xgdomingo, yselivanov
Date 2017-10-14.05:56:15
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1507960577.9.0.213398074469.issue30744@psf.upfronthosting.co.za>
In-reply-to
Content
Yep, my current goal is to see if I can come up with a surgical fix that solves the established problem with the bad interaction between cells and trace functions without any unintended consequences for either CPython or other interpreters.

That means the only behaviours I actually *want* to change are those that are pretty clearly quirky at best, and outright bugs at worst:

- registering a trace function can result in closure state being reset inappropriately, even when none of the code involved accesses locals() or f_locals
- registering a trace function may lead to changes to locals() made outside the trace function nevertheless being written back to the actual frame state

Establishing a write-through proxy for cell references is definitely fine - allowing shared access to closure state is the whole reason we have cell objects in the first place.

The more complex case is with regular locals since:

- they used to be regular dictionaries in 1.x, but one of the early 2.x releases deliberately changed their semantics with the introduction of fast locals
- people *do* sometimes treat the result of locals() at function scope as a regular dictionary, and hence they don't always copy it before mutating it and/or returning a reference to it
- f_locals is accessible from outside the running function/generator/coroutine, so compilers can't just key off calls to locals() inside the function to decide whether or not they can see all changes to local variables
- looking for calls to locals() at compile time is dubious anyway, since the builtin may have been aliased under a different name (we do something like that for zero-arg super(), but that breaks far more obviously when the use of name aliasing prevents the compiler from detecting that you need a __class__ reference compiled in)
- trace functions nevertheless still need to be able to write their changes back to the function locals in order for debuggers to support value injection

My latest design concept for the trace proxy thus looks like this (I've been iterating on design ideas to try to reduce the potential memory impact arising from merely installing a trace function):

1. The core proxy behaviour would be akin to wrapping f_locals in types.MappingProxyType (and I expect the new proxy will be a subclass of that existing type, with the tentative name "_FunctionLocalsProxy")

2. The currently planned differences consist of the following:
- setting and deleting items is supported
- holding a reference back to the originating frame (to allow for lazy initialisation of the extra state only if the local variables are actually mutated through the proxy)
- when a cell variable is mutated through the proxy, the cell gets added to a lazily constructed mapping from names to cells (if it isn't already there), and the value in the cell is also modified
- when a local variable is mutated through the proxy, it gets added to a set of "pending writebacks"

The post-traceback frame update in the trampoline function would then write back only the locals registered in "pending writebacks" (i.e. only those changes made through the proxy, *not* any incidental changes made directly to the result of locals()), which would allow this change to reduce the potential local state manipulation side effects of registering a trace function.

If actual implementation shows that this approach faces some technical hurdle that makes it infeasible in practice, then I agree it would make sense for us to look at alternatives with higher risks of unwanted side effects. However, based on what I learned while writing the first draft of PEP 558, I'm currently fairly optimistic I'll be able to make the idea work.
History
Date User Action Args
2017-10-14 05:56:18ncoghlansetrecipients: + ncoghlan, gvanrossum, arigo, belopolsky, benjamin.peterson, njs, xdegaye, Mark.Shannon, yselivanov, xgdomingo
2017-10-14 05:56:17ncoghlansetmessageid: <1507960577.9.0.213398074469.issue30744@psf.upfronthosting.co.za>
2017-10-14 05:56:17ncoghlanlinkissue30744 messages
2017-10-14 05:56:15ncoghlancreate