diff options
author | Alyssa Coghlan <ncoghlan@gmail.com> | 2024-05-21 03:32:15 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-21 03:32:15 (GMT) |
commit | e870c852c0ea96fa4e4569e9c39c7ceb80ce858d (patch) | |
tree | 1268f6cbbc811eb44df6935992ba76ff94e0ac89 /Doc/library | |
parent | 538ed5e4818aa0d0aa759634e8bfa23e317434a1 (diff) | |
download | cpython-e870c852c0ea96fa4e4569e9c39c7ceb80ce858d.zip cpython-e870c852c0ea96fa4e4569e9c39c7ceb80ce858d.tar.gz cpython-e870c852c0ea96fa4e4569e9c39c7ceb80ce858d.tar.bz2 |
gh-74929: PEP 667 general docs update (gh-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)
Diffstat (limited to 'Doc/library')
-rw-r--r-- | Doc/library/code.rst | 6 | ||||
-rw-r--r-- | Doc/library/functions.rst | 103 | ||||
-rw-r--r-- | Doc/library/pdb.rst | 22 | ||||
-rw-r--r-- | Doc/library/profile.rst | 2 | ||||
-rw-r--r-- | Doc/library/traceback.rst | 2 |
5 files changed, 86 insertions, 49 deletions
diff --git a/Doc/library/code.rst b/Doc/library/code.rst index 8c3a3e8..8f7692d 100644 --- a/Doc/library/code.rst +++ b/Doc/library/code.rst @@ -18,9 +18,9 @@ build applications which provide an interactive interpreter prompt. This class deals with parsing and interpreter state (the user's namespace); it does not deal with input buffering or prompting or input file naming (the filename is always passed in explicitly). The optional *locals* argument - specifies the dictionary in which code will be executed; it defaults to a newly - created dictionary with key ``'__name__'`` set to ``'__console__'`` and key - ``'__doc__'`` set to ``None``. + specifies a mapping to use as the namespace in which code will be executed; + it defaults to a newly created dictionary with key ``'__name__'`` set to + ``'__console__'`` and key ``'__doc__'`` set to ``None``. .. class:: InteractiveConsole(locals=None, filename="<console>", local_exit=False) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 3986ace..a879ddb 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -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* - dictionaries as global and local namespace. If the *globals* dictionary is + 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* dictionary is omitted it defaults to the - *globals* dictionary. If both dictionaries are omitted, the expression is + :func:`eval`. If the *locals* mapping is omitted it defaults to the + *globals* dictionary. If both mappings are omitted, the expression is executed with the *globals* and *locals* in the environment where - :func:`eval` is called. Note, *eval()* does not have access to the + :func:`eval` is called. Note, *eval()* will only have access to the :term:`nested scopes <nested scope>` (non-locals) in the enclosing - environment. + 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:: - Most users should just pass a *globals* argument and never *locals*. - If exec gets two separate objects as *globals* and *locals*, the code - will be executed as if it were embedded in a class definition. + 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. 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 local dictionary, respectively, which may be useful to pass around + global and local namespace, 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 ``exec()`` or ``eval()`` with a - single namespace, this function returns the same namespace as ``globals()``. + 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 - namespaces, it returns the local namespace passed in to the function call. + 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 bound, - rebound, or deleted local variables, and binding, rebinding, or deleting - local variables will immediately affect the contents of the returned mapping - object. - - At function scope (including for 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 binding, rebinding, or deleting local variables and nonlocal - cell references does *not* affect the contents of previously returned - dictionaries. + the mapping object returned from ``locals()`` will be visible as assigned, + 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 - In previous versions, the semantics of mutating the mapping object - returned from this function were formally undefined. In CPython - specifically, the mapping returned at function scope could be - implicitly refreshed by other operations, such as calling ``locals()`` - again. Obtaining the legacy CPython behaviour now requires explicit - calls to update the initially returned dictionary with the results - of subsequent calls to ``locals()``. + 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`. Note, the - locals dictionary is only useful for reads since updates to the locals - dictionary are ignored. + 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 diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 7a47a7d..7d67e06 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -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) whose global - namespace contains all the (global and local) names found in the current - scope. Use ``exit()`` or ``quit()`` to exit the interpreter and return to - the debugger. + Start an interactive interpreter (using the :mod:`code` module) in a new + global namespace initialised from the local and global namespaces for the + current scope. Use ``exit()`` or ``quit()`` to exit the interpreter and + return to the debugger. .. note:: - Because interact creates a new global namespace with the current global - and local namespace for execution, assignment to variables will not - affect the original namespaces. - However, modification to the mutable objects will be reflected in the - original namespaces. + 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 diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 3ca802e..9721da7 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -234,7 +234,7 @@ functions: .. function:: runctx(command, globals, locals, filename=None, sort=-1) This function is similar to :func:`run`, with added arguments to supply the - globals and locals dictionaries for the *command* string. This routine + globals and locals mappings for the *command* string. This routine executes:: exec(command, globals, locals) diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst index 9983b8d..bfd2c3e 100644 --- a/Doc/library/traceback.rst +++ b/Doc/library/traceback.rst @@ -473,7 +473,7 @@ in a :ref:`traceback <traceback-objects>`. attribute accessed (which also happens when casting it to a :class:`tuple`). :attr:`~FrameSummary.line` may be directly provided, and will prevent line lookups happening at all. *locals* is an optional local variable - dictionary, and if supplied the variable representations are stored in the + mapping, and if supplied the variable representations are stored in the summary for later display. :class:`!FrameSummary` instances have the following attributes: |