[Python-Dev] PEP 558: Defined semantics for locals() (original) (raw)

Nick Coghlan ncoghlan at gmail.com
Thu May 30 19:06:37 EDT 2019


On Fri., 31 May 2019, 5:20 am Xavier de Gaye, <xdegaye at gmail.com> wrote:

Currently flocals is documented as readonly [1].

Read-only in the sense that you can't rebind it to point to a different object - the dict it points to is mutable.

The PEP says: > * "Don't change what isn't broken": the current tracing mode problems are caused > by a requirement that's specific to tracing mode (support for external > rebinding of function local variable references), so it made sense to also > restrict any related fixes to tracing mode > > However, actually attempting to implement and document that dynamic approach > highlighted the fact that it makes for a really subtle runtime state dependent > behaviour distinction in how frame.flocals works, and creates several > new edge cases around how flocals behaves as trace functions are added > and removed. > > Accordingly, the design was switched to the current one, where > frame.flocals is always a write-through proxy, and locals() is always > a dynamic snapshot, which is both simpler to implement and easier to explain.

Do these edge cases still exist when flocals write access is restricted to code executed by the tracing function (which is more restrictive than 'tracing mode') ?

We can use the condition frame->f_trace not NULL and tstate->tracing true

(tstate being a pointer to the PyThreadState structure) to know when code is executed by the tracing function [2]: * The condition on tstate->tracing allows to figure out if we are running a frame executed by the trace function as opposed to a frame that is being traced or a frame executed in 'regular operation'. * The condition on frame->ftrace removes the ambiguity whether tstate->tracing is set by a tracing function or by a profiling function.

Always creating the proxy and sometimes bypassing it and returning the snapshot instead would indeed have fewer edge cases than sometimes storing the snapshot directly on the frame object without creating the proxy at all.

It's still significantly harder to document than "frame.f_locals references a proxy, locals() creates a snapshot", though.

Cheers, Nick.

-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20190531/9e2644e4/attachment.html>



More information about the Python-Dev mailing list