Nick Coghlan <ncogh...@gmail.com> added the comment:

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.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue30744>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to