Skip to content

Commit db64dae

Browse files
[3.13] gh-74929: PEP 667 general docs update (gh-119291)
* expand on What's New entry for PEP 667 (including porting notes) * define 'optimized scope' as a glossary term * cover comprehensions and generator expressions in locals() docs * review all mentions of "locals" in documentation (updating if needed) * review all mentions of "f_locals" in documentation (updating if needed) (cherry picked from commit e870c85) Co-authored-by: Alyssa Coghlan <[email protected]>
1 parent f7303cd commit db64dae

File tree

11 files changed

+163
-66
lines changed

11 files changed

+163
-66
lines changed

Doc/c-api/frame.rst

+6-5
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,18 @@ See also :ref:`Reflection <reflection>`.
121121
.. c:function:: PyObject* PyFrame_GetLocals(PyFrameObject *frame)
122122
123123
Get the *frame*'s :attr:`~frame.f_locals` attribute.
124-
If the frame refers to a function or comprehension, this returns
125-
a write-through proxy object that allows modifying the locals.
126-
In all other cases (classes, modules) it returns the :class:`dict`
127-
representing the frame locals directly.
124+
If the frame refers to an :term:`optimized scope`, this returns a
125+
write-through proxy object that allows modifying the locals.
126+
In all other cases (classes, modules, :func:`exec`, :func:`eval`) it returns
127+
the mapping representing the frame locals directly (as described for
128+
:func:`locals`).
128129
129130
Return a :term:`strong reference`.
130131
131132
.. versionadded:: 3.11
132133
133134
.. versionchanged:: 3.13
134-
Return a proxy object for functions and comprehensions.
135+
As part of :pep:`667`, return a proxy object for optimized scopes.
135136
136137
137138
.. c:function:: int PyFrame_GetLineNumber(PyFrameObject *frame)

Doc/glossary.rst

+9
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,15 @@ Glossary
889889
(methods). Also the ultimate base class of any :term:`new-style
890890
class`.
891891

892+
optimized scope
893+
A scope where target local variable names are reliably known to the
894+
compiler when the code is compiled, allowing optimization of read and
895+
write access to these names. The local namespaces for functions,
896+
generators, coroutines, comprehensions, and generator expressions are
897+
optimized in this fashion. Note: most interpreter optimizations are
898+
applied to all scopes, only those relying on a known set of local
899+
and nonlocal variable names are restricted to optimized scopes.
900+
892901
package
893902
A Python :term:`module` which can contain submodules or recursively,
894903
subpackages. Technically, a package is a Python module with a

