Unfortunately, the simplifications you propose would be backwards incompatible - it's existing behaviour that there's a real shared dict (even on optimised frames) where arbitrary extra attributes can be stored (even though they don't become accessible as Python variables). I don't want to make frame objects any bigger than they already are, so the natural solution is to store the mapping proxy as `f_locals`, and then bypass the proxy in order to make `PyEval_GetLocals` still "work" (at least as well as it ever did).
PyObject_GetAttr(string) also doesn't do that same thing as the proposed C functions, since it invokes the Python descriptor machinery. (Note that the discussion at https://discuss.python.org/t/pep-558-defined-semantics-for-locals/2936/ is more up to date than the PEP text where the C API is concerned)
The reference to tracing mode dependent semantics puzzles me, as that was removed in December: https://github.com/python/peps/commit/54888058ce8ad5257114652d9b41e8d1237b8e...
On Wed, 22 Jan 2020 at 21:59, Mark Shannon firstname.lastname@example.org wrote:
First of all I want to say that I'm very much in favour of the general idea behind PEP 558. Defined semantics is always better than undefined semantics :)
However, I think there are a few changes needed:
Don't add anything to the C API, please. Frame attributes can be accessed via `PyObject_GetAttr[String]`.
Don't make the behaviour dependent on whether "tracing" is turned on. Doing so forces debuggers to use sys.settrace which is horribly
slow. It also makes the implementation more complex, and has no benefit AFAICT.
- Don't store write-through proxies in the frame, but make proxies
retain a reference to the frame. This would reduce the size and complexity of code for handling frames. Clean up of the frame would occur naturally via reference count when all proxies have been reclaimed.
The proposed implementation is hard to reason about and I am not confident that it will not introduce some new subtle bugs to replace the ones it seeks to remove. Any implementation that has functions with "Borrow" and "BreakCycles" in their names makes me nervous.
A simpler conceptual model, which I believe could be made reliable, would be:
No change for non-function frames (as PEP 558 currently proposes).
Each access to `frame.f_locals` (for function frames) should return a new proxy object.
This proxy object would have dict-like, write-through semantics for variables in the frame. For keys that do not match variable names, an exception would be raised. This means that all proxies for a single frame will have value equivalence; object equivalence is not needed. I.e. for a frame `f`, `f.f_locals == f.f_locals` would be True, even though `f.f_locals is f.f_locals` would be False.
Cheers, Mark. _______________________________________________ Python-Dev mailing list -- email@example.com To unsubscribe send an email to firstname.lastname@example.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://email@example.com/message/TSHCB4ZH... Code of Conduct: http://python.org/psf/codeofconduct/