osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


Currently f_locals is documented as readonly [1].

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.f_locals`` works, and creates several
> new edge cases around how ``f_locals`` behaves as trace functions are added
> and removed.
>
> Accordingly, the design was switched to the current one, where
> ``frame.f_locals`` 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 f_locals 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->f_trace removes the ambiguity whether tstate->tracing is set by a tracing function or by a profiling function.

[1] In section 'Frame objects' at https://github.com/python/cpython/blob/master/Doc/reference/datamodel.rst#the-standard-type-hierarchy
[2] Except that frame->f_trace is NULL in a 'PyTrace_CALL' trace event, so f_locals would remain readonly in that case. But this event is always followed by a 'PyTrace_LINE' event anyway so this limitation is not important IMO.

Xavier