On Thu, Aug 26, 2021 at 1:29 AM Nick Coghlan <ncoghlan@gmail.com> wrote:
On Mon, 23 Aug 2021 at 13:07, Guido van Rossum <guido@python.org> wrote:
> But... I also care about backwards compatibility, and I have a crazy idea for making PyEval_GetLocals() work in a useful manner without compromising the behavior of the f_locals proxy:
>
> [snip]

I don't think any of this is crazy, as it's how the PEP 558 reference
implementation already works for individual keys

I'm not sure I understand what it means to be like my idea "for individual keys". But I'm not sure I care.

(aside from only
having a documented deprecation of PyEval_GetLocals(), not a
programmatic one)

Yeah, that's a detail. The deprecation could start out silent.
 
You don't need to eliminate the cache (and hence break compatibility
with PyEval_GetLocals()) to ensure it can never get out of sync - you
just have to resync it every time you use it, rather than allowing the
frame API consumer to make that call.

I don't think eliminating the cache part is breaking compatibility.
 
The reason I don't like the proxy semantics proposed in PEP 667 is
because it either makes the common case (analysing a frame from a
tracing function while no application code is running) slower in order
to avoid having to worry about cache consistency when trying to
analyse a running frame, or else we have to write and maintain a whole
lot more fast locals proxy specific code to implement the 5 different
dict iteration APIs.

I just think it's weird to write a long PEP to clean up the semantics and then replace it with such a complicated solution.
 
> PS. The mapping from varname to position should be on the code object, not on the frame. This is how Mark does it (though his implementation would need to be extended to take cells into account).

It's taking cells into account that forces the lookup mapping to be on
the frame: different executions of the same code object may reference
different cell objects.

But the frame stores the cells at known positions (after all, the index is embedded in the bytecode). YOu just need to interpret the mapping a bit differently.

--
--Guido van Rossum (python.org/~guido)