Doc/library/code.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ build applications which provide an interactive interpreter prompt.
1818
This class deals with parsing and interpreter state (the user's namespace); it
1919
does not deal with input buffering or prompting or input file naming (the
2020
filename is always passed in explicitly). The optional *locals* argument
21-
specifies the dictionary in which code will be executed; it defaults to a newly
22-
created dictionary with key ``'__name__'`` set to ``'__console__'`` and key
23-
``'__doc__'`` set to ``None``.
21+
specifies a mapping to use as the namespace in which code will be executed;
22+
it defaults to a newly created dictionary with key ``'__name__'`` set to
23+
``'__console__'`` and key ``'__doc__'`` set to ``None``.
2424

2525

2626
.. class:: InteractiveConsole(locals=None, filename="<console>", local_exit=False)

Doc/library/functions.rst

+68-35
Original file line numberDiff line numberDiff line change
@@ -543,18 +543,19 @@ are always available. They are listed here in alphabetical order.
543543

544544
The *expression* argument is parsed and evaluated as a Python expression
545545
(technically speaking, a condition list) using the *globals* and *locals*
546-
dictionaries as global and local namespace. If the *globals* dictionary is
546+
mappings as global and local namespace. If the *globals* dictionary is
547547
present and does not contain a value for the key ``__builtins__``, a
548548
reference to the dictionary of the built-in module :mod:`builtins` is
549549
inserted under that key before *expression* is parsed. That way you can
550550
control what builtins are available to the executed code by inserting your
551551
own ``__builtins__`` dictionary into *globals* before passing it to
552-
:func:`eval`. If the *locals* dictionary is omitted it defaults to the
553-
*globals* dictionary. If both dictionaries are omitted, the expression is
552+
:func:`eval`. If the *locals* mapping is omitted it defaults to the
553+
*globals* dictionary. If both mappings are omitted, the expression is
554554
executed with the *globals* and *locals* in the environment where
555-
:func:`eval` is called. Note, *eval()* does not have access to the
555+
:func:`eval` is called. Note, *eval()* will only have access to the
556556
:term:`nested scopes <nested scope>` (non-locals) in the enclosing
557-
environment.
557+
environment if they are already referenced in the scope that is calling
558+
:func:`eval` (e.g. via a :keyword:`nonlocal` statement).
558559

559560
Example:
560561

@@ -587,6 +588,11 @@ are always available. They are listed here in alphabetical order.
587588

588589
The *globals* and *locals* arguments can now be passed as keywords.
589590

591+
.. versionchanged:: 3.13
592+
593+
The semantics of the default *locals* namespace have been adjusted as
594+
described for the :func:`locals` builtin.
595+
590596
.. index:: pair: built-in function; exec
591597

592598
.. function:: exec(source, /, globals=None, locals=None, *, closure=None)
@@ -612,9 +618,15 @@ are always available. They are listed here in alphabetical order.
612618

613619
.. note::
614620

615-
Most users should just pass a *globals* argument and never *locals*.
616-
If exec gets two separate objects as *globals* and *locals*, the code
617-
will be executed as if it were embedded in a class definition.
621+
When ``exec`` gets two separate objects as *globals* and *locals*, the
622+
code will be executed as if it were embedded in a class definition. This
623+
means functions and classes defined in the executed code will not be able
624+
to access variables assigned at the top level (as the "top level"
625+
variables are treated as class variables in a class definition).
626+
Passing a :class:`collections.ChainMap` instance as *globals* allows name
627+
lookups to be chained across multiple mappings without triggering this
628+
behaviour. Values assigned to top level names in the executed code can be
629+
retrieved by passing an empty dictionary as the first entry in the chain.
618630

619631
If the *globals* dictionary does not contain a value for the key
620632
``__builtins__``, a reference to the dictionary of the built-in module
@@ -635,7 +647,7 @@ are always available. They are listed here in alphabetical order.
635647
.. note::
636648

637649
The built-in functions :func:`globals` and :func:`locals` return the current
638-
global and local dictionary, respectively, which may be useful to pass around
650+
global and local namespace, respectively, which may be useful to pass around
639651
for use as the second and third argument to :func:`exec`.
640652

641653
.. note::
@@ -651,6 +663,11 @@ are always available. They are listed here in alphabetical order.
651663

652664
The *globals* and *locals* arguments can now be passed as keywords.
653665

666+
.. versionchanged:: 3.13
667+
668+
The semantics of the default *locals* namespace have been adjusted as
669+
described for the :func:`locals` builtin.
670+
654671

655672
.. function:: filter(function, iterable)
656673

@@ -1056,39 +1073,51 @@ are always available. They are listed here in alphabetical order.
10561073
variable names as the keys, and their currently bound references as the
10571074
values.
10581075

1059-
At module scope, as well as when using ``exec()`` or ``eval()`` with a
1060-
single namespace, this function returns the same namespace as ``globals()``.
1076+
At module scope, as well as when using :func:`exec` or :func:`eval` with
1077+
a single namespace, this function returns the same namespace as
1078+
:func:`globals`.
10611079

10621080
At class scope, it returns the namespace that will be passed to the
10631081
metaclass constructor.
10641082

10651083
When using ``exec()`` or ``eval()`` with separate local and global
1066-
namespaces, it returns the local namespace passed in to the function call.
1084+
arguments, it returns the local namespace passed in to the function call.
10671085

10681086
In all of the above cases, each call to ``locals()`` in a given frame of
10691087
execution will return the *same* mapping object. Changes made through
1070-
the mapping object returned from ``locals()`` will be visible as bound,
1071-
rebound, or deleted local variables, and binding, rebinding, or deleting
1072-
local variables will immediately affect the contents of the returned mapping
1073-
object.
1074-
1075-
At function scope (including for generators and coroutines), each call to
1076-
``locals()`` instead returns a fresh dictionary containing the current
1077-
bindings of the function's local variables and any nonlocal cell references.
1078-
In this case, name binding changes made via the returned dict are *not*
1079-
written back to the corresponding local variables or nonlocal cell
1080-
references, and binding, rebinding, or deleting local variables and nonlocal
1081-
cell references does *not* affect the contents of previously returned
1082-
dictionaries.
1088+
the mapping object returned from ``locals()`` will be visible as assigned,
1089+
reassigned, or deleted local variables, and assigning, reassigning, or
1090+
deleting local variables will immediately affect the contents of the
1091+
returned mapping object.
1092+
1093+
In an :term:`optimized scope` (including functions, generators, and
1094+
coroutines), each call to ``locals()`` instead returns a fresh dictionary
1095+
containing the current bindings of the function's local variables and any
1096+
nonlocal cell references. In this case, name binding changes made via the
1097+
returned dict are *not* written back to the corresponding local variables
1098+
or nonlocal cell references, and assigning, reassigning, or deleting local
1099+
variables and nonlocal cell references does *not* affect the contents
1100+
of previously returned dictionaries.
1101+
1102+
Calling ``locals()`` as part of a comprehension in a function, generator, or
1103+
coroutine is equivalent to calling it in the containing scope, except that
1104+
the comprehension's initialised iteration variables will be included. In
1105+
other scopes, it behaves as if the comprehension were running as a nested
1106+
function.
1107+
1108+
Calling ``locals()`` as part of a generator expression is equivalent to
1109+
calling it in a nested generator function.
1110+
1111+
.. versionchanged:: 3.12
1112+
The behaviour of ``locals()`` in a comprehension has been updated as
1113+
described in :pep:`709`.
10831114

10841115
.. versionchanged:: 3.13
1085-
In previous versions, the semantics of mutating the mapping object
1086-
returned from this function were formally undefined. In CPython
1087-
specifically, the mapping returned at function scope could be
1088-
implicitly refreshed by other operations, such as calling ``locals()``
1089-
again. Obtaining the legacy CPython behaviour now requires explicit
1090-
calls to update the initially returned dictionary with the results
1091-
of subsequent calls to ``locals()``.
1116+
As part of :pep:`667`, the semantics of mutating the mapping objects
1117+
returned from this function are now defined. The behavior in
1118+
:term:`optimized scopes <optimized scope>` is now as described above.
1119+
Aside from being defined, the behaviour in other scopes remains
1120+
unchanged from previous versions.
10921121

10931122

10941123
.. function:: map(function, iterable, *iterables)
@@ -1975,14 +2004,18 @@ are always available. They are listed here in alphabetical order.
19752004
:attr:`~object.__dict__` attributes (for example, classes use a
19762005
:class:`types.MappingProxyType` to prevent direct dictionary updates).
19772006

1978-
Without an argument, :func:`vars` acts like :func:`locals`. Note, the
1979-
locals dictionary is only useful for reads since updates to the locals
1980-
dictionary are ignored.
2007+
Without an argument, :func:`vars` acts like :func:`locals`.
19812008

19822009
A :exc:`TypeError` exception is raised if an object is specified but
19832010
it doesn't have a :attr:`~object.__dict__` attribute (for example, if
19842011
its class defines the :attr:`~object.__slots__` attribute).
19852012

