mirror of https://github.com/python/cpython
[3.13] gh-118934: Fix PyEval_GetLocals docs (PEP 667) (GH-119934)
PEP 667's description of the planned changes to PyEval_GetLocals
was internally inconsistent when accepted, so the docs added for
gh-74929 didn't match either the current behaviour or the intended
behaviour once gh-118934 is fixed.
This PR updates the documentation and 3.13 What's New to match the
intended behaviour (once gh-118934 is fixed).
It also tidies up lingering references to `f_locals` always being a
dictionary (this hasn't been true since at least when custom
namespace support for class statement execution was added)
(cherry picked from commit fd6cd621e0
)
Co-authored-by: Alyssa Coghlan <ncoghlan@gmail.com>
This commit is contained in:
parent
36ca00f44d
commit
cf8f292a36
|
@ -19,23 +19,28 @@ Reflection
|
||||||
|
|
||||||
.. deprecated:: 3.13
|
.. deprecated:: 3.13
|
||||||
|
|
||||||
To avoid creating a reference cycle in :term:`optimized scopes <optimized scope>`,
|
Use either :c:func:`PyEval_GetFrameLocals` to obtain the same behaviour as calling
|
||||||
use either :c:func:`PyEval_GetFrameLocals` to obtain the same behaviour as calling
|
|
||||||
:func:`locals` in Python code, or else call :c:func:`PyFrame_GetLocals` on the result
|
:func:`locals` in Python code, or else call :c:func:`PyFrame_GetLocals` on the result
|
||||||
of :c:func:`PyEval_GetFrame` to get the same result as this function without having to
|
of :c:func:`PyEval_GetFrame` to access the :attr:`~frame.f_locals` attribute of the
|
||||||
cache the proxy instance on the underlying frame.
|
currently executing frame.
|
||||||
|
|
||||||
Return the :attr:`~frame.f_locals` attribute of the currently executing frame,
|
Return a mapping providing access to the local variables in the current execution frame,
|
||||||
or ``NULL`` if no frame is currently executing.
|
or ``NULL`` if no frame is currently executing.
|
||||||
|
|
||||||
If the frame refers to an :term:`optimized scope`, this returns a
|
Refer to :func:`locals` for details of the mapping returned at different scopes.
|
||||||
write-through proxy object that allows modifying the locals.
|
|
||||||
In all other cases (classes, modules, :func:`exec`, :func:`eval`) it returns
|
As this function returns a :term:`borrowed reference`, the dictionary returned for
|
||||||
the mapping representing the frame locals directly (as described for
|
:term:`optimized scopes <optimized scope>` is cached on the frame object and will remain
|
||||||
:func:`locals`).
|
alive as long as the frame object does. Unlike :c:func:`PyEval_GetFrameLocals` and
|
||||||
|
:func:`locals`, subsequent calls to this function in the same frame will update the
|
||||||
|
contents of the cached dictionary to reflect changes in the state of the local variables
|
||||||
|
rather than returning a new snapshot.
|
||||||
|
|
||||||
.. versionchanged:: 3.13
|
.. versionchanged:: 3.13
|
||||||
As part of :pep:`667`, return a proxy object for optimized scopes.
|
As part of :pep:`667`, :c:func:`PyFrame_GetLocals`, :func:`locals`, and
|
||||||
|
:attr:`FrameType.f_locals <frame.f_locals>` no longer make use of the shared cache
|
||||||
|
dictionary. Refer to the :ref:`What's New entry <whatsnew313-locals-semantics>` for
|
||||||
|
additional details.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyEval_GetGlobals(void)
|
.. c:function:: PyObject* PyEval_GetGlobals(void)
|
||||||
|
|
|
@ -1344,13 +1344,13 @@ Special read-only attributes
|
||||||
``object.__getattr__`` with arguments ``obj`` and ``"f_code"``.
|
``object.__getattr__`` with arguments ``obj`` and ``"f_code"``.
|
||||||
|
|
||||||
* - .. attribute:: frame.f_locals
|
* - .. attribute:: frame.f_locals
|
||||||
- The dictionary used by the frame to look up
|
- The mapping used by the frame to look up
|
||||||
:ref:`local variables <naming>`.
|
:ref:`local variables <naming>`.
|
||||||
If the frame refers to an :term:`optimized scope`,
|
If the frame refers to an :term:`optimized scope`,
|
||||||
this may return a write-through proxy object.
|
this may return a write-through proxy object.
|
||||||
|
|
||||||
.. versionchanged:: 3.13
|
.. versionchanged:: 3.13
|
||||||
Return a proxy for functions and comprehensions.
|
Return a proxy for optimized scopes.
|
||||||
|
|
||||||
* - .. attribute:: frame.f_globals
|
* - .. attribute:: frame.f_globals
|
||||||
- The dictionary used by the frame to look up
|
- The dictionary used by the frame to look up
|
||||||
|
|
|
@ -287,8 +287,9 @@ returns a write-through proxy to the frame's local and locally referenced
|
||||||
nonlocal variables in these scopes, rather than returning an inconsistently
|
nonlocal variables in these scopes, rather than returning an inconsistently
|
||||||
updated shared ``dict`` instance with undefined runtime semantics.
|
updated shared ``dict`` instance with undefined runtime semantics.
|
||||||
|
|
||||||
See :pep:`667` for more details, including related C API changes and
|
See :pep:`667` for more details, including related C API changes and deprecations. Porting
|
||||||
deprecations.
|
notes are also provided below for the affected :ref:`Python APIs <pep667-porting-notes-py>`
|
||||||
|
and :ref:`C APIs <pep667-porting-notes-c>`.
|
||||||
|
|
||||||
(PEP and implementation contributed by Mark Shannon and Tian Gao in
|
(PEP and implementation contributed by Mark Shannon and Tian Gao in
|
||||||
:gh:`74929`. Documentation updates provided by Guido van Rossum and
|
:gh:`74929`. Documentation updates provided by Guido van Rossum and
|
||||||
|
@ -2234,6 +2235,8 @@ Changes in the Python API
|
||||||
returned by :meth:`zipfile.ZipFile.open` was changed from ``'r'`` to ``'rb'``.
|
returned by :meth:`zipfile.ZipFile.open` was changed from ``'r'`` to ``'rb'``.
|
||||||
(Contributed by Serhiy Storchaka in :gh:`115961`.)
|
(Contributed by Serhiy Storchaka in :gh:`115961`.)
|
||||||
|
|
||||||
|
.. _pep667-porting-notes-py:
|
||||||
|
|
||||||
* Calling :func:`locals` in an :term:`optimized scope` now produces an
|
* Calling :func:`locals` in an :term:`optimized scope` now produces an
|
||||||
independent snapshot on each call, and hence no longer implicitly updates
|
independent snapshot on each call, and hence no longer implicitly updates
|
||||||
previously returned references. Obtaining the legacy CPython behaviour now
|
previously returned references. Obtaining the legacy CPython behaviour now
|
||||||
|
@ -2329,15 +2332,27 @@ Changes in the C API
|
||||||
to :c:func:`PyUnstable_Code_GetFirstFree`.
|
to :c:func:`PyUnstable_Code_GetFirstFree`.
|
||||||
(Contributed by Bogdan Romanyuk in :gh:`115781`.)
|
(Contributed by Bogdan Romanyuk in :gh:`115781`.)
|
||||||
|
|
||||||
* Calling :c:func:`PyFrame_GetLocals` or :c:func:`PyEval_GetLocals` in an
|
.. _pep667-porting-notes-c:
|
||||||
: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,
|
* The effects of mutating the dictionary returned from :c:func:`PyEval_GetLocals` in an
|
||||||
it must be created explicitly (e.g. with :c:func:`PyDict_Copy`) or by calling
|
:term:`optimized scope` have changed. New dict entries added this way will now *only* be
|
||||||
the new :c:func:`PyEval_GetFrameLocals` API. (Changed as part of :pep:`667`.)
|
visible to subsequent :c:func:`PyEval_GetLocals` calls in that frame, as
|
||||||
|
:c:func:`PyFrame_GetLocals`, :func:`locals`, and
|
||||||
|
:attr:`FrameType.f_locals <frame.f_locals>` no longer access the same underlying cached
|
||||||
|
dictionary. Changes made to entries for actual variable names and names added via the
|
||||||
|
write-through proxy interfaces will be overwritten on subsequent calls to
|
||||||
|
:c:func:`PyEval_GetLocals` in that frame. The recommended code update depends on how the
|
||||||
|
function was being used, so refer to the deprecation notice on the function for details.
|
||||||
|
(Changed as part of :pep:`667`.)
|
||||||
|
|
||||||
|
* Calling :c:func:`PyFrame_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`
|
* :c:func:`!PyFrame_FastToLocals` and :c:func:`!PyFrame_FastToLocalsWithError`
|
||||||
no longer have any effect. Calling these functions has been redundant since
|
no longer have any effect. Calling these functions has been redundant since
|
||||||
Python 3.11, when :c:func:`PyFrame_GetLocals` was first introduced.
|
Python 3.11, when :c:func:`PyFrame_GetLocals` was first introduced.
|
||||||
(Changed as part of :pep:`667`.)
|
(Changed as part of :pep:`667`.)
|
||||||
|
|
||||||
* :c:func:`!PyFrame_LocalsToFast` no longer has any effect. Calling this function
|
* :c:func:`!PyFrame_LocalsToFast` no longer has any effect. Calling this function
|
||||||
|
@ -2497,6 +2512,11 @@ Deprecated C APIs
|
||||||
:c:func:`PyWeakref_GetRef` on Python 3.12 and older.
|
:c:func:`PyWeakref_GetRef` on Python 3.12 and older.
|
||||||
(Contributed by Victor Stinner in :gh:`105927`.)
|
(Contributed by Victor Stinner in :gh:`105927`.)
|
||||||
|
|
||||||
|
* Deprecate the :c:func:`PyEval_GetBuiltins`, :c:func:`PyEval_GetGlobals`, and
|
||||||
|
:c:func:`PyEval_GetLocals` functions, which return a :term:`borrowed reference`.
|
||||||
|
Refer to the deprecation notices on each function for their recommended replacements.
|
||||||
|
(Soft deprecated as part of :pep:`667`.)
|
||||||
|
|
||||||
Pending Removal in Python 3.14
|
Pending Removal in Python 3.14
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue