diff --git a/Doc/c-api/contextvars.rst b/Doc/c-api/contextvars.rst
index 8eba54a80dc80d..b7c6550ff34aac 100644
--- a/Doc/c-api/contextvars.rst
+++ b/Doc/c-api/contextvars.rst
@@ -123,16 +123,10 @@ Context object management functions:
Enumeration of possible context object watcher events:
- - ``Py_CONTEXT_EVENT_ENTER``: A context has been entered, causing the
- :term:`current context` to switch to it. The object passed to the watch
- callback is the now-current :class:`contextvars.Context` object. Each
- enter event will eventually have a corresponding exit event for the same
- context object after any subsequently entered contexts have themselves been
- exited.
- - ``Py_CONTEXT_EVENT_EXIT``: A context is about to be exited, which will
- cause the :term:`current context` to switch back to what it was before the
- context was entered. The object passed to the watch callback is the
- still-current :class:`contextvars.Context` object.
+ - ``Py_CONTEXT_SWITCHED``: The :term:`current context` has switched to a
+ different context. The object passed to the watch callback is the
+ now-current :class:`contextvars.Context` object, or None if no context is
+ current.
.. versionadded:: 3.14
diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst
index 6f8962afc7af0d..6194d7446c73e4 100644
--- a/Doc/c-api/init_config.rst
+++ b/Doc/c-api/init_config.rst
@@ -1621,6 +1621,8 @@ Create Config
Free memory of the initialization configuration *config*.
+ If *config* is ``NULL``, no operation is performed.
+
Error Handling
--------------
@@ -1823,14 +1825,18 @@ return ``-1`` on error:
PyInitConfig_Free(config);
return 0;
- // Display the error message
- const char *err_msg;
error:
- (void)PyInitConfig_GetError(config, &err_msg);
- printf("PYTHON INIT ERROR: %s\n", err_msg);
- PyInitConfig_Free(config);
+ {
+ // Display the error message
+ // This uncommon braces style is used, because you cannot make
+ // goto targets point to variable declarations.
+ const char *err_msg;
+ (void)PyInitConfig_GetError(config, &err_msg);
+ printf("PYTHON INIT ERROR: %s\n", err_msg);
+ PyInitConfig_Free(config);
- return -1;
+ return -1;
+ }
}
diff --git a/Doc/conf.py b/Doc/conf.py
index d7197b17865854..839beaad08bebd 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -614,7 +614,7 @@
# Sphinx 8.1 has in-built CVE and CWE roles.
extlinks |= {
"cve": (
- "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-%s",
+ "https://www.cve.org/CVERecord?id=CVE-%s",
"CVE-%s",
),
"cwe": ("https://cwe.mitre.org/data/definitions/%s.html", "CWE-%s"),
diff --git a/Doc/deprecations/c-api-pending-removal-in-3.14.rst b/Doc/deprecations/c-api-pending-removal-in-3.14.rst
index d16da66c29abe7..9e10bf2691e5c8 100644
--- a/Doc/deprecations/c-api-pending-removal-in-3.14.rst
+++ b/Doc/deprecations/c-api-pending-removal-in-3.14.rst
@@ -1,4 +1,4 @@
-Pending Removal in Python 3.14
+Pending removal in Python 3.14
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* The ``ma_version_tag`` field in :c:type:`PyDictObject` for extension modules
diff --git a/Doc/deprecations/c-api-pending-removal-in-3.15.rst b/Doc/deprecations/c-api-pending-removal-in-3.15.rst
index e3974415e0cc89..1bb49e5b4874f2 100644
--- a/Doc/deprecations/c-api-pending-removal-in-3.15.rst
+++ b/Doc/deprecations/c-api-pending-removal-in-3.15.rst
@@ -1,4 +1,4 @@
-Pending Removal in Python 3.15
+Pending removal in Python 3.15
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* The bundled copy of ``libmpdecimal``.
diff --git a/Doc/deprecations/c-api-pending-removal-in-future.rst b/Doc/deprecations/c-api-pending-removal-in-future.rst
index 0c3ae52b87ff74..8fc1c80c35d092 100644
--- a/Doc/deprecations/c-api-pending-removal-in-future.rst
+++ b/Doc/deprecations/c-api-pending-removal-in-future.rst
@@ -1,4 +1,4 @@
-Pending Removal in Future Versions
+Pending removal in future versions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The following APIs are deprecated and will be removed,
diff --git a/Doc/deprecations/index.rst b/Doc/deprecations/index.rst
index a9efb0bc744335..bac6e3f18d4594 100644
--- a/Doc/deprecations/index.rst
+++ b/Doc/deprecations/index.rst
@@ -7,7 +7,7 @@ Deprecations
.. include:: pending-removal-in-future.rst
-C API Deprecations
+C API deprecations
------------------
.. include:: c-api-pending-removal-in-3.15.rst
diff --git a/Doc/deprecations/pending-removal-in-3.13.rst b/Doc/deprecations/pending-removal-in-3.13.rst
index 89790497816e83..2fd2f12cc6a2c4 100644
--- a/Doc/deprecations/pending-removal-in-3.13.rst
+++ b/Doc/deprecations/pending-removal-in-3.13.rst
@@ -1,4 +1,4 @@
-Pending Removal in Python 3.13
+Pending removal in Python 3.13
------------------------------
Modules (see :pep:`594`):
diff --git a/Doc/deprecations/pending-removal-in-3.14.rst b/Doc/deprecations/pending-removal-in-3.14.rst
index de30f4695059ed..b8791b8d6c387e 100644
--- a/Doc/deprecations/pending-removal-in-3.14.rst
+++ b/Doc/deprecations/pending-removal-in-3.14.rst
@@ -1,4 +1,4 @@
-Pending Removal in Python 3.14
+Pending removal in Python 3.14
------------------------------
* The import system:
diff --git a/Doc/deprecations/pending-removal-in-3.15.rst b/Doc/deprecations/pending-removal-in-3.15.rst
index a55fb6bea3fdaa..17029b8d4773bd 100644
--- a/Doc/deprecations/pending-removal-in-3.15.rst
+++ b/Doc/deprecations/pending-removal-in-3.15.rst
@@ -1,4 +1,4 @@
-Pending Removal in Python 3.15
+Pending removal in Python 3.15
------------------------------
* The import system:
@@ -63,7 +63,7 @@ Pending Removal in Python 3.15
* The undocumented keyword argument syntax for creating
:class:`~typing.NamedTuple` classes
- (e.g. ``Point = NamedTuple("Point", x=int, y=int)``)
+ (for example, ``Point = NamedTuple("Point", x=int, y=int)``)
has been deprecated since Python 3.13.
Use the class-based syntax or the functional syntax instead.
diff --git a/Doc/deprecations/pending-removal-in-3.16.rst b/Doc/deprecations/pending-removal-in-3.16.rst
index fc2ef33de5e5cc..fac500d34742ca 100644
--- a/Doc/deprecations/pending-removal-in-3.16.rst
+++ b/Doc/deprecations/pending-removal-in-3.16.rst
@@ -1,15 +1,6 @@
-Pending Removal in Python 3.16
+Pending removal in Python 3.16
------------------------------
-* :mod:`builtins`:
-
- * Bitwise inversion on boolean types, ``~True`` or ``~False``
- has been deprecated since Python 3.12,
- as it produces surprising and unintuitive results (``-2`` and ``-1``).
- Use ``not x`` instead for the logical negation of a Boolean.
- In the rare case that you need the bitwise inversion of
- the underlying integer, convert to ``int`` explicitly (``~int(x)``).
-
* :mod:`array`:
* The ``'u'`` format code (:c:type:`wchar_t`)
@@ -20,11 +11,19 @@ Pending Removal in Python 3.16
* :mod:`asyncio`:
- * :mod:`asyncio`:
- :func:`!asyncio.iscoroutinefunction` is deprecated
- and will be removed in Python 3.16,
- use :func:`inspect.iscoroutinefunction` instead.
- (Contributed by Jiahao Li and Kumar Aditya in :gh:`122875`.)
+ * :func:`!asyncio.iscoroutinefunction` is deprecated
+ and will be removed in Python 3.16,
+ use :func:`inspect.iscoroutinefunction` instead.
+ (Contributed by Jiahao Li and Kumar Aditya in :gh:`122875`.)
+
+* :mod:`builtins`:
+
+ * Bitwise inversion on boolean types, ``~True`` or ``~False``
+ has been deprecated since Python 3.12,
+ as it produces surprising and unintuitive results (``-2`` and ``-1``).
+ Use ``not x`` instead for the logical negation of a Boolean.
+ In the rare case that you need the bitwise inversion of
+ the underlying integer, convert to ``int`` explicitly (``~int(x)``).
* :mod:`shutil`:
diff --git a/Doc/deprecations/pending-removal-in-future.rst b/Doc/deprecations/pending-removal-in-future.rst
index 3f9cf6f208221a..f916797c07a068 100644
--- a/Doc/deprecations/pending-removal-in-future.rst
+++ b/Doc/deprecations/pending-removal-in-future.rst
@@ -1,4 +1,4 @@
-Pending Removal in Future Versions
+Pending removal in future versions
----------------------------------
The following APIs will be removed in the future,
diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index f0b465bc9ce39c..2f81080d525f86 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -180,19 +180,19 @@ Objects of the :class:`date` type are always naive.
An object of type :class:`.time` or :class:`.datetime` may be aware or naive.
-A :class:`.datetime` object *d* is aware if both of the following hold:
+A :class:`.datetime` object ``d`` is aware if both of the following hold:
1. ``d.tzinfo`` is not ``None``
2. ``d.tzinfo.utcoffset(d)`` does not return ``None``
-Otherwise, *d* is naive.
+Otherwise, ``d`` is naive.
-A :class:`.time` object *t* is aware if both of the following hold:
+A :class:`.time` object ``t`` is aware if both of the following hold:
1. ``t.tzinfo`` is not ``None``
2. ``t.tzinfo.utcoffset(None)`` does not return ``None``.
-Otherwise, *t* is naive.
+Otherwise, ``t`` is naive.
The distinction between aware and naive doesn't apply to :class:`timedelta`
objects.
@@ -358,8 +358,8 @@ Supported operations:
+--------------------------------+-----------------------------------------------+
| ``q, r = divmod(t1, t2)`` | Computes the quotient and the remainder: |
| | ``q = t1 // t2`` (3) and ``r = t1 % t2``. |
-| | q is an integer and r is a :class:`timedelta` |
-| | object. |
+| | ``q`` is an integer and ``r`` is a |
+| | :class:`timedelta` object. |
+--------------------------------+-----------------------------------------------+
| ``+t1`` | Returns a :class:`timedelta` object with the |
| | same value. (2) |
@@ -526,7 +526,7 @@ Other constructors, all class methods:
January 1 of year 1 has ordinal 1.
:exc:`ValueError` is raised unless ``1 <= ordinal <=
- date.max.toordinal()``. For any date *d*,
+ date.max.toordinal()``. For any date ``d``,
``date.fromordinal(d.toordinal()) == d``.
@@ -730,7 +730,7 @@ Instance methods:
.. method:: date.toordinal()
Return the proleptic Gregorian ordinal of the date, where January 1 of year 1
- has ordinal 1. For any :class:`date` object *d*,
+ has ordinal 1. For any :class:`date` object ``d``,
``date.fromordinal(d.toordinal()) == d``.
@@ -782,7 +782,7 @@ Instance methods:
.. method:: date.__str__()
- For a date *d*, ``str(d)`` is equivalent to ``d.isoformat()``.
+ For a date ``d``, ``str(d)`` is equivalent to ``d.isoformat()``.
.. method:: date.ctime()
@@ -1063,7 +1063,7 @@ Other constructors, all class methods:
is used. If the *date* argument is a :class:`.datetime` object, its time components
and :attr:`.tzinfo` attributes are ignored.
- For any :class:`.datetime` object *d*,
+ For any :class:`.datetime` object ``d``,
``d == datetime.combine(d.date(), d.time(), d.tzinfo)``.
.. versionchanged:: 3.6
@@ -1270,11 +1270,11 @@ Supported operations:
If both are naive, or both are aware and have the same :attr:`~.datetime.tzinfo` attribute,
the :attr:`~.datetime.tzinfo` attributes are ignored, and the result is a :class:`timedelta`
- object *t* such that ``datetime2 + t == datetime1``. No time zone adjustments
+ object ``t`` such that ``datetime2 + t == datetime1``. No time zone adjustments
are done in this case.
If both are aware and have different :attr:`~.datetime.tzinfo` attributes, ``a-b`` acts
- as if *a* and *b* were first converted to naive UTC datetimes. The
+ as if ``a`` and ``b`` were first converted to naive UTC datetimes. The
result is ``(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None)
- b.utcoffset())`` except that the implementation never overflows.
@@ -1454,11 +1454,11 @@ Instance methods:
.. method:: datetime.utctimetuple()
- If :class:`.datetime` instance *d* is naive, this is the same as
+ If :class:`.datetime` instance ``d`` is naive, this is the same as
``d.timetuple()`` except that :attr:`~.time.struct_time.tm_isdst` is forced to 0 regardless of what
``d.dst()`` returns. DST is never in effect for a UTC time.
- If *d* is aware, *d* is normalized to UTC time, by subtracting
+ If ``d`` is aware, ``d`` is normalized to UTC time, by subtracting
``d.utcoffset()``, and a :class:`time.struct_time` for the
normalized time is returned. :attr:`!tm_isdst` is forced to 0. Note
that an :exc:`OverflowError` may be raised if ``d.year`` was
@@ -1606,7 +1606,7 @@ Instance methods:
.. method:: datetime.__str__()
- For a :class:`.datetime` instance *d*, ``str(d)`` is equivalent to
+ For a :class:`.datetime` instance ``d``, ``str(d)`` is equivalent to
``d.isoformat(' ')``.
@@ -1853,7 +1853,7 @@ Instance attributes (read-only):
.. versionadded:: 3.6
:class:`.time` objects support equality and order comparisons,
-where *a* is considered less than *b* when *a* precedes *b* in time.
+where ``a`` is considered less than ``b`` when ``a`` precedes ``b`` in time.
Naive and aware :class:`!time` objects are never equal.
Order comparison between naive and aware :class:`!time` objects raises
@@ -2000,7 +2000,7 @@ Instance methods:
.. method:: time.__str__()
- For a time *t*, ``str(t)`` is equivalent to ``t.isoformat()``.
+ For a time ``t``, ``str(t)`` is equivalent to ``t.isoformat()``.
.. method:: time.strftime(format)
diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst
index ae5408ee386bbd..f7167032ad7df9 100644
--- a/Doc/reference/lexical_analysis.rst
+++ b/Doc/reference/lexical_analysis.rst
@@ -284,11 +284,10 @@ UAX-31, with elaboration and changes as defined below; see also :pep:`3131` for
further details.
Within the ASCII range (U+0001..U+007F), the valid characters for identifiers
-are the same as in Python 2.x: the uppercase and lowercase letters ``A`` through
+include the uppercase and lowercase letters ``A`` through
``Z``, the underscore ``_`` and, except for the first character, the digits
``0`` through ``9``.
-
-Python 3.0 introduces additional characters from outside the ASCII range (see
+Python 3.0 introduced additional characters from outside the ASCII range (see
:pep:`3131`). For these characters, the classification uses the version of the
Unicode Character Database as included in the :mod:`unicodedata` module.
diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst
index 4976418ba33cf8..10cdf2376229ff 100644
--- a/Doc/using/configure.rst
+++ b/Doc/using/configure.rst
@@ -29,7 +29,7 @@ Features and minimum versions required to build CPython:
* Tcl/Tk 8.5.12 for the :mod:`tkinter` module.
-* Autoconf 2.71 and aclocal 1.16.4 are required to regenerate the
+* Autoconf 2.71 and aclocal 1.16.5 are required to regenerate the
:file:`configure` script.
.. versionchanged:: 3.1
@@ -56,7 +56,7 @@ Features and minimum versions required to build CPython:
Tcl/Tk version 8.5.12 is now required for the :mod:`tkinter` module.
.. versionchanged:: 3.13
- Autoconf 2.71, aclocal 1.16.4 and SQLite 3.15.2 are now required.
+ Autoconf 2.71, aclocal 1.16.5 and SQLite 3.15.2 are now required.
See also :pep:`7` "Style Guide for C Code" and :pep:`11` "CPython platform
support".
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index a2897097aaba57..f9e74a9b8ff9c6 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -2495,9 +2495,9 @@ Build Changes
* Building CPython now requires a compiler with support for the C11 atomic
library, GCC built-in atomic functions, or MSVC interlocked intrinsics.
-* Autoconf 2.71 and aclocal 1.16.4 are now required to regenerate
+* Autoconf 2.71 and aclocal 1.16.5 are now required to regenerate
the :file:`configure` script.
- (Contributed by Christian Heimes in :gh:`89886`.)
+ (Contributed by Christian Heimes in :gh:`89886` and by Victor Stinner in :gh:`112090`.)
* SQLite 3.15.2 or newer is required to build
the :mod:`sqlite3` extension module.
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index e1908133601776..c4558de85f4cf1 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -1,6 +1,6 @@
****************************
- What's New In Python 3.14
+ What's new in Python 3.14
****************************
:Editor: TBD
@@ -56,7 +56,7 @@ For full details, see the :ref:`changelog `.
so it's worth checking back even after reading earlier versions.
-Summary -- Release highlights
+Summary -- release highlights
=============================
.. This section singles out the most important changes in Python 3.14.
@@ -67,12 +67,12 @@ Summary -- Release highlights
-New Features
+New features
============
-.. _whatsnew-314-pep649:
+.. _whatsnew314-pep649:
-PEP 649: Deferred Evaluation of Annotations
+PEP 649: deferred evaluation of annotations
-------------------------------------------
The :term:`annotations ` on functions, classes, and modules are no
@@ -150,12 +150,12 @@ In Python 3.7, :pep:`563` introduced the ``from __future__ import annotations``
directive, which turns all annotations into strings. This directive is now
considered deprecated and it is expected to be removed in a future version of Python.
However, this removal will not happen until after Python 3.13, the last version of
-Python without deferred evaluation of annotations, reaches its end of life.
+Python without deferred evaluation of annotations, reaches its end of life in 2029.
In Python 3.14, the behavior of code using ``from __future__ import annotations``
is unchanged.
-Improved Error Messages
+Improved error messages
-----------------------
* When unpacking assignment fails due to incorrect number of variables, the
@@ -195,16 +195,16 @@ The behavior of :func:`!gc.collect` changes slightly:
(Contributed by Mark Shannon in :gh:`108362`.)
-Other Language Changes
+Other language changes
======================
* Incorrect usage of :keyword:`await` and asynchronous comprehensions
is now detected even if the code is optimized away by the :option:`-O`
- command line option. For example, ``python -O -c 'assert await 1'``
+ command-line option. For example, ``python -O -c 'assert await 1'``
now produces a :exc:`SyntaxError`. (Contributed by Jelle Zijlstra in :gh:`121637`.)
* Writes to ``__debug__`` are now detected even if the code is optimized
- away by the :option:`-O` command line option. For example,
+ away by the :option:`-O` command-line option. For example,
``python -O -c 'assert (__debug__ := 1)'`` now produces a
:exc:`SyntaxError`. (Contributed by Irit Katriel in :gh:`122245`.)
@@ -214,7 +214,7 @@ Other Language Changes
(Contributed by Serhiy Storchaka in :gh:`84978`.)
-New Modules
+New modules
===========
* :mod:`annotationlib`: For introspecting :term:`annotations `.
@@ -222,7 +222,7 @@ New Modules
(Contributed by Jelle Zijlstra in :gh:`119180`.)
-Improved Modules
+Improved modules
================
argparse
@@ -237,7 +237,7 @@ ast
---
* Add :func:`ast.compare` for comparing two ASTs.
- (Contributed by Batuhan Taskaya and Jeremy Hylton in :issue:`15987`.)
+ (Contributed by Batuhan Taskaya and Jeremy Hylton in :gh:`60191`.)
* Add support for :func:`copy.replace` for AST nodes.
(Contributed by Bénédikt Tran in :gh:`121141`.)
@@ -269,6 +269,12 @@ decimal
:meth:`Decimal.from_number() `.
(Contributed by Serhiy Storchaka in :gh:`121798`.)
+datetime
+--------
+
+* Add :meth:`datetime.time.strptime` and :meth:`datetime.date.strptime`.
+ (Contributed by Wannes Boeykens in :gh:`41431`.)
+
dis
---
@@ -277,9 +283,10 @@ dis
This feature is added to the following interfaces via the *show_positions*
keyword argument:
- - :class:`dis.Bytecode`,
- - :func:`dis.dis`, :func:`dis.distb`, and
- - :func:`dis.disassemble`.
+ - :class:`dis.Bytecode`
+ - :func:`dis.dis`
+ - :func:`dis.distb`
+ - :func:`dis.disassemble`
This feature is also exposed via :option:`dis --show-positions`.
(Contributed by Bénédikt Tran in :gh:`123165`.)
@@ -362,7 +369,8 @@ json
of the error.
(Contributed by Serhiy Storchaka in :gh:`122163`.)
-* Enable the :mod:`json` module to work as a script using the :option:`-m` switch: ``python -m json``.
+* Enable the :mod:`json` module to work as a script using the :option:`-m`
+ switch: :program:`python -m json`.
See the :ref:`JSON command-line interface ` documentation.
(Contributed by Trey Hunner in :gh:`122873`.)
@@ -377,12 +385,6 @@ operator
(Contributed by Raymond Hettinger and Nico Mexis in :gh:`115808`.)
-datetime
---------
-
-* Add :meth:`datetime.time.strptime` and :meth:`datetime.date.strptime`.
- (Contributed by Wannes Boeykens in :gh:`41431`.)
-
os
--
@@ -409,11 +411,11 @@ pathlib
pdb
---
-* Hard-coded breakpoints (:func:`breakpoint` and :func:`pdb.set_trace`) now
+* Hardcoded breakpoints (:func:`breakpoint` and :func:`pdb.set_trace`) now
reuse the most recent :class:`~pdb.Pdb` instance that calls
:meth:`~pdb.Pdb.set_trace`, instead of creating a new one each time.
As a result, all the instance specific data like :pdbcmd:`display` and
- :pdbcmd:`commands` are preserved across hard-coded breakpoints.
+ :pdbcmd:`commands` are preserved across hardcoded breakpoints.
(Contributed by Tian Gao in :gh:`121450`.)
* Add a new argument *mode* to :class:`pdb.Pdb`. Disable the ``restart``
@@ -443,9 +445,9 @@ symtable
* Expose the following :class:`symtable.Symbol` methods:
- * :meth:`~symtable.Symbol.is_free_class`
- * :meth:`~symtable.Symbol.is_comp_iter`
* :meth:`~symtable.Symbol.is_comp_cell`
+ * :meth:`~symtable.Symbol.is_comp_iter`
+ * :meth:`~symtable.Symbol.is_free_class`
(Contributed by Bénédikt Tran in :gh:`120029`.)
@@ -532,11 +534,11 @@ ast
* Remove the following classes. They were all deprecated since Python 3.8,
and have emitted deprecation warnings since Python 3.12:
- * :class:`!ast.Num`
- * :class:`!ast.Str`
* :class:`!ast.Bytes`
- * :class:`!ast.NameConstant`
* :class:`!ast.Ellipsis`
+ * :class:`!ast.NameConstant`
+ * :class:`!ast.Num`
+ * :class:`!ast.Str`
Use :class:`ast.Constant` instead. As a consequence of these removals,
user-defined ``visit_Num``, ``visit_Str``, ``visit_Bytes``,
@@ -561,16 +563,16 @@ asyncio
* Remove the following classes and functions. They were all deprecated and
emitted deprecation warnings since Python 3.12:
+ * :func:`!asyncio.get_child_watcher`
+ * :func:`!asyncio.set_child_watcher`
+ * :meth:`!asyncio.AbstractEventLoopPolicy.get_child_watcher`
+ * :meth:`!asyncio.AbstractEventLoopPolicy.set_child_watcher`
* :class:`!asyncio.AbstractChildWatcher`
- * :class:`!asyncio.SafeChildWatcher`
- * :class:`!asyncio.MultiLoopChildWatcher`
* :class:`!asyncio.FastChildWatcher`
- * :class:`!asyncio.ThreadedChildWatcher`
+ * :class:`!asyncio.MultiLoopChildWatcher`
* :class:`!asyncio.PidfdChildWatcher`
- * :meth:`!asyncio.AbstractEventLoopPolicy.get_child_watcher`
- * :meth:`!asyncio.AbstractEventLoopPolicy.set_child_watcher`
- * :func:`!asyncio.get_child_watcher`
- * :func:`!asyncio.set_child_watcher`
+ * :class:`!asyncio.SafeChildWatcher`
+ * :class:`!asyncio.ThreadedChildWatcher`
(Contributed by Kumar Aditya in :gh:`120804`.)
@@ -690,14 +692,14 @@ Changes in the Python API
(Contributed by Serhiy Storchaka in :gh:`69998`.)
-Build Changes
+Build changes
=============
-C API Changes
+C API changes
=============
-New Features
+New features
------------
* Add :c:func:`PyLong_GetSign` function to get the sign of :class:`int` objects.
@@ -707,17 +709,17 @@ New Features
object:
* :c:func:`PyUnicodeWriter_Create`
+ * :c:func:`PyUnicodeWriter_DecodeUTF8Stateful`
* :c:func:`PyUnicodeWriter_Discard`
* :c:func:`PyUnicodeWriter_Finish`
+ * :c:func:`PyUnicodeWriter_Format`
* :c:func:`PyUnicodeWriter_WriteChar`
- * :c:func:`PyUnicodeWriter_WriteUTF8`
- * :c:func:`PyUnicodeWriter_WriteUCS4`
- * :c:func:`PyUnicodeWriter_WriteWideChar`
- * :c:func:`PyUnicodeWriter_WriteStr`
* :c:func:`PyUnicodeWriter_WriteRepr`
+ * :c:func:`PyUnicodeWriter_WriteStr`
* :c:func:`PyUnicodeWriter_WriteSubstring`
- * :c:func:`PyUnicodeWriter_Format`
- * :c:func:`PyUnicodeWriter_DecodeUTF8Stateful`
+ * :c:func:`PyUnicodeWriter_WriteUCS4`
+ * :c:func:`PyUnicodeWriter_WriteUTF8`
+ * :c:func:`PyUnicodeWriter_WriteWideChar`
(Contributed by Victor Stinner in :gh:`119182`.)
@@ -738,14 +740,14 @@ New Features
* Add new functions to convert C ```` numbers from/to Python
:class:`int`:
- * :c:func:`PyLong_FromInt32`
- * :c:func:`PyLong_FromInt64`
- * :c:func:`PyLong_FromUInt32`
- * :c:func:`PyLong_FromUInt64`
* :c:func:`PyLong_AsInt32`
* :c:func:`PyLong_AsInt64`
* :c:func:`PyLong_AsUInt32`
* :c:func:`PyLong_AsUInt64`
+ * :c:func:`PyLong_FromInt32`
+ * :c:func:`PyLong_FromInt64`
+ * :c:func:`PyLong_FromUInt32`
+ * :c:func:`PyLong_FromUInt64`
(Contributed by Victor Stinner in :gh:`120389`.)
@@ -768,20 +770,20 @@ New Features
* Add functions to configure the Python initialization (:pep:`741`):
+ * :c:func:`Py_InitializeFromInitConfig`
+ * :c:func:`PyInitConfig_AddModule`
* :c:func:`PyInitConfig_Create`
* :c:func:`PyInitConfig_Free`
+ * :c:func:`PyInitConfig_FreeStrList`
* :c:func:`PyInitConfig_GetError`
* :c:func:`PyInitConfig_GetExitCode`
- * :c:func:`PyInitConfig_HasOption`
* :c:func:`PyInitConfig_GetInt`
* :c:func:`PyInitConfig_GetStr`
* :c:func:`PyInitConfig_GetStrList`
- * :c:func:`PyInitConfig_FreeStrList`
+ * :c:func:`PyInitConfig_HasOption`
* :c:func:`PyInitConfig_SetInt`
* :c:func:`PyInitConfig_SetStr`
* :c:func:`PyInitConfig_SetStrList`
- * :c:func:`PyInitConfig_AddModule`
- * :c:func:`Py_InitializeFromInitConfig`
(Contributed by Victor Stinner in :gh:`107954`.)
diff --git a/Include/cpython/context.h b/Include/cpython/context.h
index 3c9be7873b9399..3a7a4b459c09ad 100644
--- a/Include/cpython/context.h
+++ b/Include/cpython/context.h
@@ -29,20 +29,11 @@ PyAPI_FUNC(int) PyContext_Exit(PyObject *);
typedef enum {
/*
- * A context has been entered, causing the "current context" to switch to
- * it. The object passed to the watch callback is the now-current
- * contextvars.Context object. Each enter event will eventually have a
- * corresponding exit event for the same context object after any
- * subsequently entered contexts have themselves been exited.
+ * The current context has switched to a different context. The object
+ * passed to the watch callback is the now-current contextvars.Context
+ * object, or None if no context is current.
*/
- Py_CONTEXT_EVENT_ENTER,
- /*
- * A context is about to be exited, which will cause the "current context"
- * to switch back to what it was before the context was entered. The
- * object passed to the watch callback is the still-current
- * contextvars.Context object.
- */
- Py_CONTEXT_EVENT_EXIT,
+ Py_CONTEXT_SWITCHED = 1,
} PyContextEvent;
/*
diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h
index 594fbb1c8e443b..cff2b1f7114793 100644
--- a/Include/internal/pycore_ceval.h
+++ b/Include/internal/pycore_ceval.h
@@ -316,6 +316,8 @@ _Py_eval_breaker_bit_is_set(PyThreadState *tstate, uintptr_t bit)
void _Py_set_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
+PyAPI_FUNC(PyObject *) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value);
+
#ifdef __cplusplus
}
diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h
index 8fec45b1e8d5c3..c18423476d3962 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -1015,13 +1015,13 @@ extern const struct opcode_metadata _PyOpcode_opcode_metadata[266];
#ifdef NEED_OPCODE_METADATA
const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+ [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
[BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
[BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
[BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG },
- [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+ [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
[BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
- [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+ [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
[BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
[BINARY_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[BINARY_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
diff --git a/Include/internal/pycore_stackref.h b/Include/internal/pycore_stackref.h
index 0e6410466b924b..588e57f6cd97e0 100644
--- a/Include/internal/pycore_stackref.h
+++ b/Include/internal/pycore_stackref.h
@@ -76,6 +76,13 @@ PyStackRef_AsPyObjectBorrow(_PyStackRef stackref)
#define PyStackRef_IsDeferred(ref) (((ref).bits & Py_TAG_BITS) == Py_TAG_DEFERRED)
+static inline PyObject *
+PyStackRef_NotDeferred_AsPyObject(_PyStackRef stackref)
+{
+ assert(!PyStackRef_IsDeferred(stackref));
+ return (PyObject *)stackref.bits;
+}
+
static inline PyObject *
PyStackRef_AsPyObjectSteal(_PyStackRef stackref)
{
diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h
index fd41e9a5fe862b..2f0a7fb2f6e549 100644
--- a/Include/internal/pycore_uop_metadata.h
+++ b/Include/internal/pycore_uop_metadata.h
@@ -69,9 +69,9 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_GUARD_BOTH_FLOAT] = HAS_EXIT_FLAG,
[_GUARD_NOS_FLOAT] = HAS_EXIT_FLAG,
[_GUARD_TOS_FLOAT] = HAS_EXIT_FLAG,
- [_BINARY_OP_MULTIPLY_FLOAT] = HAS_PURE_FLAG,
- [_BINARY_OP_ADD_FLOAT] = HAS_PURE_FLAG,
- [_BINARY_OP_SUBTRACT_FLOAT] = HAS_PURE_FLAG,
+ [_BINARY_OP_MULTIPLY_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_ADD_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_SUBTRACT_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
[_GUARD_BOTH_UNICODE] = HAS_EXIT_FLAG,
[_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
[_BINARY_OP_INPLACE_ADD_UNICODE] = HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG,
diff --git a/InternalDocs/README.md b/InternalDocs/README.md
index 805e2f97937e1e..0a6ecf899458ed 100644
--- a/InternalDocs/README.md
+++ b/InternalDocs/README.md
@@ -11,6 +11,8 @@ The core dev team attempts to keep this documentation up to date. If
it is not, please report that through the
[issue tracker](https://github.com/python/cpython/issues).
+Index:
+-----
[Guide to the parser](parser.md)
diff --git a/Lib/_pyrepl/console.py b/Lib/_pyrepl/console.py
index 3e72a56807f6fb..03266c4dfc2dd8 100644
--- a/Lib/_pyrepl/console.py
+++ b/Lib/_pyrepl/console.py
@@ -174,7 +174,13 @@ def _excepthook(self, typ, value, tb):
def runsource(self, source, filename="", symbol="single"):
try:
- tree = ast.parse(source)
+ tree = self.compile.compiler(
+ source,
+ filename,
+ "exec",
+ ast.PyCF_ONLY_AST,
+ incomplete_input=False,
+ )
except (SyntaxError, OverflowError, ValueError):
self.showsyntaxerror(filename, source=source)
return False
@@ -185,7 +191,7 @@ def runsource(self, source, filename="", symbol="single"):
the_symbol = symbol if stmt is last_stmt else "exec"
item = wrapper([stmt])
try:
- code = self.compile.compiler(item, filename, the_symbol, dont_inherit=True)
+ code = self.compile.compiler(item, filename, the_symbol)
except SyntaxError as e:
if e.args[0] == "'await' outside function":
python = os.path.basename(sys.executable)
diff --git a/Lib/_strptime.py b/Lib/_strptime.py
index 89adc174e5ad30..5f4d2475c0169b 100644
--- a/Lib/_strptime.py
+++ b/Lib/_strptime.py
@@ -15,6 +15,7 @@
import locale
import calendar
from re import compile as re_compile
+from re import sub as re_sub
from re import IGNORECASE
from re import escape as re_escape
from datetime import (date as datetime_date,
@@ -129,11 +130,23 @@ def __calc_date_time(self):
time_tuple = time.struct_time((1999,3,17,22,44,55,2,76,0))
time_tuple2 = time.struct_time((1999,1,3,1,1,1,6,3,0))
replacement_pairs = [
- ('1999', '%Y'), ('99', '%y'), ('22', '%H'),
- ('44', '%M'), ('55', '%S'), ('76', '%j'),
- ('17', '%d'), ('03', '%m'), ('3', '%m'),
- # '3' needed for when no leading zero.
- ('2', '%w'), ('10', '%I')]
+ ('1999', '%Y'), ('99', '%y'), ('22', '%H'),
+ ('44', '%M'), ('55', '%S'), ('76', '%j'),
+ ('17', '%d'), ('03', '%m'), ('3', '%m'),
+ # '3' needed for when no leading zero.
+ ('2', '%w'), ('10', '%I'),
+ # Non-ASCII digits
+ ('\u0661\u0669\u0669\u0669', '%Y'),
+ ('\u0669\u0669', '%Oy'),
+ ('\u0662\u0662', '%OH'),
+ ('\u0664\u0664', '%OM'),
+ ('\u0665\u0665', '%OS'),
+ ('\u0661\u0667', '%Od'),
+ ('\u0660\u0663', '%Om'),
+ ('\u0663', '%Om'),
+ ('\u0662', '%Ow'),
+ ('\u0661\u0660', '%OI'),
+ ]
date_time = []
for directive in ('%c', '%x', '%X'):
current_format = time.strftime(directive, time_tuple).lower()
@@ -158,6 +171,10 @@ def __calc_date_time(self):
for tz in tz_values:
if tz:
current_format = current_format.replace(tz, "%Z")
+ # Transform all non-ASCII digits to digits in range U+0660 to U+0669.
+ current_format = re_sub(r'\d(?3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])",
'f': r"(?P[0-9]{1,6})",
@@ -296,11 +313,15 @@ def __init__(self, locale_time=None):
'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone
for tz in tz_names),
'Z'),
- '%': '%'})
- base.__setitem__('W', base.__getitem__('U').replace('U', 'W'))
- base.__setitem__('c', self.pattern(self.locale_time.LC_date_time))
- base.__setitem__('x', self.pattern(self.locale_time.LC_date))
+ '%': '%'}
+ for d in 'dmyHIMS':
+ mapping['O' + d] = r'(?P<%s>\d\d|\d| \d)' % d
+ mapping['Ow'] = r'(?P\d)'
+ mapping['W'] = mapping['U'].replace('U', 'W')
+ base.__init__(mapping)
base.__setitem__('X', self.pattern(self.locale_time.LC_time))
+ base.__setitem__('x', self.pattern(self.locale_time.LC_date))
+ base.__setitem__('c', self.pattern(self.locale_time.LC_date_time))
def __seqToRE(self, to_convert, directive):
"""Convert a list to a regex string for matching a directive.
@@ -328,28 +349,25 @@ def pattern(self, format):
regex syntax are escaped.
"""
- processed_format = ''
# The sub() call escapes all characters that might be misconstrued
# as regex syntax. Cannot use re.escape since we have to deal with
# format directives (%m, etc.).
- regex_chars = re_compile(r"([\\.^$*+?\(\){}\[\]|])")
- format = regex_chars.sub(r"\\\1", format)
- whitespace_replacement = re_compile(r'\s+')
- format = whitespace_replacement.sub(r'\\s+', format)
+ format = re_sub(r"([\\.^$*+?\(\){}\[\]|])", r"\\\1", format)
+ format = re_sub(r'\s+', r'\\s+', format)
+ format = re_sub(r"'", "['\u02bc]", format) # needed for br_FR
year_in_format = False
day_of_month_in_format = False
- while '%' in format:
- directive_index = format.index('%')+1
- format_char = format[directive_index]
- processed_format = "%s%s%s" % (processed_format,
- format[:directive_index-1],
- self[format_char])
- format = format[directive_index+1:]
+ def repl(m):
+ format_char = m[1]
match format_char:
case 'Y' | 'y' | 'G':
+ nonlocal year_in_format
year_in_format = True
case 'd':
+ nonlocal day_of_month_in_format
day_of_month_in_format = True
+ return self[format_char]
+ format = re_sub(r'%(O?.)', repl, format)
if day_of_month_in_format and not year_in_format:
import warnings
warnings.warn("""\
@@ -360,7 +378,7 @@ def pattern(self, format):
See https://github.com/python/cpython/issues/70647.""",
DeprecationWarning,
skip_file_prefixes=(os.path.dirname(__file__),))
- return "%s%s" % (processed_format, format)
+ return format
def compile(self, format):
"""Return a compiled re object for the format string."""
@@ -434,8 +452,8 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
_regex_cache[format] = format_regex
found = format_regex.match(data_string)
if not found:
- raise ValueError("time data %r does not match format %r :: /%s/" %
- (data_string, format, format_regex.pattern))
+ raise ValueError("time data %r does not match format %r" %
+ (data_string, format))
if len(data_string) != found.end():
raise ValueError("unconverted data remains: %s" %
data_string[found.end():])
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 5f6fa2348726cf..c95fce035cd548 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -190,8 +190,7 @@ def result(self):
the future is done and has an exception set, this exception is raised.
"""
if self._state == _CANCELLED:
- exc = self._make_cancelled_error()
- raise exc
+ raise self._make_cancelled_error()
if self._state != _FINISHED:
raise exceptions.InvalidStateError('Result is not ready.')
self.__log_traceback = False
@@ -208,8 +207,7 @@ def exception(self):
InvalidStateError.
"""
if self._state == _CANCELLED:
- exc = self._make_cancelled_error()
- raise exc
+ raise self._make_cancelled_error()
if self._state != _FINISHED:
raise exceptions.InvalidStateError('Exception is not set.')
self.__log_traceback = False
diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py
index f2ee9648c43876..9fa772ca9d02cc 100644
--- a/Lib/asyncio/taskgroups.py
+++ b/Lib/asyncio/taskgroups.py
@@ -66,6 +66,20 @@ async def __aenter__(self):
return self
async def __aexit__(self, et, exc, tb):
+ tb = None
+ try:
+ return await self._aexit(et, exc)
+ finally:
+ # Exceptions are heavy objects that can have object
+ # cycles (bad for GC); let's not keep a reference to
+ # a bunch of them. It would be nicer to use a try/finally
+ # in __aexit__ directly but that introduced some diff noise
+ self._parent_task = None
+ self._errors = None
+ self._base_error = None
+ exc = None
+
+ async def _aexit(self, et, exc):
self._exiting = True
if (exc is not None and
@@ -122,7 +136,10 @@ async def __aexit__(self, et, exc, tb):
assert not self._tasks
if self._base_error is not None:
- raise self._base_error
+ try:
+ raise self._base_error
+ finally:
+ exc = None
if self._parent_cancel_requested:
# If this flag is set we *must* call uncancel().
@@ -133,8 +150,14 @@ async def __aexit__(self, et, exc, tb):
# Propagate CancelledError if there is one, except if there
# are other errors -- those have priority.
- if propagate_cancellation_error is not None and not self._errors:
- raise propagate_cancellation_error
+ try:
+ if propagate_cancellation_error is not None and not self._errors:
+ try:
+ raise propagate_cancellation_error
+ finally:
+ exc = None
+ finally:
+ propagate_cancellation_error = None
if et is not None and not issubclass(et, exceptions.CancelledError):
self._errors.append(exc)
@@ -146,14 +169,14 @@ async def __aexit__(self, et, exc, tb):
if self._parent_task.cancelling():
self._parent_task.uncancel()
self._parent_task.cancel()
- # Exceptions are heavy objects that can have object
- # cycles (bad for GC); let's not keep a reference to
- # a bunch of them.
try:
- me = BaseExceptionGroup('unhandled errors in a TaskGroup', self._errors)
- raise me from None
+ raise BaseExceptionGroup(
+ 'unhandled errors in a TaskGroup',
+ self._errors,
+ ) from None
finally:
- self._errors = None
+ exc = None
+
def create_task(self, coro, *, name=None, context=None):
"""Create a new task in this group and return it.
diff --git a/Lib/codeop.py b/Lib/codeop.py
index a0276b52d484e3..adf000ba29f88c 100644
--- a/Lib/codeop.py
+++ b/Lib/codeop.py
@@ -44,6 +44,7 @@
# Caveat emptor: These flags are undocumented on purpose and depending
# on their effect outside the standard library is **unsupported**.
PyCF_DONT_IMPLY_DEDENT = 0x200
+PyCF_ONLY_AST = 0x400
PyCF_ALLOW_INCOMPLETE_INPUT = 0x4000
def _maybe_compile(compiler, source, filename, symbol):
@@ -109,12 +110,14 @@ class Compile:
def __init__(self):
self.flags = PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT
- def __call__(self, source, filename, symbol, **kwargs):
- flags = self.flags
+ def __call__(self, source, filename, symbol, flags=0, **kwargs):
+ flags |= self.flags
if kwargs.get('incomplete_input', True) is False:
flags &= ~PyCF_DONT_IMPLY_DEDENT
flags &= ~PyCF_ALLOW_INCOMPLETE_INPUT
codeob = compile(source, filename, symbol, flags, True)
+ if flags & PyCF_ONLY_AST:
+ return codeob # this is an ast.Module in this case
for feature in _features:
if codeob.co_flags & feature.compiler_flag:
self.flags |= feature.compiler_flag
diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html
index 827d230b54e159..2a4adc6a4d395f 100644
--- a/Lib/idlelib/help.html
+++ b/Lib/idlelib/help.html
@@ -5,7 +5,7 @@
- IDLE — Python 3.13.0a2 documentation
+ IDLE — Python 3.14.0a0 documentation
@@ -18,7 +18,7 @@
@@ -26,6 +26,7 @@
+
@@ -45,6 +46,8 @@
+
+
@@ -184,7 +187,7 @@