Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1288a99

Browse filesBrowse files
ncoghlanestyxx
authored andcommitted
pythongh-74929: PEP 667 general docs update (pythongh-119201)
* 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)
1 parent d4ce5a3 commit 1288a99
Copy full SHA for 1288a99

File tree

11 files changed

+163
-66
lines changed
Filter options

11 files changed

+163
-66
lines changed

‎Doc/c-api/frame.rst

Copy file name to clipboardExpand all lines: Doc/c-api/frame.rst
+6-5Lines changed: 6 additions & 5 deletions
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

Copy file name to clipboardExpand all lines: Doc/glossary.rst
+9Lines changed: 9 additions & 0 deletions
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

Copy file name to clipboardExpand all lines: Doc/library/code.rst
+3-3Lines changed: 3 additions & 3 deletions
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

Copy file name to clipboardExpand all lines: Doc/library/functions.rst
+68-35Lines changed: 68 additions & 35 deletions
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

Copy file name to clipboardExpand all lines: Doc/library/pdb.rst
+13-9Lines changed: 13 additions & 9 deletions
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

Copy file name to clipboardExpand all lines: Doc/library/profile.rst
+1-1Lines changed: 1 addition & 1 deletion
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

Copy file name to clipboardExpand all lines: Doc/library/traceback.rst
+1-1Lines changed: 1 addition & 1 deletion
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

Copy file name to clipboardExpand all lines: Doc/reference/datamodel.rst
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1349,7 +1349,7 @@ Special read-only attributes
13491349
* - .. attribute:: frame.f_locals
13501350
- The dictionary used by the frame to look up
13511351
:ref:`local variables <naming>`.
1352-
If the frame refers to a function or comprehension,
1352+
If the frame refers to an :term:`optimized scope`,
13531353
this may return a write-through proxy object.
13541354

13551355
.. versionchanged:: 3.13

‎Doc/whatsnew/3.13.rst

Copy file name to clipboardExpand all lines: Doc/whatsnew/3.13.rst
+51-4Lines changed: 51 additions & 4 deletions
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

Copy file name to clipboardExpand all lines: Lib/code.py
+4-4Lines changed: 4 additions & 4 deletions
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

Copy file name to clipboardExpand all lines: Lib/pdb.py
+6-3Lines changed: 6 additions & 3 deletions
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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.