2013+
.. versionchanged:: 3.13
2014+
2015+
The result of calling this function without an argument has been
2016+
updated as described for the :func:`locals` builtin.
2017+
2018+
19862019
.. function:: zip(*iterables, strict=False)
19872020

19882021
Iterate over several iterables in parallel, producing tuples with an item

Doc/library/pdb.rst

+13-9
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ The typical usage to inspect a crashed program is::
123123
0
124124
(Pdb)
125125

126+
.. versionchanged:: 3.13
127+
The implementation of :pep:`667` means that name assignments made via ``pdb``
128+
will immediately affect the active scope, even when running inside an
129+
:term:`optimized scope`.
130+
126131

127132
The module defines the following functions; each enters the debugger in a
128133
slightly different way:
@@ -579,18 +584,17 @@ can be overridden by the local file.
579584

580585
.. pdbcommand:: interact
581586

582-
Start an interactive interpreter (using the :mod:`code` module) whose global
583-
namespace contains all the (global and local) names found in the current
584-
scope. Use ``exit()`` or ``quit()`` to exit the interpreter and return to
585-
the debugger.
587+
Start an interactive interpreter (using the :mod:`code` module) in a new
588+
global namespace initialised from the local and global namespaces for the
589+
current scope. Use ``exit()`` or ``quit()`` to exit the interpreter and
590+
return to the debugger.
586591

