Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
gh-74929: PEP 667 general docs update#119201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
6ecb4b3fa4172b9ba869b40d0a81b95890da87f1d76e3f1d1ebcf2d02a15a621e73460a86700570f1db9c5cb001d0fa5e1e109eee672458f270dface0ba6c71187f629f86cf5File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -543,18 +543,19 @@ are always available. They are listed here in alphabetical order. | ||
| The *expression* argument is parsed and evaluated as a Python expression | ||
| (technically speaking, a condition list) using the *globals* and *locals* | ||
| mappings as global and local namespace. If the *globals* dictionary is | ||
| present and does not contain a value for the key ``__builtins__``, a | ||
| reference to the dictionary of the built-in module :mod:`builtins` is | ||
| inserted under that key before *expression* is parsed. That way you can | ||
| control what builtins are available to the executed code by inserting your | ||
| own ``__builtins__`` dictionary into *globals* before passing it to | ||
| :func:`eval`. If the *locals*mapping is omitted it defaults to the | ||
| *globals* dictionary. If bothmappings are omitted, the expression is | ||
| executed with the *globals* and *locals* in the environment where | ||
| :func:`eval` is called. Note, *eval()*will only have access to the | ||
| :term:`nested scopes <nested scope>` (non-locals) in the enclosing | ||
| environment if they are already referenced in the scope that is calling | ||
| :func:`eval` (e.g. via a :keyword:`nonlocal` statement). | ||
| Example: | ||
| @@ -587,6 +588,11 @@ are always available. They are listed here in alphabetical order. | ||
| The *globals* and *locals* arguments can now be passed as keywords. | ||
| .. versionchanged:: 3.13 | ||
| The semantics of the default *locals* namespace have been adjusted as | ||
| described for the :func:`locals` builtin. | ||
| .. index:: pair: built-in function; exec | ||
| .. function:: exec(source, /, globals=None, locals=None, *, closure=None) | ||
| @@ -612,9 +618,15 @@ are always available. They are listed here in alphabetical order. | ||
| .. note:: | ||
| When ``exec`` gets two separate objects as *globals* and *locals*, the | ||
| code will be executed as if it were embedded in a class definition. This | ||
| means functions and classes defined in the executed code will not be able | ||
| to access variables assigned at the top level (as the "top level" | ||
| variables are treated as class variables in a class definition). | ||
| Passing a :class:`collections.ChainMap` instance as *globals* allows name | ||
| lookups to be chained across multiple mappings without triggering this | ||
| behaviour. Values assigned to top level names in the executed code can be | ||
| retrieved by passing an empty dictionary as the first entry in the chain. | ||
ncoghlan marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| If the *globals* dictionary does not contain a value for the key | ||
| ``__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. | ||
| .. note:: | ||
| The built-in functions :func:`globals` and :func:`locals` return the current | ||
| global and localnamespace, respectively, which may be useful to pass around | ||
| for use as the second and third argument to :func:`exec`. | ||
| .. note:: | ||
| @@ -651,6 +663,11 @@ are always available. They are listed here in alphabetical order. | ||
| The *globals* and *locals* arguments can now be passed as keywords. | ||
| .. versionchanged:: 3.13 | ||
| The semantics of the default *locals* namespace have been adjusted as | ||
| described for the :func:`locals` builtin. | ||
| .. function:: filter(function, iterable) | ||
| @@ -1056,39 +1073,51 @@ are always available. They are listed here in alphabetical order. | ||
| variable names as the keys, and their currently bound references as the | ||
| values. | ||
| At module scope, as well as when using :func:`exec` or :func:`eval` with | ||
| a single namespace, this function returns the same namespace as | ||
| :func:`globals`. | ||
| At class scope, it returns the namespace that will be passed to the | ||
| metaclass constructor. | ||
| When using ``exec()`` or ``eval()`` with separate local and global | ||
| arguments, it returns the local namespace passed in to the function call. | ||
| In all of the above cases, each call to ``locals()`` in a given frame of | ||
| execution will return the *same* mapping object. Changes made through | ||
| the mapping object returned from ``locals()`` will be visible as assigned, | ||
ncoghlan marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| reassigned, or deleted local variables, and assigning, reassigning, or | ||
| deleting local variables will immediately affect the contents of the | ||
| returned mapping object. | ||
| In an :term:`optimized scope` (including functions, generators, and | ||
| coroutines), each call to ``locals()`` instead returns a fresh dictionary | ||
| containing the current bindings of the function's local variables and any | ||
| nonlocal cell references. In this case, name binding changes made via the | ||
| returned dict are *not* written back to the corresponding local variables | ||
| or nonlocal cell references, and assigning, reassigning, or deleting local | ||
| variables and nonlocal cell references does *not* affect the contents | ||
| of previously returned dictionaries. | ||
| Calling ``locals()`` as part of a comprehension in a function, generator, or | ||
| coroutine is equivalent to calling it in the containing scope, except that | ||
| the comprehension's initialised iteration variables will be included. In | ||
| other scopes, it behaves as if the comprehension were running as a nested | ||
| function. | ||
| Calling ``locals()`` as part of a generator expression is equivalent to | ||
| calling it in a nested generator function. | ||
| .. versionchanged:: 3.12 | ||
| The behaviour of ``locals()`` in a comprehension has been updated as | ||
| described in :pep:`709`. | ||
| .. versionchanged:: 3.13 | ||
| As part of :pep:`667`, the semantics of mutating the mapping objects | ||
| returned from this function are now defined. The behavior in | ||
| :term:`optimized scopes <optimized scope>` is now as described above. | ||
| Aside from being defined, the behaviour in other scopes remains | ||
| unchanged from previous versions. | ||
| .. function:: map(function, iterable, *iterables) | ||
| @@ -1975,14 +2004,18 @@ are always available. They are listed here in alphabetical order. | ||
| :attr:`~object.__dict__` attributes (for example, classes use a | ||
| :class:`types.MappingProxyType` to prevent direct dictionary updates). | ||
| Without an argument, :func:`vars` acts like :func:`locals`. | ||
| A :exc:`TypeError` exception is raised if an object is specified but | ||
| it doesn't have a :attr:`~object.__dict__` attribute (for example, if | ||
| its class defines the :attr:`~object.__slots__` attribute). | ||
| .. versionchanged:: 3.13 | ||
| The result of calling this function without an argument has been | ||
| updated as described for the :func:`locals` builtin. | ||
| .. function:: zip(*iterables, strict=False) | ||
| Iterate over several iterables in parallel, producing tuples with an item | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -123,6 +123,11 @@ The typical usage to inspect a crashed program is:: | ||
| 0 | ||
| (Pdb) | ||
| .. versionchanged:: 3.13 | ||
| The implementation of :pep:`667` means that name assignments made via ``pdb`` | ||
| will immediately affect the active scope, even when running inside an | ||
| :term:`optimized scope`. | ||
| The module defines the following functions; each enters the debugger in a | ||
| slightly different way: | ||
| @@ -579,18 +584,17 @@ can be overridden by the local file. | ||
| .. pdbcommand:: interact | ||
| Start an interactive interpreter (using the :mod:`code` module)in a new | ||
| globalnamespaceinitialised from thelocal andglobal namespaces forthe | ||
| currentscope. Use ``exit()`` or ``quit()`` to exit the interpreter and | ||
| return tothe debugger. | ||
| .. note:: | ||
ncoghlan marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| As ``interact`` creates a new dedicated namespace for code execution, | ||
| assignments to variables will not affect the original namespaces. | ||
| However, modifications to any referenced mutable objects will be reflected | ||
| in the original namespaces as usual. | ||
| .. versionadded:: 3.2 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -94,10 +94,11 @@ Interpreter improvements: | ||
| Performance improvements are modest -- we expect to be improving this | ||
| over the next few releases. | ||
| * :pep:`667`: The :func:`locals` builtin now has | ||
| :ref:`defined semantics <whatsnew313-locals-semantics>` when mutating the | ||
| returned mapping. Python debuggers and similar tools may now more reliably | ||
| update local variables in optimized frames even during concurrent code | ||
| execution. | ||
| New typing features: | ||
| @@ -247,6 +248,34 @@ Improved Error Messages | ||
| through ``self.X`` from any function in its body. (Contributed by Irit Katriel | ||
| in :gh:`115775`.) | ||
| .. _whatsnew313-locals-semantics: | ||
| Defined mutation semantics for ``locals()`` | ||
| ------------------------------------------- | ||
| Historically, the expected result of mutating the return value of :func:`locals` | ||
| has been left to individual Python implementations to define. | ||
| Through :pep:`667`, Python 3.13 standardises the historical behaviour of CPython | ||
| for most code execution scopes, but changes | ||
| :term:`optimized scopes <optimized scope>` (functions, generators, coroutines, | ||
| comprehensions, and generator expressions) to explicitly return independent | ||
| snapshots of the currently assigned local variables, including locally | ||
| referenced nonlocal variables captured in closures. | ||
| To ensure debuggers and similar tools can reliably update local variables in | ||
| scopes affected by this change, :attr:`FrameType.f_locals <frame.f_locals>` now | ||
| returns a write-through proxy to the frame's local and locally referenced | ||
| nonlocal variables in these scopes, rather than returning an inconsistently | ||
| updated shared ``dict`` instance with undefined runtime semantics. | ||
| See :pep:`667` for more details, including related C API changes and | ||
| deprecations. | ||
| (PEP and implementation contributed by Mark Shannon and Tian Gao in | ||
| :gh:`74929`. Documentation updates provided by Guido van Rossum and | ||
| Alyssa Coghlan.) | ||
| Incremental Garbage Collection | ||
| ------------------------------ | ||
| @@ -2177,6 +2206,24 @@ Changes in the Python API | ||
| returned by :meth:`zipfile.ZipFile.open` was changed from ``'r'`` to ``'rb'``. | ||
| (Contributed by Serhiy Storchaka in :gh:`115961`.) | ||
| * Calling :func:`locals` in an :term:`optimized scope` now produces an | ||
| independent snapshot on each call, and hence no longer implicitly updates | ||
| previously returned references. Obtaining the legacy CPython behaviour now | ||
| requires explicit calls to update the initially returned dictionary with the | ||
| results of subsequent calls to ``locals()``. (Changed as part of :pep:`667`.) | ||
| * Calling :func:`locals` from a comprehension at module or class scope | ||
| (including via ``exec`` or ``eval``) once more behaves as if the comprehension | ||
| were running as an independent nested function (i.e. the local variables from | ||
| the containing scope are not included). In Python 3.12, this had changed | ||
| to include the local variables from the containing scope when implementing | ||
| :pep:`709`. (Changed as part of :pep:`667`.) | ||
ncoghlan marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| * Accessing :attr:`FrameType.f_locals <frame.f_locals>` 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 with ``dict`` or the proxy's ``.copy()`` method. | ||
| (Changed as part of :pep:`667`.) | ||
| Changes in the C API | ||
| -------------------- | ||