GH-109975: Copyedit 3.13 What's New: New Features (#122990)

Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Co-authored-by: Brandt Bucher <brandtbucher@gmail.com>
This commit is contained in:
Adam Turner 2024-08-15 10:08:15 +01:00 committed by GitHub
parent 1054a755a3
commit b106cf8d97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 226 additions and 208 deletions

View File

@ -14,8 +14,8 @@ There are two variants of the interactive :term:`REPL`. The classic
basic interpreter is supported on all platforms with minimal line
control capabilities.
On Unix-like systems (e.g. Linux or macOS) with :mod:`curses` and
:mod:`readline` support, a new interactive shell is used by default.
On Windows, or Unix-like systems with :mod:`curses` support,
a new interactive shell is used by default.
This one supports color, multiline editing, history browsing, and
paste mode. To disable color, see :ref:`using-on-controlling-color` for
details. Function keys provide some additional functionality.

View File

@ -88,7 +88,7 @@ Several legacy standard library modules have now `been removed
This article doesn't attempt to provide a complete specification
of all new features, but instead gives a convenient overview.
For full details refer to the documentation,
such as the :ref:`Library Reference <library-index>`
such as the :ref:`Library Reference <library-index>`
and :ref:`Language Reference <reference-index>`.
To understand the complete implementation and design rationale for a change,
refer to the PEP for a particular new feature;
@ -173,10 +173,10 @@ New typing features:
Platform support:
* :pep:`730`: Apple's iOS is now an officially supported platform,
at :pep:`tier 3 <11#tier-3>`.
* :pep:`730`: Apple's iOS is now an :ref:`officially supported platform
<whatsnew313-platform-support>`, at :pep:`tier 3 <11#tier-3>`.
Official Android support (:pep:`738`) is in the works as well.
* ``wasm32-wasi`` is now a supported as a :pep:`tier 2 <11#tier-2>` platform.
* ``wasm32-wasi`` is now supported as a :pep:`tier 2 <11#tier-2>` platform.
* ``wasm32-emscripten`` is no longer an officially supported platform.
Important removals:
@ -187,7 +187,7 @@ Important removals:
:mod:`!crypt`, :mod:`!imghdr`, :mod:`!mailcap`, :mod:`!msilib`, :mod:`!nis`,
:mod:`!nntplib`, :mod:`!ossaudiodev`, :mod:`!pipes`, :mod:`!sndhdr`,
:mod:`!spwd`, :mod:`!sunau`, :mod:`!telnetlib`, :mod:`!uu` and :mod:`!xdrlib`.
* Remove the :program:`!2to3` tool and :mod:`!lib2to3` module
* Remove the :program:`2to3` tool and :mod:`!lib2to3` module
(deprecated in Python 3.11).
* Remove the :mod:`!tkinter.tix` module (deprecated in Python 3.6).
* Remove :func:`!locale.resetlocale()`.
@ -209,51 +209,50 @@ This updated policy means that:
New Features
============
.. _whatsnew313-better-interactive-interpreter:
A Better Interactive Interpreter
A better interactive interpreter
--------------------------------
On Unix-like systems like Linux or macOS as well as Windows, Python now
uses a new :term:`interactive` shell. When the user starts the
:term:`REPL` from an interactive terminal the interactive shell now
supports the following new features:
Python now uses a new :term:`interactive` shell by default.
When the user starts the :term:`REPL` from an interactive terminal,
the following new features are now supported:
* Colorized prompts.
* Multiline editing with history preservation.
* Direct support for REPL-specific commands like :kbd:`help`, :kbd:`exit`,
and :kbd:`quit`, without the need to call them as functions.
* Prompts and tracebacks with :ref:`color enabled by default
<using-on-controlling-color>`.
* Interactive help browsing using :kbd:`F1` with a separate command
history.
* History browsing using :kbd:`F2` that skips output as well as the
:term:`>>>` and :term:`...` prompts.
* "Paste mode" with :kbd:`F3` that makes pasting larger blocks of code
easier (press :kbd:`F3` again to return to the regular prompt).
* The ability to issue REPL-specific commands like :kbd:`help`, :kbd:`exit`,
and :kbd:`quit` without the need to use call parentheses after the command
name.
If the new interactive shell is not desired, it can be disabled via
the :envvar:`PYTHON_BASIC_REPL` environment variable.
The new shell requires :mod:`curses` on Unix-like systems.
To disable the new interactive shell,
set the :envvar:`PYTHON_BASIC_REPL` environment variable.
For more on interactive mode, see :ref:`tut-interac`.
(Contributed by Pablo Galindo Salgado, Łukasz Langa, and
Lysandros Nikolaou in :gh:`111201` based on code from the PyPy project.
Windows support contributed by Dino Viehland and Anthony Shaw.)
.. _whatsnew313-improved-error-messages:
Improved Error Messages
Improved error messages
-----------------------
* The interpreter now colorizes error messages when displaying tracebacks by default.
This feature can be controlled via the new :envvar:`PYTHON_COLORS` environment
variable as well as the canonical |NO_COLOR|_ and |FORCE_COLOR|_ environment
variables. See also :ref:`using-on-controlling-color`.
* The interpreter now uses color by default when displaying tracebacks in the
terminal. This feature :ref:`can be controlled <using-on-controlling-color>`
via the new :envvar:`PYTHON_COLORS` environment variable as well as
the canonical |NO_COLOR|_ and |FORCE_COLOR|_ environment variables.
(Contributed by Pablo Galindo Salgado in :gh:`112730`.)
.. Apparently this how you hack together a formatted link:
(https://www.docutils.org/docs/ref/rst/directives.html#replacement-text)
.. |FORCE_COLOR| replace:: ``FORCE_COLOR``
.. _FORCE_COLOR: https://force-color.org/
@ -265,207 +264,81 @@ Improved Error Messages
standard library module. When this results in errors, we now
display a more helpful error message:
.. code-block:: shell-session
.. code-block:: pytb
$ python random.py
Traceback (most recent call last):
File "/home/random.py", line 1, in <module>
import random; print(random.randint(5))
^^^^^^^^^^^^^
File "/home/random.py", line 1, in <module>
import random; print(random.randint(5))
^^^^^^^^^^^^^^
AttributeError: module 'random' has no attribute 'randint' (consider renaming '/home/random.py' since it has the same name as the standard library module named 'random' and the import system gives it precedence)
$ python random.py
Traceback (most recent call last):
File "/home/me/random.py", line 1, in <module>
import random
File "/home/me/random.py", line 3, in <module>
print(random.randint(5))
^^^^^^^^^^^^^^
AttributeError: module 'random' has no attribute 'randint' (consider renaming '/home/me/random.py' since it has the same name as the standard library module named 'random' and the import system gives it precedence)
Similarly, if a script has the same name as a third-party
module it attempts to import, and this results in errors,
module that it attempts to import and this results in errors,
we also display a more helpful error message:
.. code-block:: shell-session
.. code-block:: pytb
$ python numpy.py
Traceback (most recent call last):
File "/home/numpy.py", line 1, in <module>
import numpy as np; np.array([1,2,3])
^^^^^^^^^^^^^^^^^^
File "/home/numpy.py", line 1, in <module>
import numpy as np; np.array([1,2,3])
^^^^^^^^
AttributeError: module 'numpy' has no attribute 'array' (consider renaming '/home/numpy.py' if it has the same name as a third-party module you intended to import)
$ python numpy.py
Traceback (most recent call last):
File "/home/me/numpy.py", line 1, in <module>
import numpy as np
File "/home/me/numpy.py", line 3, in <module>
np.array([1, 2, 3])
^^^^^^^^
AttributeError: module 'numpy' has no attribute 'array' (consider renaming '/home/me/numpy.py' if it has the same name as a third-party module you intended to import)
(Contributed by Shantanu Jain in :gh:`95754`.)
* When an incorrect keyword argument is passed to a function, the error message
now potentially suggests the correct keyword argument.
* The error message now tries to suggest the correct keyword argument
when an incorrect keyword argument is passed to a function.
.. code-block:: pycon
>>> "Better error messages!".split(max_split=1)
Traceback (most recent call last):
File "<python-input-0>", line 1, in <module>
"Better error messages!".split(max_split=1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
TypeError: split() got an unexpected keyword argument 'max_split'. Did you mean 'maxsplit'?
(Contributed by Pablo Galindo Salgado and Shantanu Jain in :gh:`107944`.)
>>> "better error messages!".split(max_split=1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
"better error messages!".split(max_split=1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
TypeError: split() got an unexpected keyword argument 'max_split'. Did you mean 'maxsplit'?
* Classes have a new :attr:`~class.__static_attributes__` attribute, populated by the compiler,
with a tuple of names of attributes of this class which are assigned
through ``self.X`` from any function in its body. (Contributed by Irit Katriel
in :gh:`115775`.)
.. _whatsnew313-locals-semantics:
Defined mutation semantics for :py:func:`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.
This change to the semantics of :func:`locals` in optimized scopes also affects the default
behaviour of code execution functions that implicitly target ``locals()`` if no explicit
namespace is provided (such as :func:`exec` and :func:`eval`). In previous versions, whether
or not changes could be accessed by calling ``locals()`` after calling the code execution
function was implementation dependent. In CPython specifically, such code would typically
appear to work as desired, but could sometimes fail in optimized scopes based on other code
(including debuggers and code execution tracing tools) potentially resetting the shared
snapshot in that scope. Now, the code will always run against an independent snapshot of the
local variables in optimized scopes, and hence the changes will never be visible in
subsequent calls to ``locals()``. To access the changes made in these cases, an explicit
namespace reference must now be passed to the relevant function. Alternatively, it may make
sense to update affected code to use a higher level code execution API that returns the
resulting code execution namespace (e.g. :func:`runpy.run_path` when executing Python
files from disk).
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. Porting
notes are also provided below for the affected :ref:`Python APIs <pep667-porting-notes-py>`
and :ref:`C APIs <pep667-porting-notes-c>`.
(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
------------------------------
* The cycle garbage collector is now incremental.
This means that maximum pause times are reduced
by an order of magnitude or more for larger heaps.
Support For Mobile Platforms
----------------------------
* iOS is now a :pep:`11` supported platform. ``arm64-apple-ios``
(iPhone and iPad devices released after 2013) and
``arm64-apple-ios-simulator`` (Xcode iOS simulator running on Apple Silicon
hardware) are now tier 3 platforms.
``x86_64-apple-ios-simulator`` (Xcode iOS simulator running on older x86_64
hardware) is not a tier 3 supported platform, but will be supported on a
best-effort basis.
See :pep:`730`: for more details.
(PEP written and implementation contributed by Russell Keith-Magee in
:gh:`114099`.)
.. _whatsnew313-jit-compiler:
Experimental JIT Compiler
-------------------------
When CPython is configured using the ``--enable-experimental-jit`` option,
a just-in-time compiler is added which may speed up some Python programs.
The internal architecture is roughly as follows.
* We start with specialized *Tier 1 bytecode*.
See :ref:`What's new in 3.11 <whatsnew311-pep659>` for details.
* When the Tier 1 bytecode gets hot enough, it gets translated
to a new, purely internal *Tier 2 IR*, a.k.a. micro-ops ("uops").
* The Tier 2 IR uses the same stack-based VM as Tier 1, but the
instruction format is better suited to translation to machine code.
* We have several optimization passes for Tier 2 IR, which are applied
before it is interpreted or translated to machine code.
* There is a Tier 2 interpreter, but it is mostly intended for debugging
the earlier stages of the optimization pipeline.
The Tier 2 interpreter can be enabled by configuring Python
with ``--enable-experimental-jit=interpreter``.
* When the JIT is enabled, the optimized
Tier 2 IR is translated to machine code, which is then executed.
* The machine code translation process uses a technique called
*copy-and-patch*. It has no runtime dependencies, but there is a new
build-time dependency on LLVM.
The ``--enable-experimental-jit`` flag has the following optional values:
* ``no`` (default) -- Disable the entire Tier 2 and JIT pipeline.
* ``yes`` (default if the flag is present without optional value)
-- Enable the JIT. To disable the JIT at runtime,
pass the environment variable ``PYTHON_JIT=0``.
* ``yes-off`` -- Build the JIT but disable it by default.
To enable the JIT at runtime, pass the environment variable
``PYTHON_JIT=1``.
* ``interpreter`` -- Enable the Tier 2 interpreter but disable the JIT.
The interpreter can be disabled by running with
``PYTHON_JIT=0``.
(On Windows, use ``PCbuild/build.bat --experimental-jit`` to enable the JIT
or ``--experimental-jit-interpreter`` to enable the Tier 2 interpreter.)
See :pep:`744` for more details.
(JIT by Brandt Bucher, inspired by a paper by Haoran Xu and Fredrik Kjolstad.
Tier 2 IR by Mark Shannon and Guido van Rossum.
Tier 2 optimizer by Ken Jin.)
.. _whatsnew313-free-threaded-cpython:
Free-threaded CPython
---------------------
CPython will run with the :term:`global interpreter lock` (GIL) disabled when
configured using the ``--disable-gil`` option at build time. This is an
experimental feature and therefore isn't used by default. Users need to
either compile their own interpreter, or install one of the experimental
builds that are marked as *free-threaded*. See :pep:`703` "Making the Global
Interpreter Lock Optional in CPython" for more detail.
CPython now has experimental support for running in a free-threaded mode,
with the :term:`global interpreter lock` (GIL) disabled.
This is an experimental feature and therefore is not enabled by default.
The free-threaded mode requires a different executable,
usually called ``python3.13t`` or ``python3.13t.exe``.
Pre-built binaries marked as *free-threaded* can be installed as part of
the official :ref:`Windows <install-freethreaded-windows>`
and :ref:`macOS <getting-and-installing-macpython>` installers,
or CPython can be built from source with the :option:`--disable-gil` option.
.. better macOS link pending
https://github.com/python/cpython/issues/109975#issuecomment-2286391179
Free-threaded execution allows for full utilization of the available
processing power by running threads in parallel on available CPU cores.
While not all software will benefit from this automatically, programs
designed with threading in mind will run faster on multicore hardware.
Work is still ongoing: expect some bugs and a substantial single-threaded
performance hit.
The free-threaded build still supports optionally running with the GIL
designed with threading in mind will run faster on multi-core hardware.
**The free-threaded mode is experimental** and work is ongoing to improve it:
expect some bugs and a substantial single-threaded performance hit.
Free-threaded builds of CPython support optionally running with the GIL
enabled at runtime using the environment variable :envvar:`PYTHON_GIL` or
the command line option :option:`-X gil`.
the command-line option :option:`-X gil`.
To check if the current interpreter is configured with ``--disable-gil``,
use ``sysconfig.get_config_var("Py_GIL_DISABLED")``. To check if the :term:`GIL`
is actually disabled in the running process, the :func:`!sys._is_gil_enabled`
function can be used.
To check if the current interpreter supports free-threading, :option:`python -VV <-V>`
and :attr:`sys.version` contain "experimental free-threading build".
The new :func:`!sys._is_gil_enabled` function can be used to check whether
the GIL is actually disabled in the running process.
C-API extension modules need to be built specifically for the free-threaded
build. Extensions that support running with the :term:`GIL` disabled should
@ -475,13 +348,158 @@ running with the GIL disabled. Importing C extensions that don't use these
mechanisms will cause the GIL to be enabled, unless the GIL was explicitly
disabled with the :envvar:`PYTHON_GIL` environment variable or the
:option:`-X gil=0` option.
pip 24.1b1 or newer is required to install packages with C extensions in the
pip 24.1 or newer is required to install packages with C extensions in the
free-threaded build.
.. seealso::
:pep:`703` "Making the Global Interpreter Lock Optional in CPython"
contains rationale and information surrounding this work.
.. _whatsnew313-jit-compiler:
An experimental just-in-time (JIT) compiler
-------------------------------------------
When CPython is configured and built using
the :option:`!--enable-experimental-jit` option,
a just-in-time (JIT) compiler is added which may speed up some Python programs.
On Windows, use ``PCbuild/build.bat --experimental-jit`` to enable the JIT
or ``--experimental-jit-interpreter`` to enable the Tier 2 interpreter.
Build requirements and further supporting information `are contained at`__
:file:`Tools/jit/README.md`.
__ https://github.com/python/cpython/blob/main/Tools/jit/README.md
The :option:`!--enable-experimental-jit` option takes these (optional) values,
defaulting to ``yes`` if :option:`!--enable-experimental-jit` is present
without the optional value.
* ``no``: Disable the entire Tier 2 and JIT pipeline.
* ``yes``: Enable the JIT.
To disable the JIT at runtime, pass the environment variable ``PYTHON_JIT=0``.
* ``yes-off``: Build the JIT but disable it by default.
To enable the JIT at runtime, pass the environment variable ``PYTHON_JIT=1``.
* ``interpreter``: Enable the Tier 2 interpreter but disable the JIT.
The interpreter can be disabled by running with ``PYTHON_JIT=0``.
The internal architecture is roughly as follows:
* We start with specialized *Tier 1 bytecode*.
See :ref:`What's new in 3.11 <whatsnew311-pep659>` for details.
* When the Tier 1 bytecode gets hot enough, it gets translated
to a new purely internal intermediate representation (IR),
called the *Tier 2 IR*, and sometimes referred to as micro-ops ("uops").
* The Tier 2 IR uses the same stack-based virtual machine as Tier 1,
but the instruction format is better suited to translation to machine code.
* We have several optimization passes for Tier 2 IR, which are applied
before it is interpreted or translated to machine code.
* There is a Tier 2 interpreter, but it is mostly intended for debugging
the earlier stages of the optimization pipeline.
The Tier 2 interpreter can be enabled by configuring Python
with ``--enable-experimental-jit=interpreter``.
* When the JIT is enabled, the optimized
Tier 2 IR is translated to machine code, which is then executed.
* The machine code translation process uses a technique called
*copy-and-patch*. It has no runtime dependencies, but there is a new
build-time dependency on LLVM.
.. seealso:: :pep:`744`
(JIT by Brandt Bucher, inspired by a paper by Haoran Xu and Fredrik Kjolstad.
Tier 2 IR by Mark Shannon and Guido van Rossum.
Tier 2 optimizer by Ken Jin.)
.. _whatsnew313-locals-semantics:
Defined mutation semantics for :py:func:`locals`
------------------------------------------------
Historically, the expected result of mutating the return value of
:func:`locals` has been left to individual Python implementations to define.
Starting from Python 3.13, :pep:`667` 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.
This change to the semantics of :func:`locals` in optimized scopes also
affects the default behaviour of code execution functions that implicitly
target :func:`!locals` if no explicit namespace is provided
(such as :func:`exec` and :func:`eval`).
In previous versions, whether or not changes could be accessed by calling
:func:`!locals` after calling the code execution function was
implementation-dependent. In CPython specifically, such code would typically
appear to work as desired, but could sometimes fail in optimized scopes based
on other code (including debuggers and code execution tracing tools)
potentially resetting the shared snapshot in that scope.
Now, the code will always run against an independent snapshot of
the local variables in optimized scopes, and hence the changes will never
be visible in subsequent calls to :func:`!locals`.
To access the changes made in these cases, an explicit namespace reference
must now be passed to the relevant function.
Alternatively, it may make sense to update affected code to use a higher level
code execution API that returns the resulting code execution namespace
(e.g. :func:`runpy.run_path` when executing Python files from disk).
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. Porting notes are also provided below for the affected
:ref:`Python APIs <pep667-porting-notes-py>` and :ref:`C APIs
<pep667-porting-notes-c>`.
(PEP and implementation contributed by Mark Shannon and Tian Gao in
:gh:`74929`. Documentation updates provided by Guido van Rossum and
Alyssa Coghlan.)
.. _whatsnew313-platform-support:
Support for mobile platforms
----------------------------
:pep:`730`: iOS is now a :pep:`11` supported platform, with the
``arm64-apple-ios`` and ``arm64-apple-ios-simulator`` targets at tier 3
(iPhone and iPad devices released after 2013 and the Xcode iOS simulator
running on Apple silicon hardware, respectively).
``x86_64-apple-ios-simulator``
(the Xcode iOS simulator running on older ``x86_64`` hardware)
is not a tier 3 supported platform, but will have best-effort support.
(PEP written and implementation contributed by Russell Keith-Magee in
:gh:`114099`.)
:pep:`738`: Android support is being actively worked on,
but the platform is not yet officially supported.
(PEP written and implementation contributed by Malcolm Smith in
:gh:`116622`.)
.. seealso:: :pep:`730`, :pep:`738`
Incremental garbage collection
------------------------------
The cycle garbage collector is now incremental.
This means that maximum pause times are reduced
by an order of magnitude or more for larger heaps.
Other Language Changes
======================
* Classes have a new :attr:`~class.__static_attributes__` attribute, populated by the compiler,
with a tuple of names of attributes of this class which are assigned
through ``self.X`` from any function in its body. (Contributed by Irit Katriel
in :gh:`115775`.)
* The :func:`exec` and :func:`eval` built-ins now accept their ``globals``
and ``locals`` namespace arguments as keywords.
(Contributed by Raphael Gaschignard in :gh:`105879`)
@ -2033,8 +2051,8 @@ Changes in the Python API
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()``. Code execution functions that
implicitly target ``locals()`` (such as ``exec`` and ``eval``) must be
results of subsequent calls to :func:`!locals`. Code execution functions that
implicitly target :func:`!locals` (such as ``exec`` and ``eval``) must be
passed an explicit namespace to access their results in an optimized scope.
(Changed as part of :pep:`667`.)