587592
.. note::
588593

589-
Because interact creates a new global namespace with the current global
590-
and local namespace for execution, assignment to variables will not
591-
affect the original namespaces.
592-
However, modification to the mutable objects will be reflected in the
593-
original namespaces.
594+
As ``interact`` creates a new dedicated namespace for code execution,
595+
assignments to variables will not affect the original namespaces.
596+
However, modifications to any referenced mutable objects will be reflected
597+
in the original namespaces as usual.
594598

595599
.. versionadded:: 3.2
596600

Doc/library/profile.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ functions:
234234
.. function:: runctx(command, globals, locals, filename=None, sort=-1)
235235

236236
This function is similar to :func:`run`, with added arguments to supply the
237-
globals and locals dictionaries for the *command* string. This routine
237+
globals and locals mappings for the *command* string. This routine
238238
executes::
239239

240240
exec(command, globals, locals)

Doc/library/traceback.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ in a :ref:`traceback <traceback-objects>`.
473473
attribute accessed (which also happens when casting it to a :class:`tuple`).
474474
:attr:`~FrameSummary.line` may be directly provided, and will prevent line
475475
lookups happening at all. *locals* is an optional local variable
476-
dictionary, and if supplied the variable representations are stored in the
476+
mapping, and if supplied the variable representations are stored in the
477477
summary for later display.
478478

479479
:class:`!FrameSummary` instances have the following attributes:

Doc/reference/datamodel.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,7 @@ Special read-only attributes
13461346
* - .. attribute:: frame.f_locals
13471347
- The dictionary used by the frame to look up
13481348
:ref:`local variables <naming>`.
1349-
If the frame refers to a function or comprehension,
1349+
If the frame refers to an :term:`optimized scope`,
13501350
this may return a write-through proxy object.
13511351

13521352
.. versionchanged:: 3.13

Doc/whatsnew/3.13.rst

+51-4
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,11 @@ Interpreter improvements:
9494
Performance improvements are modest -- we expect to be improving this
9595
over the next few releases.
9696

97-
* :pep:`667`: :attr:`FrameType.f_locals <frame.f_locals>` when used in
98-
a function now returns a write-through proxy to the frame's locals,
99-
rather than a ``dict``. See the PEP for corresponding C API changes
100-
and deprecations.
97+
* :pep:`667`: The :func:`locals` builtin now has
98+
:ref:`defined semantics <whatsnew313-locals-semantics>` when mutating the
99+
returned mapping. Python debuggers and similar tools may now more reliably
100+
update local variables in optimized frames even during concurrent code
101+
execution.
101102

102103
New typing features:
103104

@@ -247,6 +248,34 @@ Improved Error Messages
247248
through ``self.X`` from any function in its body. (Contributed by Irit Katriel
248249
in :gh:`115775`.)
249250

