From ef168c11ae30091039d5aecd2fdd22e832eedc35 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 7 Dec 2024 10:13:10 -0500 Subject: [PATCH 1/5] Docs: C API: Document frame locals proxies. --- Doc/c-api/frame.rst | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst index 638a740e0c24da..57151bdaca3ad3 100644 --- a/Doc/c-api/frame.rst +++ b/Doc/c-api/frame.rst @@ -132,7 +132,7 @@ See also :ref:`Reflection `. .. versionadded:: 3.11 .. versionchanged:: 3.13 - As part of :pep:`667`, return a proxy object for optimized scopes. + As part of :pep:`667`, return an instance of :c:var:`PyFrameLocalsProxy_Type`. .. c:function:: int PyFrame_GetLineNumber(PyFrameObject *frame) @@ -140,6 +140,31 @@ See also :ref:`Reflection `. Return the line number that *frame* is currently executing. +Frame Locals Proxies +^^^^^^^^^^^^^^^^^^^^ + +.. versionadded:: 3.13 + +In older versions of :term:`CPython`, the exposed local variables dictionary +(via :attr:`~frame.f_locals`, :c:func:`PyFrame_GetLocals`, or :func:`locals`) +wouldn't be consistent with the actual local variables, leading to all sorts of +weird issues. In 3.13, instead of using a dictionary to expose local variables, +a special proxy type is used instead, which retains consistency when manipulating +scopes. + +See :pep:`667` for more information. + +.. c:var:: PyTypeObject PyFrameLocalsProxy_Type + + The type of frame :func:`locals` proxy objects. + + .. versionadded:: 3.13 + +.. c:function:: int PyFrameLocalsProxy_Check(PyObject *obj) + + Return non-zero if *obj* is a frame :func:`locals` proxy. + + .. versionadded:: 3.13 Internal Frames ^^^^^^^^^^^^^^^ From 61662c046b007ee3108e8d23642fd44772f8e415 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 7 Dec 2024 11:14:31 -0500 Subject: [PATCH 2/5] Clarify 3.13 --- Doc/c-api/frame.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst index 57151bdaca3ad3..f483f3e7324b02 100644 --- a/Doc/c-api/frame.rst +++ b/Doc/c-api/frame.rst @@ -148,7 +148,7 @@ Frame Locals Proxies In older versions of :term:`CPython`, the exposed local variables dictionary (via :attr:`~frame.f_locals`, :c:func:`PyFrame_GetLocals`, or :func:`locals`) wouldn't be consistent with the actual local variables, leading to all sorts of -weird issues. In 3.13, instead of using a dictionary to expose local variables, +weird issues. In Python 3.13, instead of using a dictionary to expose local variables, a special proxy type is used instead, which retains consistency when manipulating scopes. From 86f7cdd68c239d219c7800ac7cad40532ecbecb9 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 7 Dec 2024 16:58:19 -0500 Subject: [PATCH 3/5] Minor change to wording. --- Doc/c-api/frame.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst index f483f3e7324b02..004ea80c44a601 100644 --- a/Doc/c-api/frame.rst +++ b/Doc/c-api/frame.rst @@ -147,10 +147,10 @@ Frame Locals Proxies In older versions of :term:`CPython`, the exposed local variables dictionary (via :attr:`~frame.f_locals`, :c:func:`PyFrame_GetLocals`, or :func:`locals`) -wouldn't be consistent with the actual local variables, leading to all sorts of -weird issues. In Python 3.13, instead of using a dictionary to expose local variables, -a special proxy type is used instead, which retains consistency when manipulating -scopes. +wasn't consistent with the actual local variables, which lead to all sorts of +weird issues. In Python 3.13, instead of using a dictionary to expose locals, +a special proxy type that retains consistency when manipulating +scopes is used. See :pep:`667` for more information. From 8ec995f618a2f56f3f1ca3b4a889f28f40e83503 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Mon, 9 Dec 2024 14:53:55 -0500 Subject: [PATCH 4/5] Update frame.rst Co-authored-by: Alex Waygood --- Doc/c-api/frame.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst index 004ea80c44a601..0d61996a72d85d 100644 --- a/Doc/c-api/frame.rst +++ b/Doc/c-api/frame.rst @@ -145,12 +145,11 @@ Frame Locals Proxies .. versionadded:: 3.13 -In older versions of :term:`CPython`, the exposed local variables dictionary -(via :attr:`~frame.f_locals`, :c:func:`PyFrame_GetLocals`, or :func:`locals`) -wasn't consistent with the actual local variables, which lead to all sorts of -weird issues. In Python 3.13, instead of using a dictionary to expose locals, -a special proxy type that retains consistency when manipulating -scopes is used. +The :attr:`~frame.f_locals` attribute on a :ref:`frame object ` +is an instance of a "frame-locals proxy". The proxy object exposes a +write-through view of the underlying locals dictionary for the frame. This +ensures that the variables exposed by ``f_locals`` are always up to date with +the live local variables in the frame itself. See :pep:`667` for more information. From 4fca5392bd6192d22a4bbaefabd9e64b48125b0d Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Wed, 11 Dec 2024 10:33:23 -0500 Subject: [PATCH 5/5] Remove redundant version added directive --- Doc/c-api/frame.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst index 0d61996a72d85d..1a52e146a69751 100644 --- a/Doc/c-api/frame.rst +++ b/Doc/c-api/frame.rst @@ -157,14 +157,10 @@ See :pep:`667` for more information. The type of frame :func:`locals` proxy objects. - .. versionadded:: 3.13 - .. c:function:: int PyFrameLocalsProxy_Check(PyObject *obj) Return non-zero if *obj* is a frame :func:`locals` proxy. - .. versionadded:: 3.13 - Internal Frames ^^^^^^^^^^^^^^^