PEP 558: Update for conversation with Guido
- new open questions around how storage and updates will work - note that we definitely *don't* want to return the write-through proxy from locals() at function scope
This commit is contained in:
parent
a6d74b181c
commit
94e6606edb
63
pep-0558.rst
63
pep-0558.rst
|
@ -125,6 +125,55 @@ function locals).
|
||||||
Open Questions
|
Open Questions
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
Allowing local variable binding mutation outside trace functions
|
||||||
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
This PEP allows local variable bindings to be mutated whenever code has access
|
||||||
|
to the frame object - it doesn't restrict that ability to trace functions the
|
||||||
|
way the status quo does.
|
||||||
|
|
||||||
|
It does this since it wants to allow trace functions to make changes, while
|
||||||
|
removing the current bulk copy from ``f_locals`` back to the frame state when
|
||||||
|
the trace function returns.
|
||||||
|
|
||||||
|
An alternative approach might be to *temporarily* replace ``f_locals`` with
|
||||||
|
a write-through proxy while the trace function is running, and then swap it
|
||||||
|
back to the result of ``locals()`` when the trace function returns.
|
||||||
|
|
||||||
|
|
||||||
|
Where is the new ``locals()`` result stored?
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
If ``locals()`` is a new mapping distinct from the write-through proxy stored in
|
||||||
|
``frame.f_locals``, where will that mapping be stored?
|
||||||
|
|
||||||
|
A new lazily initialised frame attribute seems like a plausible answer, but that
|
||||||
|
raises new questions around how that attribute will be managed for module and
|
||||||
|
class scopes (set to the same thing as ``f_locals``? Set to ``NULL``/``None``?)
|
||||||
|
|
||||||
|
Alternatively, it could be stored in ``f_locals`` most of the time (as it is
|
||||||
|
today), and have the write-through proxy stored in a separate lazily
|
||||||
|
initialised attribute that gets swapped in as ``f_locals`` only when calling
|
||||||
|
trace functions.
|
||||||
|
|
||||||
|
|
||||||
|
What happens with the default args for ``eval()`` and ``exec()``?
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
These are formally defined as inheriting ``globals()`` and ``locals()`` from
|
||||||
|
the calling scope by default.
|
||||||
|
|
||||||
|
There doesn't seem to be any reason for the PEP to change this.
|
||||||
|
|
||||||
|
|
||||||
|
Does mutating the ``f_locals`` proxy refresh the ``locals()`` mapping?
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
This is probably needed in order to retain the current behaviour where writes
|
||||||
|
to ``frame.f_locals`` are immediately visible via references obtained via
|
||||||
|
``locals()``.
|
||||||
|
|
||||||
|
|
||||||
How much compatibility is enough compatibility?
|
How much compatibility is enough compatibility?
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
|
|
||||||
|
@ -227,6 +276,20 @@ This proposal deliberately *doesn't* formalise these semantics as is, since they
|
||||||
only make sense in terms of the historical evolution of the language and the
|
only make sense in terms of the historical evolution of the language and the
|
||||||
reference implementation, rather than being deliberately designed.
|
reference implementation, rather than being deliberately designed.
|
||||||
|
|
||||||
|
Rejected Alternatives
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Making ``locals()`` return the write-through proxy directly
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
A number of changes have been made to ``locals()`` over the years to
|
||||||
|
deliberately make it *harder* for arbitrary code to mutate function local
|
||||||
|
variables without those changes being visible to the compiler at compile time.
|
||||||
|
|
||||||
|
As such the desired default semantics for ``locals()`` are those currently
|
||||||
|
seen when a tracing function *isn't* installed, rather than the mutating
|
||||||
|
behaviour currently seen when a tracing hook is installed.
|
||||||
|
|
||||||
|
|
||||||
Implementation
|
Implementation
|
||||||
==============
|
==============
|
||||||
|
|
Loading…
Reference in New Issue