251+
.. _whatsnew313-locals-semantics:
252+
253+
Defined mutation semantics for ``locals()``
254+
-------------------------------------------
255+
256+
Historically, the expected result of mutating the return value of :func:`locals`
257+
has been left to individual Python implementations to define.
258+
259+
Through :pep:`667`, Python 3.13 standardises the historical behaviour of CPython
260+
for most code execution scopes, but changes
261+
:term:`optimized scopes <optimized scope>` (functions, generators, coroutines,
262+
comprehensions, and generator expressions) to explicitly return independent
263+
snapshots of the currently assigned local variables, including locally
264+
referenced nonlocal variables captured in closures.
265+
266+
To ensure debuggers and similar tools can reliably update local variables in
267+
scopes affected by this change, :attr:`FrameType.f_locals <frame.f_locals>` now
268+
returns a write-through proxy to the frame's local and locally referenced
269+
nonlocal variables in these scopes, rather than returning an inconsistently
270+
updated shared ``dict`` instance with undefined runtime semantics.
271+
272+
See :pep:`667` for more details, including related C API changes and
273+
deprecations.
274+
275+
(PEP and implementation contributed by Mark Shannon and Tian Gao in
276+
:gh:`74929`. Documentation updates provided by Guido van Rossum and
277+
Alyssa Coghlan.)
278+
250279
Incremental Garbage Collection
251280
------------------------------
252281

@@ -2177,6 +2206,24 @@ Changes in the Python API
21772206
returned by :meth:`zipfile.ZipFile.open` was changed from ``'r'`` to ``'rb'``.
21782207
(Contributed by Serhiy Storchaka in :gh:`115961`.)
21792208

2209+
* Calling :func:`locals` in an :term:`optimized scope` now produces an
2210+
independent snapshot on each call, and hence no longer implicitly updates
2211+
previously returned references. Obtaining the legacy CPython behaviour now
2212+
requires explicit calls to update the initially returned dictionary with the
2213+
results of subsequent calls to ``locals()``. (Changed as part of :pep:`667`.)
2214+
2215+
* Calling :func:`locals` from a comprehension at module or class scope
2216+
(including via ``exec`` or ``eval``) once more behaves as if the comprehension
2217+
were running as an independent nested function (i.e. the local variables from
2218+
the containing scope are not included). In Python 3.12, this had changed
2219+
to include the local variables from the containing scope when implementing
2220+
:pep:`709`. (Changed as part of :pep:`667`.)
2221+
2222+
* Accessing :attr:`FrameType.f_locals <frame.f_locals>` in an
2223+
:term:`optimized scope` now returns a write-through proxy rather than a
2224+
snapshot that gets updated at ill-specified times. If a snapshot is desired,
2225+
it must be created explicitly with ``dict`` or the proxy's ``.copy()`` method.
2226+
(Changed as part of :pep:`667`.)
21802227

21812228
Changes in the C API
21822229
--------------------

Lib/code.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ class InteractiveInterpreter:
2525
def __init__(self, locals=None):
2626
"""Constructor.
2727
28-
The optional 'locals' argument specifies the dictionary in
29-
which code will be executed; it defaults to a newly created
30-
dictionary with key "__name__" set to "__console__" and key
31-
"__doc__" set to None.
28+
The optional 'locals' argument specifies a mapping to use as the
29+
namespace in which code will be executed; it defaults to a newly
30+
created dictionary with key "__name__" set to "__console__" and
31+
key "__doc__" set to None.
3232
3333
"""
3434
if locals is None:

Lib/pdb.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -392,9 +392,12 @@ def setup(self, f, tb):
392392
self.tb_lineno[tb.tb_frame] = lineno
393393
tb = tb.tb_next
394394
self.curframe = self.stack[self.curindex][0]
395-
# The f_locals dictionary is updated from the actual frame
396-
# locals whenever the .f_locals accessor is called, so we
397-
# cache it here to ensure that modifications are not overwritten.
395+
# The f_locals dictionary used to be updated from the actual frame
396+
# locals whenever the .f_locals accessor was called, so it was
397+
# cached here to ensure that modifications were not overwritten. While
398+
# the caching is no longer required now that f_locals is a direct proxy
399+
# on optimized frames, it's also harmless, so the code structure has
400+
# been left unchanged.
398401
self.curframe_locals = self.curframe.f_locals
399402
self.set_convenience_variable(self.curframe, '_frame', self.curframe)
400403

0 commit comments

Comments
 (0)