mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
[3.13] gh-118888: Further PEP 667 docs updates (gh-119894)
* Clarify impact on default behaviour of exec, eval, etc
* Update documentation for changes to PyEval_GetLocals (gh-74929)
Closes gh-118888
(cherry picked from commit 2180991ea3
)
Co-authored-by: Alyssa Coghlan <ncoghlan@gmail.com>
This commit is contained in:
parent
edb6883ef3
commit
36ca00f44d
2 changed files with 44 additions and 3 deletions
|
@ -266,6 +266,21 @@ comprehensions, and generator expressions) to explicitly return independent
|
|||
snapshots of the currently assigned local variables, including locally
|
||||
referenced nonlocal variables captured in closures.
|
||||
|
||||
This change to the semantics of :func:`locals` in optimized scopes also affects the default
|
||||
behaviour of code execution functions that implicitly target ``locals()`` if no explicit
|
||||
namespace is provided (such as :func:`exec` and :func:`eval`). In previous versions, whether
|
||||
or not changes could be accessed by calling ``locals()`` after calling the code execution
|
||||
function was implementation dependent. In CPython specifically, such code would typically
|
||||
appear to work as desired, but could sometimes fail in optimized scopes based on other code
|
||||
(including debuggers and code execution tracing tools) potentially resetting the shared
|
||||
snapshot in that scope. Now, the code will always run against an independent snapshot of the
|
||||
local variables in optimized scopes, and hence the changes will never be visible in
|
||||
subsequent calls to ``locals()``. To access the changes made in these cases, an explicit
|
||||
namespace reference must now be passed to the relevant function. Alternatively, it may make
|
||||
sense to update affected code to use a higher level code execution API that returns the
|
||||
resulting code execution namespace (e.g. :func:`runpy.run_path` when executing Python
|
||||
files from disk).
|
||||
|
||||
To ensure debuggers and similar tools can reliably update local variables in
|
||||
scopes affected by this change, :attr:`FrameType.f_locals <frame.f_locals>` now
|
||||
returns a write-through proxy to the frame's local and locally referenced
|
||||
|
@ -2223,7 +2238,10 @@ Changes in the Python API
|
|||
independent snapshot on each call, and hence no longer implicitly updates
|
||||
previously returned references. Obtaining the legacy CPython behaviour now
|
||||
requires explicit calls to update the initially returned dictionary with the
|
||||
results of subsequent calls to ``locals()``. (Changed as part of :pep:`667`.)
|
||||
results of subsequent calls to ``locals()``. Code execution functions that
|
||||
implicitly target ``locals()`` (such as ``exec`` and ``eval``) must be
|
||||
passed an explicit namespace to access their results in an optimized scope.
|
||||
(Changed as part of :pep:`667`.)
|
||||
|
||||
* Calling :func:`locals` from a comprehension at module or class scope
|
||||
(including via ``exec`` or ``eval``) once more behaves as if the comprehension
|
||||
|
@ -2311,6 +2329,12 @@ Changes in the C API
|
|||
to :c:func:`PyUnstable_Code_GetFirstFree`.
|
||||
(Contributed by Bogdan Romanyuk in :gh:`115781`.)
|
||||
|
||||
* Calling :c:func:`PyFrame_GetLocals` or :c:func:`PyEval_GetLocals` in an
|
||||
:term:`optimized scope` now returns a write-through proxy rather than a
|
||||
snapshot that gets updated at ill-specified times. If a snapshot is desired,
|
||||
it must be created explicitly (e.g. with :c:func:`PyDict_Copy`) or by calling
|
||||
the new :c:func:`PyEval_GetFrameLocals` API. (Changed as part of :pep:`667`.)
|
||||
|
||||
* :c:func:`!PyFrame_FastToLocals` and :c:func:`!PyFrame_FastToLocalsWithError`
|
||||
no longer have any effect. Calling these functions has been redundant since
|
||||
Python 3.11, when :c:func:`PyFrame_GetLocals` was first introduced.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue