@@ -287,8 +287,9 @@ returns a write-through proxy to the frame's local and locally referenced
287287nonlocal variables in these scopes, rather than returning an inconsistently
288288updated shared ``dict `` instance with undefined runtime semantics.
289289
290- See :pep: `667 ` for more details, including related C API changes and
291- deprecations.
290+ See :pep: `667 ` for more details, including related C API changes and deprecations. Porting
291+ notes are also provided below for the affected :ref: `Python APIs <pep667-porting-notes-py >`
292+ and :ref: `C APIs <pep667-porting-notes-c >`
292293
293294(PEP and implementation contributed by Mark Shannon and Tian Gao in
294295:gh: `74929 `. Documentation updates provided by Guido van Rossum and
@@ -2246,6 +2247,8 @@ Changes in the Python API
22462247 returned by :meth: `zipfile.ZipFile.open ` was changed from ``'r' `` to ``'rb' ``.
22472248 (Contributed by Serhiy Storchaka in :gh: `115961 `.)
22482249
2250+ .. _pep667-porting-notes-py :
2251+
22492252* Calling :func: `locals ` in an :term: `optimized scope ` now produces an
22502253 independent snapshot on each call, and hence no longer implicitly updates
22512254 previously returned references. Obtaining the legacy CPython behaviour now
@@ -2341,15 +2344,24 @@ Changes in the C API
23412344 to :c:func: `PyUnstable_Code_GetFirstFree `.
23422345 (Contributed by Bogdan Romanyuk in :gh: `115781 `.)
23432346
2344- * Calling :c:func: `PyFrame_GetLocals ` or :c:func: `PyEval_GetLocals ` in an
2345- :term: `optimized scope ` now returns a write-through proxy rather than a
2346- snapshot that gets updated at ill-specified times. If a snapshot is desired,
2347- it must be created explicitly (e.g. with :c:func: `PyDict_Copy `) or by calling
2348- the new :c:func: `PyEval_GetFrameLocals ` API. (Changed as part of :pep: `667 `.)
2347+ .. _pep667-porting-notes-c :
2348+
2349+ * The effects of mutating the dictionary returned from :c:func: `PyEval_GetLocals ` in an
2350+ :term: `optimized scope ` have changed. Changes made this way will now *only * be visible to
2351+ subsequent :c:func: `PyEval_GetLocals ` calls in that frame, as :c:func: `PyFrame_GetLocals `,
2352+ :func: `locals `, and :attr: `FrameType.f_locals <frame.f_locals> ` no longer access the same
2353+ underlying cached dictionary. The recommended code update depends on how the function was
2354+ being used, so refer to the deprecation notice on the function for details.
2355+ (Changed as part of :pep: `667 `.)
2356+
2357+ * Calling :c:func: `PyFrame_GetLocals ` in an :term: `optimized scope ` now returns a
2358+ write-through proxy rather than a snapshot that gets updated at ill-specified times.
2359+ If a snapshot is desired, it must be created explicitly (e.g. with :c:func: `PyDict_Copy `)
2360+ or by calling the new :c:func: `PyEval_GetFrameLocals ` API. (Changed as part of :pep: `667 `.)
23492361
23502362* :c:func: `!PyFrame_FastToLocals ` and :c:func: `!PyFrame_FastToLocalsWithError `
23512363 no longer have any effect. Calling these functions has been redundant since
2352- Python 3.11, when :c:func: `PyFrame_GetLocals ` was first introduced.
2364+ Python 3.11, when :c:func: `PyFrame_GetLocals ` was first introduced.
23532365 (Changed as part of :pep: `667 `.)
23542366
23552367* :c:func: `!PyFrame_LocalsToFast ` no longer has any effect. Calling this function
@@ -2509,6 +2521,11 @@ Deprecated C APIs
25092521 :c:func: `PyWeakref_GetRef ` on Python 3.12 and older.
25102522 (Contributed by Victor Stinner in :gh: `105927 `.)
25112523
2524+ * Deprecate the :c:func: `PyEval_GetBuiltins `, :c:func: `PyEval_GetGlobals `, and
2525+ :c:func: `PyEval_GetLocals ` functions, which return a :term: `borrowed reference `.
2526+ Refer to the deprecation notices on each function for their recommended replacements.
2527+ (Soft deprecated as part of :pep: `667 `.)
2528+
25122529Pending Removal in Python 3.14
25132530------------------------------
25142531
0 commit comments