
****************************
  What's new in Python 3.15
****************************

:Editor: Hugo van Kemenade

.. Rules for maintenance:

   * Anyone can add text to this document.  Do not spend very much time
   on the wording of your changes, because your text will probably
   get rewritten to some degree.

   * The maintainer will go through Misc/NEWS periodically and add
   changes; it's therefore more important to add your changes to
   Misc/NEWS than to this file.

   * This is not a complete list of every single change; completeness
   is the purpose of Misc/NEWS.  Some changes I consider too small
   or esoteric to include.  If such a change is added to the text,
   I'll just remove it.  (This is another reason you shouldn't spend
   too much time on writing your addition.)

   * If you want to draw your new text to the attention of the
   maintainer, add 'XXX' to the beginning of the paragraph or
   section.

   * It's OK to just add a fragmentary note about a change.  For
   example: "XXX Describe the transmogrify() function added to the
   socket module."  The maintainer will research the change and
   write the necessary text.

   * You can comment out your additions if you like, but it's not
   necessary (especially when a final release is some months away).

   * Credit the author of a patch or bugfix.   Just the name is
   sufficient; the e-mail address isn't necessary.

   * It's helpful to add the issue number as a comment:

   XXX Describe the transmogrify() function added to the socket
   module.
   (Contributed by P.Y. Developer in :gh:`12345`.)

   This saves the maintainer the effort of going through the VCS log
   when researching a change.

This article explains the new features in Python 3.15, compared to 3.14.

For full details, see the :ref:`changelog <changelog>`.

.. note::

   Prerelease users should be aware that this document is currently in draft
   form. It will be updated substantially as Python 3.15 moves towards release,
   so it's worth checking back even after reading earlier versions.


Summary -- Release highlights
=============================

.. This section singles out the most important changes in Python 3.15.
   Brevity is key.


.. PEP-sized items next.

* :pep:`810`: :ref:`Explicit lazy imports for faster startup times
  <whatsnew315-lazy-imports>`
* :pep:`814`: :ref:`Add frozendict built-in type
  <whatsnew315-frozendict>`
* :pep:`661`: :ref:`Add sentinel built-in type
  <whatsnew315-sentinel>`
* :pep:`799`: :ref:`A dedicated profiling package for organizing Python
  profiling tools <whatsnew315-profiling-package>`
* :pep:`799`: :ref:`Tachyon: High frequency statistical sampling profiler
  <whatsnew315-sampling-profiler>`
* :pep:`831`: :ref:`Frame pointers are enabled by default for improved
  system-level observability <whatsnew315-frame-pointers>`
* :pep:`798`: :ref:`Unpacking in comprehensions
  <whatsnew315-unpacking-in-comprehensions>`
* :pep:`686`: :ref:`Python now uses UTF-8 as the default encoding
  <whatsnew315-utf8-default>`
* :pep:`829`: :ref:`Package startup configuration files <whatsnew315-startup-files>`
* :pep:`728`: :ref:`TypedDict with typed extra items <whatsnew315-typeddict>`
* :pep:`747`: :ref:`Annotating type forms with TypeForm
  <whatsnew315-typeform>`
* :pep:`800`: :ref:`Disjoint bases in the type system <whatsnew315-disjoint-base>`
* :pep:`782`: :ref:`A new PyBytesWriter C API to create a Python bytes object
  <whatsnew315-pybyteswriter>`
* :pep:`803`, :pep:`820 <820>`, :pep:`793 <793>`:
  :ref:`Stable ABI for free-threaded builds <whatsnew315-abi3t>` and
  related C API
* :pep:`788`: :ref:`Protection against finalization in the C API <whatsnew315-c-api-interpreter-finalization>`
* :ref:`The JIT compiler has been significantly upgraded <whatsnew315-jit>`
* :ref:`The official Windows 64-bit binaries now use the tail-calling interpreter
  <whatsnew315-windows-tail-calling-interpreter>`
* :ref:`Improved error messages <whatsnew315-improved-error-messages>`
* :ref:`More color <whatsnew315-more-color>`


New features
============

.. _whatsnew315-lazy-imports:

:pep:`810`: Explicit lazy imports
---------------------------------

Large Python applications often suffer from slow startup times. A
significant contributor to this problem is the import system: when a module
is imported, Python must locate the file, read it from disk, compile it to
bytecode, and execute all top-level code. For applications with deep
dependency trees, this process can take seconds, even when most of the
imported code is never actually used during a particular run.

Developers have worked around this by moving imports inside functions, using
:mod:`importlib` to load modules on demand, or restructuring code to avoid
unnecessary dependencies. These approaches work but make code harder to read
and maintain, scatter import statements throughout the codebase, and require
discipline to apply consistently.

Python now provides a cleaner solution through explicit :keyword:`lazy`
imports using the new ``lazy`` soft keyword. When you mark an import as
lazy, Python defers the actual module loading until the imported name is
first used. This gives you the organizational benefits of declaring all
imports at the top of the file while only paying the loading cost for
modules you actually use.

The ``lazy`` keyword works with both ``import`` and ``from ... import``
statements. When you write ``lazy import heavy_module``, Python does not
immediately load the module. Instead, it creates a lightweight proxy object.
The actual module loading happens transparently when you first access the
name:

.. code-block:: python

   lazy import json
   lazy from pathlib import Path

   print("Starting up...")  # json and pathlib not loaded yet

   data = json.loads('{"key": "value"}')  # json loads here
   p = Path(".")  # pathlib loads here

This mechanism is particularly useful for applications that import many
modules at the top level but may only use a subset of them in any given run.
The deferred loading reduces startup latency without requiring code
restructuring or conditional imports scattered throughout the codebase.

In the case where loading a lazily imported module fails (for example, if
the module does not exist), Python raises the exception at the point of
first use rather than at import time. The associated traceback includes both
the location where the name was accessed and the original import statement,
making it straightforward to diagnose and debug the failure.

For cases where you want to enable lazy loading globally without modifying
source code, Python provides the :option:`-X lazy_imports <-X>` command-line
option and the :envvar:`PYTHON_LAZY_IMPORTS` environment variable. Both
accept two values: ``all`` makes all imports lazy by default, and ``normal``
(the default) respects the ``lazy`` keyword in source code. The
:func:`sys.set_lazy_imports` and :func:`sys.get_lazy_imports` functions allow
changing and querying this mode at runtime.

For more selective control, :func:`sys.set_lazy_imports_filter` accepts a
callable that determines whether a specific module should be loaded lazily.
The filter receives three arguments: the importing module's name (or
``None``), the imported module's name, and the fromlist (or ``None`` for
regular imports). It should return ``True`` to allow the import to be lazy,
or ``False`` to force eager loading. This allows patterns like making only
your own application's modules lazy while keeping third-party dependencies
eager:

.. code-block:: python

   import sys

   def myapp_filter(importing, imported, fromlist):
       return imported.startswith("myapp.")
   sys.set_lazy_imports_filter(myapp_filter)
   sys.set_lazy_imports("all")

   import myapp.slow_module  # lazy (matches filter)
   import json               # eager (does not match filter)

The proxy type itself is available as :class:`types.LazyImportType` for code
that needs to detect lazy imports programmatically.

There are some restrictions on where the ``lazy`` keyword can be used. Lazy
imports are only permitted at module scope; using ``lazy`` inside a
function, class body, or ``try``/``except``/``finally`` block raises a
:exc:`SyntaxError`. Neither star imports nor future imports can be lazy
(``lazy from module import *`` and ``lazy from __future__ import ...`` both
raise :exc:`SyntaxError`).

For code that cannot use the ``lazy`` keyword directly (for example, when
supporting Python versions older than 3.15 while still using lazy
imports on 3.15+), a module can define
:attr:`~module.__lazy_modules__` as a container of fully qualified module
name strings.  Regular ``import`` statements for those modules are then treated
as lazy, with the same semantics as the ``lazy`` keyword::

   __lazy_modules__ = ["json", "pathlib"]

   import json     # lazy
   import os       # still eager

.. seealso:: :pep:`810` for the full specification and rationale.

(Contributed by Pablo Galindo Salgado and Dino Viehland in :gh:`142349`.)


.. _whatsnew315-frozendict:

:pep:`814`: Add frozendict built-in type
----------------------------------------

A new :term:`immutable` type, :class:`frozendict`, is added to the :mod:`builtins` module.
It does not allow modification after creation. A :class:`!frozendict` is not a subclass of ``dict``;
it inherits directly from ``object``. A :class:`!frozendict` is :term:`hashable`
as long as all of its keys and values are hashable. A :class:`!frozendict` preserves
insertion order, but comparison does not take order into account.

For example::

    >>> a = frozendict(x=1, y=2)
    >>> a
    frozendict({'x': 1, 'y': 2})
    >>> a['z'] = 3
    Traceback (most recent call last):
      File "<python-input-2>", line 1, in <module>
        a['z'] = 3
        ~^^^^^
    TypeError: 'frozendict' object does not support item assignment
    >>> b = frozendict(y=2, x=1)
    >>> hash(a) == hash(b)
    True
    >>> a == b
    True

The following standard library modules have been updated to accept
:class:`!frozendict`: :mod:`copy`, :mod:`decimal`, :mod:`json`, :mod:`marshal`,
:mod:`plistlib` (only for serialization), :mod:`pickle`, :mod:`pprint` and
:mod:`xml.etree.ElementTree`.

:func:`eval` and :func:`exec` accept :class:`!frozendict` for *globals*, and
:func:`type` and :meth:`str.maketrans` accept :class:`!frozendict` for *dict*.

Code checking for :class:`dict` type using ``isinstance(arg, dict)`` can be
updated to ``isinstance(arg, (dict, frozendict))`` to accept also the
:class:`!frozendict` type, or to ``isinstance(arg, collections.abc.Mapping)``
to accept also other mapping types such as :class:`~types.MappingProxyType`.

.. seealso:: :pep:`814` for the full specification and rationale.

(Contributed by Victor Stinner and Donghee Na in :gh:`141510`.)


.. _whatsnew315-sentinel:

:pep:`661`: Add sentinel built-in type
--------------------------------------

A new :class:`sentinel` type is added to the :mod:`builtins` module for
creating unique sentinel values with a concise representation.  Sentinel
objects preserve identity when copied, support use in type expressions with
the ``|`` operator, and can be pickled when they are importable by module and
name.

(PEP by Tal Einat; contributed by Jelle Zijlstra in :gh:`148829`.)

.. seealso:: :pep:`661` for further details.


.. _whatsnew315-profiling-package:

:pep:`799`: A dedicated profiling package
-----------------------------------------

A new :mod:`profiling` module has been added to organize Python's built-in
profiling tools under a single, coherent namespace. This module contains:

* :mod:`profiling.tracing`: deterministic function-call tracing (relocated from
  ``cProfile``).
* :mod:`profiling.sampling`: a new statistical sampling profiler (named Tachyon).

The ``cProfile`` module remains as an alias for backwards compatibility.
The :mod:`profile` module is deprecated and will be removed in Python 3.17.

.. seealso:: :pep:`799` for further details.

(Contributed by Pablo Galindo and László Kiss Kollár in :gh:`138122`.)


.. _whatsnew315-sampling-profiler:

Tachyon: High frequency statistical sampling profiler
-----------------------------------------------------

.. image:: ../../Lib/profiling/sampling/_assets/tachyon-logo.png
   :alt: Tachyon profiler logo
   :align: center
   :width: 200px

A new statistical sampling profiler (Tachyon) has been added as
:mod:`profiling.sampling`. This profiler enables low-overhead performance analysis of
running Python processes without requiring code modification or process restart.

Unlike deterministic profilers (such as :mod:`profiling.tracing`) that instrument
every function call, the sampling profiler periodically captures stack traces from
running processes.  This approach provides virtually zero overhead while achieving
sampling rates of **up to 1,000,000 Hz**, making it the fastest sampling profiler
available for Python (at the time of its contribution) and ideal for debugging
performance issues in production environments. This capability is particularly
valuable for debugging performance issues in production systems where traditional
profiling approaches would be too intrusive.

Key features include:

* **Zero-overhead profiling**: Attach to any running Python process without
  affecting its performance. Ideal for production debugging where you can't afford
  to restart or slow down your application.

* **No code modification required**: Profile existing applications without restart.
  Simply point the profiler at a running process by PID and start collecting data.

* **Flexible target modes**:

  * Profile running processes by PID (``attach``) - attach to already-running applications
  * Run and profile scripts directly (``run``) - profile from the very start of execution
  * Execute and profile modules (``run -m``) - profile packages run as ``python -m module``
  * Capture a one-shot snapshot of a running process (``dump``) - print a
    traceback-style stack of every thread (or all asyncio tasks with
    ``--async-aware``). Useful for investigating hung processes.

* **Multiple profiling modes**: Choose what to measure based on your performance investigation:

  * **Wall-clock time** (``--mode wall``, default): Measures real elapsed time including I/O,
    network waits, and blocking operations. Use this to understand where your program spends
    calendar time, including when waiting for external resources.
  * **CPU time** (``--mode cpu``): Measures only active CPU execution time, excluding I/O waits
    and blocking. Use this to identify CPU-bound bottlenecks and optimize computational work.
  * **GIL-holding time** (``--mode gil``): Measures time spent holding Python's Global Interpreter
    Lock. Use this to identify which threads dominate GIL usage in multi-threaded applications.
  * **Exception handling time** (``--mode exception``): Captures samples only from threads with
    an active exception. Use this to analyze exception handling overhead.

* **Thread-aware profiling**: Option to profile all threads (``-a``) or just the main thread,
  essential for understanding multi-threaded application behavior.

* **Multiple output formats**: Choose the visualization that best fits your workflow:

  * ``--pstats``: Detailed tabular statistics compatible with :mod:`pstats`. Shows function-level
    timing with direct and cumulative samples. Best for detailed analysis and integration with
    existing Python profiling tools.
  * ``--collapsed``: Generates collapsed stack traces (one line per stack). This format is
    specifically designed for creating flame graphs with external tools like Brendan Gregg's
    FlameGraph scripts or speedscope.
  * ``--flamegraph``: Generates a self-contained interactive HTML flame graph using D3.js.
    Opens directly in your browser for immediate visual analysis. Flame graphs show the call
    hierarchy where width represents time spent, making it easy to spot bottlenecks at a glance.
  * ``--gecko``: Generates Gecko Profiler format compatible with `Firefox Profiler
    <https://profiler.firefox.com>`__. Upload the output to Firefox Profiler for advanced
    timeline-based analysis with features like stack charts, markers, and network activity.
  * ``--heatmap``: Generates an interactive HTML heatmap visualization with line-level sample
    counts. Creates a directory with per-file heatmaps showing exactly where time is spent
    at the source code level.

* **Live interactive mode**: Real-time TUI profiler with a top-like interface (``--live``).
  Monitor performance as your application runs with interactive sorting and filtering.

* **Async-aware profiling**: Profile async/await code with task-based stack reconstruction
  (``--async-aware``). See which coroutines are consuming time, with options to show only
  running tasks or all tasks including those waiting.

* **Opcode-level profiling**: Gather bytecode opcode information for instruction-level
  profiling (``--opcodes``). Shows which bytecode instructions are executing, including
  specializations from the adaptive interpreter.

See :mod:`profiling.sampling` for the complete documentation, including all
available output formats, profiling modes, and configuration options.

(Contributed by Pablo Galindo and László Kiss Kollár in :gh:`135953` and :gh:`138122`.)


.. _whatsnew315-frame-pointers:

:pep:`831`: Frame pointers enabled by default
---------------------------------------------

CPython is now built with frame pointers by default on platforms that support
them.  This uses the compiler flags ``-fno-omit-frame-pointer`` and
``-mno-omit-leaf-frame-pointer``, making native stack unwinding faster and
more reliable for system profilers, debuggers, crash analysis tools, and
eBPF-based observability tools.

The flags are exposed through :mod:`sysconfig`, so extension modules built by
tools that consume Python's build configuration inherit frame pointers by
default.  This propagation is intentional: mixed Python/native profiling needs
an unbroken frame-pointer chain through the interpreter, extension modules,
embedding applications, and native libraries.

.. important::

   Third-party build backends and native build systems should preserve these
   flags when they consume Python's :mod:`sysconfig` values.  Build systems
   that compile C, C++, Rust, or other native code without inheriting Python's
   compiler flags should enable equivalent frame-pointer flags themselves.  A
   single native component built without frame pointers can break stack
   unwinding for the whole Python process.

(Contributed by Pablo Galindo Salgado and Savannah Ostrowski in
:gh:`149201`; PEP 831 written by Pablo Galindo Salgado, Ken Jin,
Savannah Ostrowski, and Diego Russo.)

.. seealso:: :pep:`831` for further details.


.. _whatsnew315-unpacking-in-comprehensions:

:pep:`798`: Unpacking in comprehensions
---------------------------------------

List, set, and dictionary comprehensions, as well as generator expressions, now
support unpacking with ``*`` and ``**``.  This extends the unpacking syntax
from :pep:`448` to comprehensions, providing a new syntax for combining an
arbitrary number of iterables or dictionaries into a single flat structure.
This new syntax is a direct alternative to nested comprehensions,
:func:`itertools.chain`, and :meth:`itertools.chain.from_iterable`.  For
example::

    >>> lists = [[1, 2], [3, 4], [5]]
    >>> [*L for L in lists]  # equivalent to [x for L in lists for x in L]
    [1, 2, 3, 4, 5]

    >>> sets = [{1, 2}, {2, 3}, {3, 4}]
    >>> {*s for s in sets}  # equivalent to {x for s in sets for x in s}
    {1, 2, 3, 4}

    >>> dicts = [{'a': 1}, {'b': 2}, {'a': 3}]
    >>> {**d for d in dicts}  # equivalent to {k: v for d in dicts for k,v in d.items()}
    {'a': 3, 'b': 2}

Generator expressions can similarly use unpacking to yield values from multiple
iterables::

    >>> gen = (*L for L in lists)  # equivalent to (x for L in lists for x in L)
    >>> list(gen)
    [1, 2, 3, 4, 5]

This change also extends to asynchronous generator expressions, such that, for
example, ``(*a async for a in agen())`` is equivalent to ``(x async for a in
agen() for x in a)``.

.. seealso:: :pep:`798` for further details.

(Contributed by Adam Hartz in :gh:`143055`.)

.. _whatsnew315-startup-files:

:pep:`829`: Package startup configuration files
-----------------------------------------------

Loaded by the :mod:`site` module when ``-S`` is not given, :ref:`.pth files <site-pth-files>`
can contain lines that both extend :data:`sys.path` and execute arbitrary code
when the line starts with ``import`` (followed by a space or tab).  The latter
functionality can be problematic, since it is difficult to know exactly what
gets executed when Python starts up.

As a step towards improving the ability to audit pre-start executable code,
Python 3.15 introduces :ref:`.start files <site-start-files>` which contain entry point
specifications of the form ``pkg.mod:callable`` where ``pkg.mod`` is the
import path to the given callable.  When Python starts up, the callable is
located and called with no arguments.

``import`` lines in :file:`.pth` files are silently deprecated.  When a
matching :file:`.start` file is found, ``import`` lines in :file:`.pth` files
are ignored.  There is no change to :data:`sys.path` extension lines in
:file:`.pth` files.

The :mod:`site` module also provides :class:`site.StartupState` to batch
startup processing for multiple site directories, ensuring all static path
extensions are applied before any startup code is executed.  :func:`site.main`
uses an instance of this class implicitly to batch process all startup
configuration files during normal interpreter startup.  Callers needing the
same batching behavior can build a :class:`~site.StartupState` directly and
drive it with :meth:`~site.StartupState.addsitedir`,
:meth:`~site.StartupState.addusersitepackages`, and
:meth:`~site.StartupState.addsitepackages`, then call
:meth:`~site.StartupState.process` once at the end of the batch.

(Contributed by Barry Warsaw in :gh:`148641` and :gh:`150228`.)


.. _whatsnew315-abi3t:

:pep:`803`: Stable ABI for free-threaded builds
-----------------------------------------------

C extensions that target the :ref:`Stable ABI <stable-abi>` can now be
compiled for the new *Stable ABI for Free-Threaded Builds* (also known
as ``abi3t``), which makes them compatible with
:term:`free-threaded builds <free-threaded build>` of CPython.
This usually requires some non-trivial changes to the source code;
specifically:

- Switching to API introduced in :pep:`697` (Python 3.12), such as
  negative :c:member:`~PyType_Spec.basicsize` and
  :c:func:`PyObject_GetTypeData`, rather than making :c:type:`PyObject`
  part of the instance struct; and
- Switching from a ``PyInit_`` function to a new export hook,
  :c:func:`PyModExport_* <PyModExport_modulename>`, introduced for this
  purpose in :pep:`793`, with a new :c:type:`PySlot` structure
  introduced in :pep:`820`.

Note that Stable ABI does not offer all the functionality that CPython
has to offer.
Extensions that cannot switch to ``abi3t`` should continue to build for
the existing Stable ABI (``abi3``) and the version-specific ABI for
free-threading (``cp315t``) separately.

Stable ABI for Free-Threaded Builds should typically
be selected in a build tool (such as, for example, Setuptools, meson-python,
scikit-build-core, or Maturin).
At the time of writing, these tools do **not** support ``abi3t``.
If this is the case for your tool, compile for ``cp315t`` separately.
If not using a build tool -- or when writing such a tool -- you can select
``abi3t`` by setting the macro :c:macro:`!Py_TARGET_ABI3T` as discussed
in :ref:`abi3-compiling`.

A practical :ref:`migration guide <abi3t-migration-howto>` for switching to
``abi3t`` is available.

.. seealso:: :pep:`803` for further details.


.. _whatsnew315-c-api-interpreter-finalization:

:pep:`788`: Protecting the C API from interpreter finalization
--------------------------------------------------------------

In the C API, :term:`interpreter finalization <interpreter shutdown>` can be
problematic for many extensions, because :term:`attaching <attached thread
state>` a thread state will permanently hang the thread, resulting in deadlocks
and other spurious issues. Additionally, it has historically been impossible
to safely check whether an interpreter is alive before using it, leading to crashes
when a thread concurrently deletes an interpreter while another thread is
trying to attach to it.

There are now several new suites of APIs to circumvent these problems:

* :ref:`Interpreter guards <interpreter-guards>`, which prevent an interpreter
  from finalizing.
* :ref:`Interpreter views <interpreter-views>`, which allow thread-safe access
  to an interpreter that may be concurrently finalizing or deleted.
* :ref:`New APIs <c-api-attach-detach>` to automatically attach and detach
  thread states that come with built-in protection against finalization.

In addition, APIs in the ``PyGILState`` family (most notably
:c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release`) have been
:term:`soft deprecated`. There is **no** plan to remove them, and existing
code will continue to work, but there will be no new ``PyGILState`` APIs
in future versions of Python.

.. seealso:: :pep:`788` for further details.

(Contributed by Peter Bierma in :gh:`149101`.)


.. _whatsnew315-improved-error-messages:

Improved error messages
-----------------------

* The interpreter now provides more helpful suggestions in :exc:`AttributeError`
  exceptions when accessing an attribute on an object that does not exist, but
  a similar attribute is available through one of its members.

  For example, if the object has an attribute that itself exposes the requested
  name, the error message will suggest accessing it via that inner attribute:

  .. code-block:: python

     @dataclass
     class Circle:
        radius: float

        @property
        def area(self) -> float:
           return pi * self.radius**2

     class Container:
        def __init__(self, inner: Circle) -> None:
           self.inner = inner

     circle = Circle(radius=4.0)
     container = Container(circle)
     print(container.area)

  Running this code now produces a clearer suggestion:

  .. code-block:: pytb

     Traceback (most recent call last):
       File "/home/pablogsal/github/python/main/lel.py", line 42, in <module>
         print(container.area)
               ^^^^^^^^^^^^^^
     AttributeError: 'Container' object has no attribute 'area'. Did you mean '.inner.area' instead of '.area'?

* When an :exc:`AttributeError` on a builtin type has no close match via
  Levenshtein distance, the error message now checks a static table of common
  method names from other languages (JavaScript, Java, Ruby, C#) and suggests
  the Python equivalent:

  .. doctest::

     >>> [1, 2, 3].push(4)  # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
     AttributeError: 'list' object has no attribute 'push'. Did you mean '.append'?

     >>> 'hello'.toUpperCase()  # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
     AttributeError: 'str' object has no attribute 'toUpperCase'. Did you mean '.upper'?

  When the Python equivalent is a language construct rather than a method,
  the hint describes the construct directly:

  .. doctest::

     >>> {}.put("a", 1)  # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
     AttributeError: 'dict' object has no attribute 'put'. Use d[k] = v.

  When a mutable method is called on an immutable type, the hint suggests
  the mutable counterpart:

  .. doctest::

     >>> (1, 2, 3).append(4)  # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
     AttributeError: 'tuple' object has no attribute 'append'. Did you mean to use a 'list' object?

  These hints also work for subclasses of builtin types.

  (Contributed by Matt Van Horn in :gh:`146406`.)

* The interpreter now tries to provide a suggestion when
  :func:`delattr` fails due to a missing attribute.
  When an attribute name that closely resembles an existing attribute is used,
  the interpreter will suggest the correct attribute name in the error message.
  For example:

  .. doctest::

     >>> class A:
     ...     pass
     >>> a = A()
     >>> a.abcde = 1
     >>> del a.abcdf  # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
     AttributeError: 'A' object has no attribute 'abcdf'. Did you mean: 'abcde'?

  (Contributed by Nikita Sobolev and Pranjal Prajapati in :gh:`136588`.)

* Several error messages incorrectly using the term "argument" have been corrected.
  (Contributed by Stan Ulbrych in :gh:`133382`.)


Other language changes
======================

.. _whatsnew315-utf8-default:

* Python now uses UTF-8_ as the default encoding, independent of the system's
  environment. This means that I/O operations without an explicit encoding,
  for example, ``open('flying-circus.txt')``, will use UTF-8.
  UTF-8 is a widely-supported Unicode_ character encoding that has become a
  *de facto* standard for representing text, including nearly every webpage
  on the internet, many common file formats, programming languages, and more.

  This only applies when no ``encoding`` argument is given. For best
  compatibility between versions of Python, ensure that an explicit ``encoding``
  argument is always provided. The :ref:`opt-in encoding warning <io-encoding-warning>`
  can be used to identify code that may be affected by this change.
  The special ``encoding='locale'`` argument uses the current locale
  encoding, and has been supported since Python 3.10.

  To retain the previous behaviour, Python's UTF-8 mode may be disabled with
  the :envvar:`PYTHONUTF8=0 <PYTHONUTF8>` environment variable or the
  :option:`-X utf8=0 <-X>` command-line option.

  .. seealso:: :pep:`686` for further details.

  .. _UTF-8: https://en.wikipedia.org/wiki/UTF-8
  .. _Unicode: https://home.unicode.org/

  (Contributed by Adam Turner in :gh:`133711`; PEP 686 written by Inada Naoki.)

  .. _whatsnew315-color-interpreter-help:

* The interpreter help (such as ``python --help``) is now in color.
  This can be controlled by :ref:`environment variables
  <using-on-controlling-color>`.
  (Contributed by Hugo van Kemenade in :gh:`148766`.)

  .. _whatsnew315-color-exceptions:

* Unraisable exceptions are now highlighted with color by default. This can be
  controlled by :ref:`environment variables <using-on-controlling-color>`.
  (Contributed by Peter Bierma in :gh:`134170`.)

  .. _whatsnew315-more-color:

* More color in
  :ref:`argparse <whatsnew315-color-argparse>`,
  :ref:`ast <whatsnew315-color-ast>`,
  :ref:`calendar <whatsnew315-color-calendar>`,
  :ref:`difflib <whatsnew315-color-difflib>`,
  :ref:`http.server <whatsnew315-color-http.server>`,
  :ref:`pickletools <whatsnew315-color-pickletools>`,
  :ref:`PyREPL tab completion <whatsnew315-pyrepl-completion>`,
  :ref:`python --help <whatsnew315-color-interpreter-help>`,
  :ref:`sqlite3 <whatsnew315-color-sqlite3>`,
  :ref:`timeit <whatsnew315-color-timeit>`,
  :ref:`tokenize <whatsnew315-color-tokenize>`,
  :ref:`unraisable exceptions <whatsnew315-color-exceptions>` and
  :term:`stdlib` (ast, compileall, doctest, gzip, inspect, json.tool, pdb,
  profiling.sampling, random, regrtest, sqlite3, timeit, tokenize, trace,
  unittest, uuid, zipapp, zipfile) CLI help.

* The :meth:`~object.__repr__` of :class:`ImportError` and :class:`ModuleNotFoundError`
  now shows "name" and "path" as ``name=<name>`` and ``path=<path>`` if they were given
  as keyword arguments at construction time.
  (Contributed by Serhiy Storchaka, Oleg Iarygin, and Yoav Nir in :gh:`74185`.)

* The :attr:`~object.__dict__` and :attr:`!__weakref__` descriptors now use a
  single descriptor instance per interpreter, shared across all types that
  need them.
  This speeds up class creation, and helps avoid reference cycles.
  (Contributed by Petr Viktorin in :gh:`135228`.)

* The :option:`-W` option and the :envvar:`PYTHONWARNINGS` environment variable
  can now specify regular expressions instead of literal strings to match
  the warning message and the module name, if the corresponding field starts
  and ends with a forward slash (``/``).
  (Contributed by Serhiy Storchaka in :gh:`134716`.)

* Functions that take timestamp or timeout arguments now accept any real
  numbers (such as :class:`~decimal.Decimal` and :class:`~fractions.Fraction`),
  not only integers or floats, although this does not improve precision.
  (Contributed by Serhiy Storchaka in :gh:`67795`.)

.. _whatsnew315-bytearray-take-bytes:

* Added :meth:`bytearray.take_bytes(n=None, /) <bytearray.take_bytes>` to take
  bytes out of a :class:`bytearray` without copying. This enables optimizing code
  which must return :class:`bytes` after working with a mutable buffer of bytes
  such as data buffering, network protocol parsing, encoding, decoding,
  and compression. Common code patterns which can be optimized with
  :func:`~bytearray.take_bytes` are listed below.

  .. list-table:: Suggested optimizing refactors
      :header-rows: 1

      * - Description
        - Old
        - New

      * - Return :class:`bytes` after working with :class:`bytearray`
        - .. code:: python

              def read() -> bytes:
                  buffer = bytearray(1024)
                  ...
                  return bytes(buffer)

        - .. code:: python

              def read() -> bytes:
                  buffer = bytearray(1024)
                  ...
                  return buffer.take_bytes()

      * - Empty a buffer getting the bytes
        - .. code:: python

              buffer = bytearray(1024)
              ...
              data = bytes(buffer)
              buffer.clear()

        - .. code:: python

              buffer = bytearray(1024)
              ...
              data = buffer.take_bytes()

      * - Split a buffer at a specific separator
        - .. code:: python

              buffer = bytearray(b'abc\ndef')
              n = buffer.find(b'\n')
              data = bytes(buffer[:n + 1])
              del buffer[:n + 1]
              assert data == b'abc\n'
              assert buffer == bytearray(b'def')

        - .. code:: python

              buffer = bytearray(b'abc\ndef')
              n = buffer.find(b'\n')
              data = buffer.take_bytes(n + 1)

      * - Split a buffer at a specific separator; discard after the separator
        - .. code:: python

              buffer = bytearray(b'abc\ndef')
              n = buffer.find(b'\n')
              data = bytes(buffer[:n])
              buffer.clear()
              assert data == b'abc'
              assert len(buffer) == 0

        - .. code:: python

              buffer = bytearray(b'abc\ndef')
              n = buffer.find(b'\n')
              buffer.resize(n)
              data = buffer.take_bytes()

  (Contributed by Cody Maloney in :gh:`139871`.)

* Many functions related to compiling or parsing Python code, such as
  :func:`compile`, :func:`ast.parse`, :func:`symtable.symtable`,
  and :func:`importlib.abc.InspectLoader.source_to_code`, now allow the module
  name to be passed. It is needed to unambiguously :ref:`filter <warning-filter>`
  syntax warnings by module name.
  (Contributed by Serhiy Storchaka in :gh:`135801`.)

* Allowed defining the *__dict__* and *__weakref__* :ref:`__slots__ <slots>`
  for any class.
  (Contributed by Serhiy Storchaka in :gh:`41779`.)

* Allowed defining any :ref:`__slots__ <slots>` for a class derived from
  :class:`tuple` (including classes created by :func:`collections.namedtuple`).
  (Contributed by Serhiy Storchaka in :gh:`41779`.)

* The :class:`slice` type now supports subscription,
  making it a :term:`generic type`.
  (Contributed by James Hilton-Balfe in :gh:`128335`.)

* The class :class:`memoryview` now supports the :c:expr:`float complex` and
  :c:expr:`double complex` C types: formatting characters ``'Zf'`` and ``'Zd'``
  respectively.
  (Contributed by Victor Stinner in :gh:`146151` and :gh:`148675`.)

* Allow the *count* argument of :meth:`bytes.replace` to be a keyword.
  (Contributed by Stan Ulbrych in :gh:`147856`.)

* Unary plus is now accepted in :keyword:`match` literal patterns, mirroring
  the existing support for unary minus.
  (Contributed by Bartosz Sławecki in :gh:`145239`.)

* The import system now acquires per-module locks in hierarchical order
  (parent packages before their submodules). This fixes a long-standing
  deadlock where one thread importing ``pkg.sub`` and another importing
  ``pkg.sub.mod`` could each block the other when ``pkg/sub/__init__.py``
  imports ``pkg.sub.mod``.
  (Contributed by Gregory P. Smith in :gh:`83065`.)

* File names of Stable ABI extensions that use the ``.so`` suffix may now
  include a multiarch tuple, for example, ``foo.abi3-x86-64-linux-gnu.so``.
  This permits stable ABI extensions for multiple architectures to be
  co-installed into the same directory, without clashing with each
  other, as regular dynamic extensions do.
  (Contributed by Stefano Rivera in :gh:`122931`.)



Default interactive shell
=========================

.. _whatsnew315-pyrepl-completion:

* Tab completions are now colored by object kind, based on
  :pypi:`fancycompleter`.
  Set :envvar:`PYTHON_BASIC_COMPLETER` to fall back to :mod:`rlcompleter`.
  Color can also be controlled by :ref:`environment variables
  <using-on-controlling-color>`.
  (Contributed by Antonio Cuni and Pablo Galindo in :gh:`130472`.)


New modules
===========

math.integer
------------

This module provides access to the mathematical functions for integer
arguments (:pep:`791`).
(Contributed by Serhiy Storchaka in :gh:`81313`.)


Improved modules
================

argparse
--------

* The :class:`~argparse.BooleanOptionalAction` action now supports single-dash
  long options and alternate prefix characters.
  (Contributed by Serhiy Storchaka in :gh:`138525`.)

* Changed the *suggest_on_error* parameter of :class:`argparse.ArgumentParser` to
  default to ``True``. This enables suggestions for mistyped arguments by default.
  (Contributed by Jakob Schluse in :gh:`140450`.)

  .. _whatsnew315-color-argparse:

* Added backtick markup support in :class:`~argparse.ArgumentParser` description
  and epilog text to highlight inline code when color output is enabled.
  (Contributed by Savannah Ostrowski in :gh:`142390`.)

* Extended backtick markup to argument ``help`` text and added support for
  double backticks (RST inline-literal style).
  (Contributed by Hugo van Kemenade in :gh:`149375`.)


array
-----

* Support the :c:expr:`float complex` and :c:expr:`double complex` C types:
  formatting characters ``'Zf'`` and ``'Zd'`` respectively.
  (Contributed by Victor Stinner in :gh:`146151` and :gh:`148675`.)

* Support half-floats (16-bit IEEE 754 binary interchange format): formatting
  character ``'e'``.
  (Contributed by Sergey B Kirpichev in :gh:`146238`.)

* The :data:`array.typecodes` type changed from :class:`str` to :class:`tuple`
  to support type codes longer than 1 character (``Zf`` and ``Zd``).
  (Contributed by Victor Stinner in :gh:`148675`.)


ast
---

  .. _whatsnew315-color-ast:

* Add *color* parameter to :func:`~ast.dump`.
  If ``True``, the returned string is syntax highlighted using ANSI escape
  sequences.
  If ``False`` (the default), colored output is always disabled.
  (Contributed by Stan Ulbrych in :gh:`148981`.)

* The :ref:`command-line <ast-cli>` output is now syntax highlighted by default.
  This can be :ref:`controlled using environment variables <using-on-controlling-color>`.
  (Contributed by Stan Ulbrych in :gh:`148981`.)


asyncio
-------

* Added :meth:`TaskGroup.cancel <asyncio.TaskGroup.cancel>` to allow early
  termination of a task group, for instance, when the goal of the tasks has
  been achieved or their services are no longer needed.
  Previously this would involve unintuitive boilerplate such as an extra task
  raising a custom exception which is then suppressed as it exits the task group.
  (Contributed by John Belmonte in :gh:`127214`.)


base64
------

* Added the *pad* parameter in :func:`~base64.z85encode`.
  (Contributed by Hauke Dämpfling in :gh:`143103`.)

* Added the *padded* parameter in
  :func:`~base64.b32encode`, :func:`~base64.b32decode`,
  :func:`~base64.b32hexencode`, :func:`~base64.b32hexdecode`,
  :func:`~base64.b64encode`, :func:`~base64.b64decode`,
  :func:`~base64.urlsafe_b64encode`, and :func:`~base64.urlsafe_b64decode`.
  (Contributed by Serhiy Storchaka in :gh:`73613`.)

* Added the *wrapcol* parameter in :func:`~base64.b16encode`,
  :func:`~base64.b32encode`, :func:`~base64.b32hexencode`,
  :func:`~base64.b64encode`, :func:`~base64.b85encode`, and
  :func:`~base64.z85encode`.
  (Contributed by Serhiy Storchaka in :gh:`143214` and :gh:`146431`.)

* Added the *ignorechars* parameter in :func:`~base64.b16decode`,
  :func:`~base64.b32decode`, :func:`~base64.b32hexdecode`,
  :func:`~base64.b64decode`, :func:`~base64.b85decode`, and
  :func:`~base64.z85decode`.
  (Contributed by Serhiy Storchaka in :gh:`144001` and :gh:`146431`.)

* Added the *canonical* parameter in
  :func:`~base64.b32decode`, :func:`~base64.b32hexdecode`,
  :func:`~base64.b64decode`, :func:`~base64.urlsafe_b64decode`,
  :func:`~base64.a85decode`, :func:`~base64.b85decode`, and
  :func:`~base64.z85decode`,
  to reject encodings with non-zero padding bits or other non-canonical
  forms.
  (Contributed by Gregory P. Smith in :gh:`146311`.)


binascii
--------

* Added functions for Base32 encoding:

  - :func:`~binascii.b2a_base32` and :func:`~binascii.a2b_base32`

  (Contributed by James Seo in :gh:`146192`.)

* Added functions for Ascii85, Base85, and Z85 encoding:

  - :func:`~binascii.b2a_ascii85` and :func:`~binascii.a2b_ascii85`
  - :func:`~binascii.b2a_base85` and :func:`~binascii.a2b_base85`

  (Contributed by James Seo and Serhiy Storchaka in :gh:`101178`.)

* Added the *padded* parameter in
  :func:`~binascii.b2a_base32`, :func:`~binascii.a2b_base32`,
  :func:`~binascii.b2a_base64`, and :func:`~binascii.a2b_base64`.
  (Contributed by Serhiy Storchaka in :gh:`73613`.)

* Added the *wrapcol* parameter in :func:`~binascii.b2a_base64`.
  (Contributed by Serhiy Storchaka in :gh:`143214`.)

* Added the *alphabet* parameter in :func:`~binascii.b2a_base64` and
  :func:`~binascii.a2b_base64`.
  (Contributed by Serhiy Storchaka in :gh:`145980`.)

* Added the *ignorechars* parameter in :func:`~binascii.a2b_hex`,
  :func:`~binascii.unhexlify`, and :func:`~binascii.a2b_base64`.
  (Contributed by Serhiy Storchaka in :gh:`144001` and :gh:`146431`.)

* Added the *canonical* parameter in :func:`~binascii.a2b_base64`,
  to reject encodings with non-zero padding bits.
  (Contributed by Gregory P. Smith in :gh:`146311`.)


calendar
--------

  .. _whatsnew315-color-calendar:

* :mod:`calendar`'s :ref:`command-line <calendar-cli>` text output has more
  color. This can be controlled with :ref:`environment variables
  <using-on-controlling-color>`.
  (Contributed by Hugo van Kemenade in :gh:`148352`.)

* The :mod:`calendar`'s :ref:`command-line <calendar-cli>` HTML output now
  accepts the year-month option: ``python -m calendar -t html 2009 06``.
  (Contributed by Pål Grønås Drange in :gh:`140212`.)

* Calendar pages generated by the :class:`calendar.HTMLCalendar` class now support
  dark mode and have been migrated to the HTML5 standard for improved accessibility.
  (Contributed by Jiahao Li and Hugo van Kemenade in :gh:`137634`.)


collections
-----------

* Added :meth:`!collections.Counter.__xor__` and
  :meth:`!collections.Counter.__ixor__` to compute the symmetric difference
  between :class:`~collections.Counter` objects.
  (Contributed by Raymond Hettinger in :gh:`138682`.)


concurrent.futures
------------------

* Improved error reporting when a child process in a
  :class:`concurrent.futures.ProcessPoolExecutor` terminates abruptly.
  The resulting traceback will now tell you the PID and exit code of the
  terminated process.
  (Contributed by Jonathan Berg in :gh:`139486`.)


contextlib
----------

* Added support for arbitrary descriptors :meth:`!__enter__`,
  :meth:`!__exit__`, :meth:`!__aenter__`, and :meth:`!__aexit__` in
  :class:`~contextlib.ExitStack` and :class:`contextlib.AsyncExitStack`, for
  consistency with the :keyword:`with` and :keyword:`async with` statements.
  (Contributed by Serhiy Storchaka in :gh:`144386`.)

* :class:`~contextlib.ContextDecorator` and
  :class:`~contextlib.AsyncContextDecorator` (and therefore
  :func:`~contextlib.contextmanager` and :func:`~contextlib.asynccontextmanager`
  used as decorators) now detect generator functions, coroutine functions, and
  asynchronous generator functions and keep the context manager open across
  iteration or await.  Previously the context manager exited as soon as the
  generator or coroutine object was created.
  (Contributed by Alex Grönholm & Gregory P. Smith in :gh:`125862`.)


ctypes
------

* Change the :py:attr:`~ctypes._SimpleCData._type_` of
  :class:`~ctypes.c_float_complex`, :class:`~ctypes.c_double_complex` and
  :class:`~ctypes.c_longdouble_complex` from ``F``, ``D`` and ``G`` to ``Zf``,
  ``Zd`` and ``Zg`` for compatibility with NumPy.
  (Contributed by Victor Stinner in :gh:`148675`.)


dataclasses
-----------

* Annotations for generated ``__init__`` methods no longer include internal
  type names.


dbm
---

* Added new :meth:`!reorganize` methods to :mod:`dbm.dumb` and :mod:`dbm.sqlite3`
  to recover unused free space previously occupied by deleted entries.
  (Contributed by Andrea Oliveri in :gh:`134004`.)


difflib
-------

  .. _whatsnew315-color-difflib:

* Introduced the optional *color* parameter to :func:`difflib.unified_diff`,
  enabling color output similar to :program:`git diff`.
  This can be controlled by :ref:`environment variables
  <using-on-controlling-color>`.
  (Contributed by Douglas Thor in :gh:`133725`.)

* Improved the styling of HTML diff pages generated by the :class:`difflib.HtmlDiff`
  class, and migrated the output to the HTML5 standard.
  (Contributed by Jiahao Li in :gh:`134580`.)


email
-----

* Email generators now raise an error when an :class:`.EmailMessage` cannot be
  accurately flattened due to a non-ASCII email address (mailbox) in an address
  header. Options for supporting Email Address Internationalization (EAI) are
  discussed in :attr:`.EmailPolicy.utf8`.
  (Contributed by R David Murray and Mike Edmunds in :gh:`122540`.)


faulthandler
------------

* Added the *max_threads* parameter in :func:`faulthandler.enable`,
  :func:`faulthandler.dump_traceback`, :func:`faulthandler.dump_traceback_later`,
  and :func:`faulthandler.register`.
  (Contributed by Eric Froemling in :gh:`149085`.)


functools
---------

* :func:`~functools.singledispatchmethod` now supports non-:term:`descriptor`
  callables.
  (Contributed by Serhiy Storchaka in :gh:`140873`.)

* :func:`~functools.singledispatchmethod` now dispatches on the second argument
  if it wraps a regular method and is called as a class attribute.
  (Contributed by Bartosz Sławecki in :gh:`143535`.)


gc
--

* Python 3.14.0-3.14.4 shipped with a new incremental garbage collector.
  However, due to a number of `reports
  <https://github.com/python/cpython/issues/142516>`__
  of significant memory pressure in production environments,
  it has been reverted back to the generational GC from 3.13.
  This is the GC now used in Python 3.14.5 and later and Python 3.15.


hashlib
-------

* Ensure that hash functions guaranteed to be always *available* exist as
  attributes of :mod:`hashlib` even if they will not work at runtime due to
  missing backend implementations. For instance, ``hashlib.md5`` will no
  longer raise :exc:`AttributeError` if OpenSSL is not available and Python
  has been built without MD5 support.
  (Contributed by Bénédikt Tran in :gh:`136929`.)


http.client
-----------

* A new *max_response_headers* keyword-only parameter has been added to
  :class:`~http.client.HTTPConnection` and :class:`~http.client.HTTPSConnection`
  constructors. This parameter overrides the default maximum number of allowed
  response headers.
  (Contributed by Alexander Enrique Urieles Nieto in :gh:`131724`.)


http.server
-----------

  .. _whatsnew315-color-http.server:

* The logging of :mod:`~http.server.BaseHTTPRequestHandler`,
  as used by the :ref:`command-line interface <http-server-cli>`,
  is colored by default.
  This can be controlled with :ref:`environment variables
  <using-on-controlling-color>`.
  (Contributed by Hugo van Kemenade in :gh:`146292`.)

* Added :attr:`~http.server.SimpleHTTPRequestHandler.default_content_type`
  and the :option:`--content-type <http.server --content-type>` command-line
  option to allow customizing the default ``Content-Type`` header
  for files with unknown extensions.
  (Contributed by John Comeau and Hugo van Kemenade in :gh:`113471`.)

* Add a new ``extra_response_headers`` keyword argument to
  :class:`~http.server.SimpleHTTPRequestHandler` to support custom headers in
  HTTP responses.
  (Contributed by Anton I. Sipos in :gh:`135057`.)

* Add a ``-H/--header`` option to the :program:`python -m http.server`
  command-line interface to support custom headers in HTTP responses.
  (Contributed by Anton I. Sipos in :gh:`135057`.)


importlib.metadata
------------------

* Previously, when accessing a distribution metadata directory not
  containing a metadata file, ``metadata()`` and ``Distribution.metadata``
  would return an empty ``PackageMetadata`` object as if the file
  was present but empty. Now, a ``MetadataNotFound`` exception is raised.
  See `importlib_metadata#493 <https://github.com/python/importlib_metadata/issues/493>`_
  for background and rationale and :gh:`143387` for rationale on the
  compatibility concerns.
  (Contributed by Jason R. Coombs.)


inspect
-------

* Add parameters *inherit_class_doc* and *fallback_to_class_doc*
  for :func:`~inspect.getdoc`.
  (Contributed by Serhiy Storchaka in :gh:`132686`.)


json
----

* Add the *array_hook* parameter to :func:`~json.load` and
  :func:`~json.loads` functions:
  allow a callback for JSON literal array types to customize Python lists in
  the resulting decoded object. Passing combined :class:`frozendict` to
  *object_pairs_hook* param and :class:`tuple` to ``array_hook`` will yield a
  deeply nested immutable Python structure representing the JSON data.
  (Contributed by Joao S. O. Bueno in :gh:`146440`.)


locale
------

* :func:`~locale.setlocale` now supports language codes with ``@``-modifiers.
  ``@``-modifiers are no longer silently removed in :func:`~locale.getlocale`,
  but included in the language code.
  (Contributed by Serhiy Storchaka in :gh:`137729`.)

* Undeprecate the :func:`locale.getdefaultlocale` function.
  (Contributed by Victor Stinner in :gh:`130796`.)


math
----

* Add :func:`math.isnormal` and :func:`math.issubnormal` functions.
  (Contributed by Sergey B Kirpichev in :gh:`132908`.)

* Add :func:`math.fmax`, :func:`math.fmin` and :func:`math.signbit` functions.
  (Contributed by Bénédikt Tran in :gh:`135853`.)


mimetypes
---------

* Add more MIME types.
  (Contributed by Benedikt Johannes, Charlie Lin, Foolbar, Gil Forcada and
  John Franey
  in :gh:`144217`, :gh:`145720`, :gh:`140937`, :gh:`139959`, :gh:`145698`,
  :gh:`145718`, :gh:`145918`, and :gh:`144213`.)
* Rename ``application/x-texinfo`` to ``application/texinfo``.
  (Contributed by Charlie Lin in :gh:`140165`.)
* Changed the MIME type for ``.ai`` files to ``application/pdf``.
  (Contributed by Stan Ulbrych in :gh:`141239`.)


mmap
----

* :class:`mmap.mmap` now has a *trackfd* parameter on Windows;
  if it is ``False``, the file handle corresponding to *fileno* will
  not be duplicated.
  (Contributed by Serhiy Storchaka in :gh:`78502`.)

* Added the :meth:`mmap.mmap.set_name` method
  to annotate an anonymous memory mapping
  if Linux kernel supports :manpage:`PR_SET_VMA_ANON_NAME <PR_SET_VMA(2const)>` (Linux 5.17 or newer).
  (Contributed by Donghee Na in :gh:`142419`.)


os
--

* Add :func:`os.statx` on Linux kernel versions 4.11 and later with
  glibc versions 2.28 and later.
  (Contributed by Jeffrey Bosboom and Victor Stinner in :gh:`83714`.)

* :func:`os.makedirs` function now has a *parent_mode* parameter that allows
  specifying the mode for intermediate directories. This can be used to match
  the behavior from Python 3.6 and earlier by passing ``parent_mode=mode``.
  (Contributed by Zackery Spytz and Gregory P. Smith in :gh:`86533`.)

os.path
-------

* Add support of the all-but-last mode in :func:`~os.path.realpath`.
  (Contributed by Serhiy Storchaka in :gh:`71189`.)

* The *strict* parameter to :func:`os.path.realpath` accepts a new value,
  :data:`os.path.ALLOW_MISSING`.
  If used, errors other than :exc:`FileNotFoundError` will be re-raised;
  the resulting path can be missing but it will be free of symlinks.
  (Contributed by Petr Viktorin for :cve:`2025-4517`.)


pathlib
-------

* :meth:`pathlib.Path.mkdir` now has a *parent_mode* parameter that allows
  specifying the mode for intermediate directories when ``parents=True``.
  (Contributed by Gregory P. Smith in :gh:`86533`.)


pdb
---

* Use the new interactive shell as the default input shell for :mod:`pdb`.
  (Contributed by Tian Gao in :gh:`145379`.)


pickle
------

* Add support for pickling private methods and nested classes.
  (Contributed by Zackery Spytz and Serhiy Storchaka in :gh:`77188`.)


pickletools
-----------

  .. _whatsnew315-color-pickletools:

* The output of the :mod:`pickletools` command-line interface is colored by
  default. This can be controlled with
  :ref:`environment variables <using-on-controlling-color>`.
  (Contributed by Hugo van Kemenade in :gh:`149026`.)


pprint
------

* Add an *expand* keyword argument for :func:`pprint.pprint`,
  :func:`pprint.pformat`, :func:`pprint.pp`. If true, the output will be
  formatted similar to pretty-printed :func:`json.dumps` when
  *indent* is supplied.
  (Contributed by Stefan Todoran, Semyon Moroz and Hugo van Kemenade in
  :gh:`112632`.)

* Add t-string support to :mod:`pprint`.
  (Contributed by Loïc Simon and Hugo van Kemenade in :gh:`134551`.)


re
--

* :func:`re.prefixmatch` and a corresponding :meth:`re.Pattern.prefixmatch`
  have been added as alternate, more explicit names for the existing
  and now :term:`soft deprecated`
  :func:`re.match` and :meth:`re.Pattern.match` APIs. These are intended
  to be used to alleviate confusion around what *match* means by following the
  Zen of Python's *"Explicit is better than implicit"* mantra. Most other
  language regular expression libraries use an API named *match* to mean what
  Python has always called *search*.
  (Contributed by Gregory P. Smith in :gh:`86519`.)


resource
--------

* Add new constants: :data:`~resource.RLIMIT_NTHR`,
  :data:`~resource.RLIMIT_UMTXP`, :data:`~resource.RLIMIT_THREADS`,
  :data:`~resource.RLIM_SAVED_CUR`, and :data:`~resource.RLIM_SAVED_MAX`.
  (Contributed by Serhiy Storchaka in :gh:`137512`.)


shelve
------

* Added new :meth:`!reorganize` method to :mod:`shelve` used to recover unused free
  space previously occupied by deleted entries.
  (Contributed by Andrea Oliveri in :gh:`134004`.)
* Add support for custom serialization and deserialization functions
  in the :mod:`shelve` module.
  (Contributed by Furkan Onder in :gh:`99631`.)


socket
------

* Add constants for the ISO-TP CAN protocol.
  (Contributed by Patrick Menschel and Stefan Tatschner in :gh:`86819`.)


sqlite3
-------

* The :ref:`command-line interface <sqlite3-cli>` has several new features:

  * SQL keyword completion on <tab>.
    (Contributed by Long Tan in :gh:`133393`.)

  .. _whatsnew315-color-sqlite3:

  * Prompts, error messages, and help text are now colored.
    This is enabled by default, see :ref:`using-on-controlling-color` for
    details.
    (Contributed by Stan Ulbrych and Łukasz Langa in :gh:`133461`.)

  * Table, index, trigger, view, column, function, and schema completion on <tab>.
    (Contributed by Long Tan in :gh:`136101`.)


ssl
---

* Indicate through :data:`ssl.HAS_PSK_TLS13` whether the :mod:`ssl` module
  supports "External PSKs" in TLSv1.3, as described in :rfc:`9258`.
  (Contributed by Will Childs-Klein in :gh:`133624`.)

* Added new methods for managing groups used for SSL key agreement:

  * :meth:`ssl.SSLContext.set_groups` sets the groups allowed for doing
    key agreement, extending the previous
    :meth:`ssl.SSLContext.set_ecdh_curve` method.
    This new API provides the ability to list multiple groups and
    supports fixed-field and post-quantum groups in addition to ECDH
    curves. This method can also be used to control what key shares
    are sent in the TLS handshake.
  * :meth:`ssl.SSLSocket.group` returns the group selected for doing key
    agreement on the current connection after the TLS handshake completes.
    This call requires OpenSSL 3.2 or later.
  * :meth:`ssl.SSLContext.get_groups` returns a list of all available key
    agreement groups compatible with the minimum and maximum TLS versions
    currently set in the context. This call requires OpenSSL 3.5 or later.

  (Contributed by Ron Frederick in :gh:`136306`.)

* Added a new method :meth:`ssl.SSLContext.set_ciphersuites` for setting TLS 1.3
  ciphers. For TLS 1.2 or earlier, :meth:`ssl.SSLContext.set_ciphers` should
  continue to be used. Both calls can be made on the same context and the
  selected cipher suite will depend on the TLS version negotiated when a
  connection is made.
  (Contributed by Ron Frederick in :gh:`137197`.)

* Added new methods for managing signature algorithms:

  * :func:`ssl.get_sigalgs` returns a list of all available TLS signature
    algorithms. This call requires OpenSSL 3.4 or later.
  * :meth:`ssl.SSLContext.set_client_sigalgs` sets the signature algorithms
    allowed for certificate-based client authentication.
  * :meth:`ssl.SSLContext.set_server_sigalgs` sets the signature algorithms
    allowed for the server to complete the TLS handshake.
  * :meth:`ssl.SSLSocket.client_sigalg` returns the signature algorithm
    selected for client authentication on the current connection. This call
    requires OpenSSL 3.5 or later.
  * :meth:`ssl.SSLSocket.server_sigalg` returns the signature algorithm
    selected for the server to complete the TLS handshake on the current
    connection. This call requires OpenSSL 3.5 or later.

  (Contributed by Ron Frederick in :gh:`138252`.)


subprocess
----------

* :meth:`subprocess.Popen.wait`: when ``timeout`` is not ``None`` and the
  platform supports it, an efficient event-driven mechanism is used to wait for
  process termination:

  - Linux >= 5.3 uses :func:`os.pidfd_open` + :func:`select.poll`.
  - macOS and other BSD variants use :func:`select.kqueue` + ``KQ_FILTER_PROC`` + ``KQ_NOTE_EXIT``.
  - Windows keeps using ``WaitForSingleObject`` (unchanged).

  If none of these mechanisms are available, the function falls back to the
  traditional busy loop (non-blocking call and short sleeps).
  (Contributed by Giampaolo Rodola in :gh:`83069`.)


symtable
--------

* Add :meth:`symtable.Function.get_cells` and :meth:`symtable.Symbol.is_cell` methods.
  (Contributed by Yashp002 in :gh:`143504`.)


sys
---

* Add :data:`sys.abi_info` namespace to improve access to ABI information.
  (Contributed by Klaus Zimmermann in :gh:`137476`.)


sys.monitoring
--------------

* The :ref:`other events <monitoring-event-global>`
  (:monitoring-event:`PY_THROW`, :monitoring-event:`PY_UNWIND`,
  :monitoring-event:`RAISE`, :monitoring-event:`EXCEPTION_HANDLED`, and
  :monitoring-event:`RERAISE`) can now be turned on and disabled on a per code
  object basis. Returning :data:`~sys.monitoring.DISABLE` from a callback for
  one of these events disables the event for the entire code object (for the
  current tool), rather than raising :exc:`ValueError` as in prior versions.
  (Contributed by Gabriele N. Tornetta in :gh:`146182`.)


tarfile
-------

* :func:`~tarfile.data_filter` now normalizes symbolic link targets in order to
  avoid path traversal attacks.
  (Contributed by Petr Viktorin in :gh:`127987` and :cve:`2025-4138`.)
* :func:`~tarfile.TarFile.extractall` now skips fixing up directory attributes
  when a directory was removed or replaced by another kind of file.
  (Contributed by Petr Viktorin in :gh:`127987` and :cve:`2024-12718`.)
* :func:`~tarfile.TarFile.extract` and :func:`~tarfile.TarFile.extractall`
  now (re-)apply the extraction filter when substituting a link (hard or
  symbolic) with a copy of another archive member, and when fixing up
  directory attributes.
  The former raises a new exception, :exc:`~tarfile.LinkFallbackError`.
  (Contributed by Petr Viktorin for :cve:`2025-4330` and :cve:`2024-12718`.)
* :func:`~tarfile.TarFile.extract` and :func:`~tarfile.TarFile.extractall`
  no longer extract rejected members when
  :func:`~tarfile.TarFile.errorlevel` is zero.
  (Contributed by Matt Prodani and Petr Viktorin in :gh:`112887`
  and :cve:`2025-4435`.)
* :func:`~tarfile.TarFile.extract` and :func:`~tarfile.TarFile.extractall`
  now replace slashes with backslashes in symlink targets on Windows to prevent
  creation of corrupted links.
  (Contributed by Christoph Walcher in :gh:`57911`.)
* :func:`~tarfile.TarFile.gettarinfo` now replaces backslashes with slashes in
  symlink targets on Windows to conform to the tar format standard. (Contributed
  by Daniele Nicolodi in :gh:`151669`.)


threading
---------

* Added :class:`~threading.serialize_iterator`,
  :func:`~threading.synchronized_iterator`,
  and :func:`~threading.concurrent_tee` to support concurrent access to
  generators and iterators.
  (Contributed by Raymond Hettinger in :gh:`124397`.)


timeit
------

  .. _whatsnew315-color-timeit:

* The output of the :mod:`timeit` command-line interface is colored by default.
  This can be controlled with
  :ref:`environment variables <using-on-controlling-color>`.
  (Contributed by Hugo van Kemenade in :gh:`146609`.)

* The command-line interface now colorizes error tracebacks
  by default. This can be controlled with
  :ref:`environment variables <using-on-controlling-color>`.
  (Contributed by Yi Hong in :gh:`139374`.)

* Make the target time of :meth:`timeit.Timer.autorange` configurable
  and add ``--target-time`` option to the command-line interface.
  (Contributed by Alessandro Cucci and Miikka Koskinen in :gh:`80642`.)


tkinter
-------

* The :meth:`!tkinter.Text.search` method now supports two additional
  arguments: *nolinestop* which allows the search to
  continue across line boundaries;
  and *strictlimits* which restricts the search to within the specified range.
  (Contributed by Rihaan Meher in :gh:`130848`.)

* A new method :meth:`!tkinter.Text.search_all` has been introduced.
  This method allows for searching for all matches of a pattern
  using Tcl's ``-all`` and ``-overlap`` options.
  (Contributed by Rihaan Meher in :gh:`130848`.)

* Added new methods :meth:`!pack_content`, :meth:`!place_content` and
  :meth:`!grid_content` which use Tk commands with new names (introduced
  in Tk 8.6) instead of :meth:`!*_slaves` methods which use Tk commands
  with outdated names.
  (Contributed by Serhiy Storchaka in :gh:`143754`.)

* Added :class:`!Event` attributes :attr:`!user_data` for Tk virtual events
  and :attr:`!detail` for ``Enter``, ``Leave``, ``FocusIn``, ``FocusOut``,
  and ``ConfigureRequest`` events.
  (Contributed by Matthias Kievernagel and Serhiy Storchaka in :gh:`47655`.)


tokenize
--------

  .. _whatsnew315-color-tokenize:

* The output of the :mod:`tokenize` :ref:`command-line interface
  <tokenize-cli>` is colored by default. This can be controlled with
  :ref:`environment variables <using-on-controlling-color>`.
  (Contributed by Hugo van Kemenade in :gh:`148991`.)


.. _whatsnew315-tomllib-1-1-0:

tomllib
-------

* The :mod:`tomllib` module now supports TOML 1.1.0.
  This is a backwards compatible update, meaning that all valid TOML 1.0.0
  documents are parsed the same way.

  The changes, according to the `official TOML changelog`_, are:

  - Allow newlines and trailing commas in inline tables.

    Previously an inline table had to be on a single line and couldn't end
    with a trailing comma. This is now relaxed so that the following is valid:

    .. code-block:: toml

       tbl = {
          key      = "a string",
          moar-tbl =  {
             key = 1,
          },
       }

  - Add ``\xHH`` notation to basic strings for codepoints under 255,
    and the ``\e`` escape for the escape character:

    .. code-block:: toml

       null = "null byte: \x00; letter a: \x61"
       csi = "\e["

  - Seconds in datetime and time values are now optional.
    The following are now valid:

    .. code-block:: toml

       dt = 2010-02-03 14:15
       t  = 14:15

  (Contributed by Taneli Hukkinen in :gh:`142956`.)

.. _official TOML changelog: https://github.com/toml-lang/toml/blob/main/CHANGELOG.md


types
-----

* Expose the write-through :func:`locals` proxy type
  as :class:`types.FrameLocalsProxyType`.
  This represents the type of the :attr:`frame.f_locals` attribute,
  as described in :pep:`667`.


typing
------

.. _whatsnew315-typeform:

* :pep:`747`: Add :data:`~typing.TypeForm`, a new special form for annotating
  values that are themselves type expressions.
  ``TypeForm[T]`` means "a type form object describing ``T`` (or a type
  assignable to ``T``)". At runtime, ``TypeForm(x)`` simply returns ``x``,
  which allows explicit annotation of type-form values without changing
  behavior.

  This helps libraries that accept user-provided type expressions
  (for example ``int``, ``str | None``, :class:`~typing.TypedDict`
  classes, or ``list[int]``) expose precise signatures:

  .. code-block:: python

     from typing import Any, TypeForm

     def cast[T](typ: TypeForm[T], value: Any) -> T: ...

  (Contributed by Jelle Zijlstra in :gh:`145033`.)

.. _whatsnew315-typeddict:

* :pep:`728`: Add support in :class:`~typing.TypedDict` for the *closed*
  and *extra_items* class arguments. A closed :class:`~typing.TypedDict`
  does not allow extra keys beyond those specified in the class body, while
  a :class:`~typing.TypedDict` with ``extra_items`` allows arbitrary extra
  items where the values are of the specified type. (Contributed by Angela
  Liss in :gh:`137840`.)

* Code like ``class ExtraTypeVars(P1[S], Protocol[T, T2]): ...`` now raises
  a :exc:`TypeError`, because ``S`` is not listed in ``Protocol`` parameters.
  (Contributed by Nikita Sobolev in :gh:`137191`.)

* Code like ``class B2(A[T2], Protocol[T1, T2]): ...`` now correctly handles
  type parameters order: it is ``(T1, T2)``, not ``(T2, T1)``
  as it was incorrectly inferred at runtime before.
  (Contributed by Nikita Sobolev in :gh:`137191`.)

  .. _whatsnew315-disjoint-base:

* :pep:`800`: Add :deco:`typing.disjoint_base`, a new decorator marking a class
  as a disjoint base. This is an advanced feature primarily intended to allow
  type checkers to faithfully reflect the runtime semantics of types defined
  as builtins or in compiled extensions. If a class ``C`` is a disjoint base, then
  child classes of that class cannot inherit from other disjoint bases that are
  not parent or child classes of ``C``. (Contributed by Jelle Zijlstra in :gh:`148639`.)

* :class:`~typing.TypeVarTuple` now accepts ``bound``, ``covariant``,
  ``contravariant``, and ``infer_variance`` keyword arguments, matching the
  interface of :class:`~typing.TypeVar` and :class:`~typing.ParamSpec`.
  ``bound`` semantics remain undefined in the specification.


unicodedata
-----------

* The Unicode database has been updated to Unicode 17.0.0.

* Add :func:`unicodedata.isxidstart` and :func:`unicodedata.isxidcontinue`
  functions to check whether a character can start or continue a
  `Unicode Standard Annex #31 <https://www.unicode.org/reports/tr31/>`_ identifier.
  (Contributed by Stan Ulbrych in :gh:`129117`.)

* Add the :func:`~unicodedata.iter_graphemes`
  function to iterate over grapheme clusters according to rules defined in
  `Unicode Standard Annex #29, "Unicode Text Segmentation"
  <https://www.unicode.org/reports/tr29/>`_.
  Add :func:`~unicodedata.grapheme_cluster_break`,
  :func:`~unicodedata.indic_conjunct_break` and
  :func:`~unicodedata.extended_pictographic` functions to get the properties
  of the character which are related to the above algorithm.
  (Contributed by Serhiy Storchaka and Guillaume Sanchez in :gh:`74902`.)

* Add :func:`~unicodedata.block` function to return the `Unicode block
  <https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-3/#G64189>`_
  assigned to a character.
  (Contributed by Stan Ulbrych in :gh:`66802`.)


unittest
--------

* :meth:`unittest.TestCase.assertLogs` will now accept a formatter
  to control how messages are formatted.
  (Contributed by Garry Cairns in :gh:`134567`.)

* :meth:`unittest.TestCase.assertWarns` and
  :meth:`unittest.TestCase.assertWarnsRegex` no longer swallow warnings that
  do not match the specified category or regex.
  Nested context managers are now supported.
  (Contributed by Serhiy Storchaka in :gh:`143231`.)


urllib.parse
------------

* Add the *missing_as_none* parameter to :func:`~urllib.parse.urlsplit`,
  :func:`~urllib.parse.urlparse` and :func:`~urllib.parse.urldefrag` functions.
  Add the *keep_empty* parameter to :func:`~urllib.parse.urlunsplit` and
  :func:`~urllib.parse.urlunparse` functions.
  This allows distinguishing between empty and undefined URI components
  and preserving empty components.
  (Contributed by Serhiy Storchaka in :gh:`67041`.)


venv
----

* On POSIX platforms, platlib directories will be created if needed when
  creating virtual environments, instead of using a ``lib64 -> lib`` symlink.
  This means purelib and platlib of virtual environments no longer share the
  same ``lib`` directory on platforms where :data:`sys.platlibdir` is not
  equal to ``lib``.
  (Contributed by Rui Xi in :gh:`133951`.)


warnings
--------

* Improve filtering by module in :func:`warnings.warn_explicit` if no *module*
  argument is passed.
  It now tests the module regular expression in the warnings filter not only
  against the filename with ``.py`` stripped, but also against module names
  constructed starting from different parent directories of the filename
  (with ``/__init__.py``, ``.py`` and, on Windows, ``.pyw`` stripped).
  (Contributed by Serhiy Storchaka in :gh:`135801`.)


wave
----

* Added support for IEEE floating-point WAVE audio
  (``WAVE_FORMAT_IEEE_FLOAT``) in :mod:`wave`.

* Added :meth:`wave.Wave_read.getformat`, :meth:`wave.Wave_write.getformat`,
  and :meth:`wave.Wave_write.setformat` for explicit frame format handling.

* :meth:`wave.Wave_write.setparams` accepts both 7-item tuples including
  ``format`` and 6-item tuples for backwards compatibility (defaulting to
  ``WAVE_FORMAT_PCM``).

* ``WAVE_FORMAT_IEEE_FLOAT`` output now includes a ``fact`` chunk,
  as required for non-PCM WAVE formats.

(Contributed by Lionel Koenig and Michiel W. Beijen in :gh:`60729`.)


webbrowser
----------

* On macOS, the new :class:`!webbrowser.MacOS` class opens URLs via
  :program:`/usr/bin/open` instead of constructing and executing AppleScript
  via :program:`osascript`. The default browser is detected from the
  LaunchServices preferences file using :mod:`plistlib`, with
  :class:`!com.apple.Safari` as the fallback on fresh installations.
  For non-HTTP(S) URLs, :program:`open -b <bundle-id>` is used to route the
  URL through a browser rather than the OS file handler, preventing
  file injection attacks.
  (Contributed by Jeff Lyon in :gh:`137586`.)


xml
---

* Add the :func:`xml.is_valid_name` function to check
  whether a string can be used as an element or attribute name in XML.
  (Contributed by Serhiy Storchaka in :gh:`139489`.)

* Add the :func:`xml.is_valid_text` function to check
  whether a string can be used in an XML document.
  (Contributed by Serhiy Storchaka in :gh:`139489`.)


xml.parsers.expat
-----------------

* Add :meth:`~xml.parsers.expat.xmlparser.SetAllocTrackerActivationThreshold`
  and :meth:`~xml.parsers.expat.xmlparser.SetAllocTrackerMaximumAmplification`
  to :ref:`xmlparser <xmlparser-objects>` objects to tune protections against
  disproportional amounts of dynamic memory usage from within an Expat parser.
  (Contributed by Bénédikt Tran in :gh:`90949`.)

* Add :meth:`~xml.parsers.expat.xmlparser.SetBillionLaughsAttackProtectionActivationThreshold`
  and :meth:`~xml.parsers.expat.xmlparser.SetBillionLaughsAttackProtectionMaximumAmplification`
  to :ref:`xmlparser <xmlparser-objects>` objects to tune protections against
  `billion laughs`_ attacks.
  (Contributed by Bénédikt Tran in :gh:`90949`.)

  .. _billion laughs: https://en.wikipedia.org/wiki/Billion_laughs_attack


zlib
----

* Allow combining two Adler-32 checksums via :func:`~zlib.adler32_combine`.
  (Contributed by Callum Attryde and Bénédikt Tran in :gh:`134635`.)

* Allow combining two CRC-32 checksums via :func:`~zlib.crc32_combine`.
  (Contributed by Bénédikt Tran in :gh:`134635`.)


.. Add improved modules above alphabetically, not here at the end.

Optimizations
=============

* ``mimalloc`` is now used as the default allocator for
  raw memory allocations such as via :c:func:`PyMem_RawMalloc`
  for better performance on :term:`free-threaded builds <free-threaded build>`.
  (Contributed by Kumar Aditya in :gh:`144914`.)


base64 & binascii
-----------------

* CPython's underlying base64 implementation now encodes 2x faster and decodes 3x
  faster thanks to simple CPU pipelining optimizations.
  (Contributed by Gregory P. Smith and Serhiy Storchaka in :gh:`143262`.)

* Implementation for Ascii85, Base85, and Z85 encoding has been rewritten in C.
  Encoding and decoding is now two orders of magnitude faster and consumes
  two orders of magnitude less memory.
  (Contributed by James Seo and Serhiy Storchaka in :gh:`101178`.)

* Implementation for Base32 has been rewritten in C.
  Encoding and decoding is now two orders of magnitude faster.
  (Contributed by James Seo in :gh:`146192`.)


csv
---

* :meth:`csv.Sniffer.sniff` delimiter detection is now up to 1.6x faster.
  (Contributed by Maurycy Pawłowski-Wieroński in :gh:`137628`.)


.. _whatsnew315-jit:

Upgraded JIT compiler
---------------------

Results from the `pyperformance <https://github.com/python/pyperformance>`__
benchmark suite report
`8-9% <https://www.doesjitgobrrr.com/run/2026-04-29>`__
geometric mean performance improvement for the JIT over the standard CPython
interpreter built with all optimizations enabled on x86-64 Linux. On AArch64
macOS, the JIT has a
`12-13% <https://www.doesjitgobrrr.com/run/2026-04-29>`__
speedup over the :ref:`tail calling interpreter <whatsnew314-tail-call-interpreter>`
with all optimizations enabled. The speedups for JIT
builds versus no JIT builds range from roughly 15% slowdown to over
100% speedup (ignoring the ``unpack_sequence`` microbenchmark) on
x86-64 Linux and AArch64 macOS systems.

.. attention::
    These results are not yet final.

The major upgrades to the JIT are:

* LLVM 21 build-time dependency
* New tracing frontend
* Basic register allocation in the JIT
* More JIT optimizations
* GDB and GNU ``backtrace()`` unwinding support
* Better machine code generation

.. rubric:: LLVM 21 build-time dependency

The JIT compiler now uses LLVM 21 for build-time stencil generation. As
always, LLVM is only needed when building CPython with the JIT enabled;
end users running Python do not need LLVM installed. Instructions for
installing LLVM can be found in the `JIT compiler documentation
<https://github.com/python/cpython/blob/main/Tools/jit/README.md>`__
for all supported platforms.
(Contributed by Savannah Ostrowski in :gh:`140973`.)

.. rubric:: A new tracing frontend

The JIT compiler now supports significantly more bytecode operations and
control flow than in Python 3.14, enabling speedups on a wider variety of
code. For example, simple Python object creation is now understood by the
3.15 JIT compiler. Overloaded operations and generators are also partially
supported. This was made possible by an overhauled JIT tracing frontend
that records actual execution paths through code, rather than estimating
them as the previous implementation did.
(Contributed by Ken Jin in :gh:`139109`. Support for Windows added by
Mark Shannon in :gh:`141703`.)

.. rubric:: Basic register allocation in the JIT

A basic form of register allocation has been added to the JIT compiler's
optimizer. This allows the JIT compiler to avoid certain stack operations
altogether and instead operate on registers. This allows the JIT to produce
more efficient traces by avoiding reads and writes to memory.
(Contributed by Mark Shannon in :gh:`135379`.)

.. rubric:: More JIT optimizations

More `constant-propagation <https://en.wikipedia.org/wiki/Constant_folding>`__
is now performed. This means when the JIT compiler detects that certain user
code results in constants, the code can be simplified by the JIT.
(Contributed by Ken Jin and Savannah Ostrowski in :gh:`132732`.)

:term:`Reference counts <reference count>` are avoided whenever it is safe to
do so. This generally reduces the cost of most operations in Python.
(Contributed by Ken Jin, Donghee Na, Zheao Li, Hai Zhu, Savannah Ostrowski,
Reiden Ong, Noam Cohen, Tomas Roun, PuQing, Cajetan Rodrigues, and Sacul in :gh:`134584`.)

By tracking unique references to objects, the JIT optimizer can now eliminate
reference count updates and perform in-place operations on ints and floats.
(Contributed by Reiden Ong, and Pieter Eendebak in :gh:`143414` and :gh:`146306`.)

The JIT optimizer now supports significantly more operations than in 3.14.
(Contributed by Kumar Aditya, Ken Jin, Jiahao Li, and Sacul in :gh:`131798`.)

.. rubric:: GDB and GNU ``backtrace()`` unwinding support

The JIT compiler now publishes unwind information for generated machine code to the
GDB interface on supported Linux ELF platforms. When libgcc frame
registration is available, the same unwind information is also registered for
GNU ``backtrace()`` stack walkers. This allows native debuggers, crash
handlers, and diagnostic tools using these mechanisms to unwind through JIT
frames instead of stopping at generated code.
(Contributed by Diego Russo and Pablo Galindo Salgado in :gh:`146071` and
:gh:`149104`.)

.. rubric:: Better machine code generation

The JIT compiler's machine code generator now produces better machine code
for x86-64 and AArch64 macOS and Linux targets. In general, users should
experience lower memory usage for generated machine code and more efficient
machine code versus 3.14.
(Contributed by Brandt Bucher in :gh:`136528` and :gh:`135905`.
Implementation for AArch64 contributed by Mark Shannon in :gh:`139855`.
Additional optimizations for AArch64 contributed by Mark Shannon and
Diego Russo in :gh:`140683` and :gh:`142305`.)

.. rubric:: Maintainability

The JIT optimizer's operations have been simplified.
This was made possible by a refactoring of JIT data structures.
(Contributed by Zhongtian Zheng in :gh:`148211` and Hai Zhu in :gh:`143421`.)


Removed
========

ast
---

* The constructors of :ref:`AST nodes <ast_nodes>` now raise a :exc:`TypeError`
  when a required argument is omitted or when a keyword argument that does not
  map to a field on the AST node is passed. These cases had previously raised a
  :exc:`DeprecationWarning` since Python 3.13.
  (Contributed by Brian Schubert and Jelle Zijlstra in :gh:`137600` and :gh:`105858`.)


collections.abc
---------------

* :class:`collections.abc.ByteString` has been removed from
  ``collections.abc.__all__``. :class:`!collections.abc.ByteString` has been
  deprecated since Python 3.12, and is scheduled for removal in Python 3.17.


ctypes
------

* Removed the undocumented function :func:`!ctypes.SetPointerType`,
  which has been deprecated since Python 3.13.
  (Contributed by Bénédikt Tran in :gh:`133866`.)


datetime
--------

* :meth:`~datetime.datetime.strptime` now raises :exc:`ValueError` when the
  format string contains ``%d`` (day of month) without a year directive.
  This has been deprecated since Python 3.13.
  (Contributed by Stan Ulbrych and Gregory P. Smith in :gh:`70647`.)


glob
----

* Removed the undocumented :func:`!glob.glob0` and :func:`!glob.glob1`
  functions, which have been deprecated since Python 3.13. Use
  :func:`glob.glob` and pass a directory to its *root_dir* argument instead.
  (Contributed by Barney Gale in :gh:`137466`.)


http.server
-----------

* Removed the :class:`!CGIHTTPRequestHandler` class
  and the ``--cgi`` flag from the :program:`python -m http.server`
  command-line interface. They were deprecated in Python 3.13.
  (Contributed by Bénédikt Tran in :gh:`133810`.)


importlib.resources
-------------------

* Removed deprecated ``package`` parameter
  from :func:`importlib.resources.files` function.
  (Contributed by Semyon Moroz in :gh:`138044`.)


pathlib
-------

* Removed deprecated :meth:`!pathlib.PurePath.is_reserved`.
  Use :func:`os.path.isreserved` to detect reserved paths on Windows.
  (Contributed by Nikita Sobolev in :gh:`133875`.)


platform
--------

* Removed the :func:`!platform.java_ver` function,
  which was deprecated since Python 3.13.
  (Contributed by Alexey Makridenko in :gh:`133604`.)


sre_*
-----

* Removed :mod:`!sre_compile`, :mod:`!sre_constants` and :mod:`!sre_parse` modules.
  (Contributed by Stan Ulbrych in :gh:`135994`.)


sysconfig
---------

* Removed the *check_home* parameter of :func:`sysconfig.is_python_build`.
  (Contributed by Filipe Laíns in :gh:`92897`.)


threading
---------

* Remove support for arbitrary positional or keyword arguments in the C
  implementation of :class:`~threading.RLock` objects. This was deprecated
  in Python 3.14.
  (Contributed by Bénédikt Tran in :gh:`134087`.)


types
-----

* Removed :attr:`!codeobject.co_lnotab` from :class:`types.CodeType`,
  deprecated since Python 3.12 by :pep:`626`.
  (Contributed by Nikita Sobolev in :gh:`134690`.)


typing
------

* :class:`typing.ByteString` has been removed from ``typing.__all__``.
  :class:`!typing.ByteString` has been deprecated since Python 3.9, and is
  scheduled for removal in Python 3.17.

* The undocumented keyword argument syntax for creating
  :class:`~typing.NamedTuple` classes (for example,
  ``Point = NamedTuple("Point", x=int, y=int)``) is no longer supported.
  Use the class-based syntax or the functional syntax instead.
  (Contributed by Bénédikt Tran in :gh:`133817`.)

* Using ``TD = TypedDict("TD")`` or ``TD = TypedDict("TD", None)`` to
  construct a :class:`~typing.TypedDict` type with zero fields is no
  longer supported. Use ``class TD(TypedDict): pass``
  or ``TD = TypedDict("TD", {})`` instead.
  (Contributed by Bénédikt Tran in :gh:`133823`.)

* Deprecated :deco:`!typing.no_type_check_decorator` has been removed.
  (Contributed by Nikita Sobolev in :gh:`133601`.)


wave
----

* Removed the ``getmark()``, ``setmark()`` and ``getmarkers()`` methods
  of the :class:`~wave.Wave_read` and :class:`~wave.Wave_write` classes,
  which were deprecated since Python 3.13.
  (Contributed by Bénédikt Tran in :gh:`133873`.)


zipimport
---------

* Remove deprecated :meth:`!zipimport.zipimporter.load_module`.
  Use :meth:`zipimport.zipimporter.exec_module` instead.
  (Contributed by Jiahao Li in :gh:`133656`.)


Deprecated
==========

New deprecations
----------------

* :mod:`ast`

  * Creating instances of abstract AST nodes (such as :class:`ast.AST`
    or :class:`!ast.expr`) is deprecated and will raise an error in Python 3.20.

    (Contributed by Brian Schubert in :gh:`116021`.)

* :mod:`base64`:

  * Accepting the ``+`` and ``/`` characters with an alternative alphabet in
    :func:`~base64.b64decode` and :func:`~base64.urlsafe_b64decode` is now
    deprecated.
    In future Python versions they will be errors in the strict mode and
    discarded in the non-strict mode.
    (Contributed by Serhiy Storchaka in :gh:`125346`.)

* CLI:

  * Deprecate :option:`-b` and :option:`!-bb` command-line options
    and schedule them to become no-ops in Python 3.17.
    These were primarily helpers for the Python 2 -> 3 transition.
    Starting with Python 3.17, no :exc:`BytesWarning` will be raised
    for these cases; use a type checker instead.

    (Contributed by Nikita Sobolev in :gh:`136355`.)

* :mod:`collections.abc`

  * The following statements now cause ``DeprecationWarning``\ s to be emitted
    at runtime:

    * ``from collections.abc import ByteString``
    * ``import collections.abc; collections.abc.ByteString``.

    ``DeprecationWarning``\ s were already emitted if
    :class:`collections.abc.ByteString` was subclassed or used as the second
    argument to :func:`isinstance` or :func:`issubclass`, but warnings were not
    previously emitted if it was merely imported or accessed from the
    :mod:`!collections.abc` module.


* :mod:`hashlib`:

  * In hash function constructors such as :func:`~hashlib.new` or the
    direct hash-named constructors such as :func:`~hashlib.md5` and
    :func:`~hashlib.sha256`, the optional initial data parameter could
    also be passed as a keyword argument named ``data=`` or ``string=`` in
    various :mod:`hashlib` implementations.

    Support for the ``string`` keyword argument name is now deprecated and
    is slated for removal in Python 3.19. Prefer passing the initial data as
    a positional argument for maximum backwards compatibility.

    (Contributed by Bénédikt Tran in :gh:`134978`.)


* :mod:`http.cookies`:

  * :meth:`Morsel.js_output <http.cookies.Morsel.js_output>` and
    :meth:`BaseCookie.js_output <http.cookies.BaseCookie.js_output>` are
    deprecated and will be removed in Python 3.19. Use
    :meth:`Morsel.output <http.cookies.Morsel.output>` or
    :meth:`BaseCookie.output <http.cookies.BaseCookie.output>` instead.
    (Contributed by kishorhange111 in :gh:`148849`.)


* :mod:`imaplib`:

  * Altering :attr:`IMAP4.file <imaplib.IMAP4.file>` is now deprecated
    and slated for removal in Python 3.19. This property is now unused
    and changing its value does *not* explicitly close the current file.


* :mod:`profile`:

  * The :mod:`!profile` module is deprecated and will be removed in
    Python 3.17. Use :mod:`profiling.tracing` instead, which provides a
    compatible API. See :pep:`799` for details.
    (Contributed by Pablo Galindo and László Kiss Kollár in :gh:`138122`.)


* :mod:`re`:

  * :func:`re.match` and :meth:`re.Pattern.match` are now
    :term:`soft deprecated` in favor of the new :func:`re.prefixmatch` and
    :meth:`re.Pattern.prefixmatch` APIs, which have been added as alternate,
    more explicit names. These are intended to be used to alleviate confusion
    around what *match* means by following the Zen of Python's *"Explicit is
    better than implicit"* mantra. Most other language regular expression
    libraries use an API named *match* to mean what Python has always called
    *search*.

    We **do not** plan to remove the older :func:`!match` name, as it has been
    used in code for over 30 years. Code supporting older versions of Python
    should continue to use :func:`!match`, while new code should prefer
    :func:`!prefixmatch`. See :ref:`prefixmatch-vs-match`.

    (Contributed by Gregory P. Smith in :gh:`86519` and
    Hugo van Kemenade in :gh:`148100`.)


* :mod:`struct`:

  * Calling ``Struct.__new__()`` without a required argument is now
    deprecated and will be removed in Python 3.20.  Calling the
    :meth:`~object.__init__` method on an initialized :class:`~struct.Struct`
    object is deprecated and will be removed in Python 3.20.

    (Contributed by Sergey B Kirpichev and Serhiy Storchaka in :gh:`143715`.)

  * The ``'F'`` and ``'D'`` type codes are now :term:`soft deprecated`
    in favor of the two-letter forms ``'Zf'`` and ``'Zd'``.
    (Contributed by Sergey B Kirpichev in :gh:`121249`.)


* :mod:`typing`:

  * The following statements now cause ``DeprecationWarning``\ s to be emitted
    at runtime:

    * ``from typing import ByteString``
    * ``import typing; typing.ByteString``.

    ``DeprecationWarning``\ s were already emitted if :class:`typing.ByteString`
    was subclassed or used as the second argument to :func:`isinstance` or
    :func:`issubclass`, but warnings were not previously emitted if it was
    merely imported or accessed from the :mod:`!typing` module.

  * It is deprecated to call :func:`isinstance` and :func:`issubclass` checks on
    protocol classes that were not explicitly decorated with :func:`!runtime_checkable`
    but that inherit from a runtime-checkable protocol class.
    This will raise a :exc:`TypeError` in Python 3.20.

    (Contributed by Bartosz Sławecki in :gh:`132604`.)


* :mod:`webbrowser`:

  * :class:`!webbrowser.MacOSXOSAScript` is deprecated in favour of
    :class:`!webbrowser.MacOS` and scheduled for removal in Python 3.17.
    (Contributed by Jeff Lyon in :gh:`137586`.)

* ``__version__``

  * The ``__version__``, ``version`` and ``VERSION`` attributes have been
    deprecated in these standard library modules and will be removed in
    Python 3.20. Use :py:data:`sys.version_info` instead.

    - :mod:`argparse`
    - :mod:`csv`
    - :mod:`ctypes`
    - :mod:`!ctypes.macholib`
    - :mod:`decimal` (use :data:`decimal.SPEC_VERSION` instead)
    - :mod:`http.server`
    - :mod:`imaplib`
    - :mod:`ipaddress`
    - :mod:`json`
    - :mod:`logging` (``__date__`` also deprecated)
    - :mod:`optparse`
    - :mod:`pickle`
    - :mod:`platform`
    - :mod:`re`
    - :mod:`socketserver`
    - :mod:`tabnanny`
    - :mod:`tarfile`
    - :mod:`tkinter.font`
    - :mod:`tkinter.ttk`
    - :mod:`wsgiref.simple_server`
    - :mod:`xml.etree.ElementTree`
    - :mod:`!xml.sax.expatreader`
    - :mod:`xml.sax.handler`
    - :mod:`zlib`

    (Contributed by Hugo van Kemenade and Stan Ulbrych in :gh:`76007`.)

.. Add deprecations above alphabetically, not here at the end.

.. include:: ../deprecations/pending-removal-in-3.16.rst

.. include:: ../deprecations/pending-removal-in-3.17.rst

.. include:: ../deprecations/pending-removal-in-3.18.rst

.. include:: ../deprecations/pending-removal-in-3.19.rst

.. include:: ../deprecations/pending-removal-in-3.20.rst

.. include:: ../deprecations/pending-removal-in-future.rst

.. include:: ../deprecations/soft-deprecations.rst


C API changes
=============

New features
------------

* Add :c:func:`PyArg_ParseArray` and :c:func:`PyArg_ParseArrayAndKeywords`
  functions to parse arguments of functions using the :c:macro:`METH_FASTCALL`
  calling convention.
  (Contributed by Victor Stinner in :gh:`144175`.)

* Add the following functions for the new :class:`frozendict` type:

  * :c:func:`PyAnyDict_Check`
  * :c:func:`PyAnyDict_CheckExact`
  * :c:func:`PyFrozenDict_Check`
  * :c:func:`PyFrozenDict_CheckExact`
  * :c:func:`PyFrozenDict_New`

  (Contributed by Victor Stinner in :gh:`141510`.)

* Add :c:func:`PyObject_CallFinalizerFromDealloc` function to the limited C
  API.
  (Contributed by Victor Stinner in :gh:`146063`.)

* Add :c:func:`PySys_GetAttr`, :c:func:`PySys_GetAttrString`,
  :c:func:`PySys_GetOptionalAttr`, and :c:func:`PySys_GetOptionalAttrString`
  functions as replacements for :c:func:`PySys_GetObject`.
  (Contributed by Serhiy Storchaka in :gh:`108512`.)

* Add :c:func:`PyUnstable_Unicode_GET_CACHED_HASH` to get the cached hash of
  a string. See the documentation for caveats.
  (Contributed by Petr Viktorin in :gh:`131510`.)

* Add API for checking an extension module's ABI compatibility:
  :c:data:`Py_mod_abi`, :c:func:`PyABIInfo_Check`,
  and :c:macro:`PyABIInfo_VAR`.
  (Contributed by Petr Viktorin in :gh:`137210`.)

.. _whatsnew315-pybyteswriter:

* Implement :pep:`782`, the :ref:`PyBytesWriter API <pybyteswriter>`.
  Add functions:

  * :c:func:`PyBytesWriter_Create`
  * :c:func:`PyBytesWriter_Discard`
  * :c:func:`PyBytesWriter_Finish`
  * :c:func:`PyBytesWriter_FinishWithPointer`
  * :c:func:`PyBytesWriter_FinishWithSize`
  * :c:func:`PyBytesWriter_Format`
  * :c:func:`PyBytesWriter_GetData`
  * :c:func:`PyBytesWriter_GetSize`
  * :c:func:`PyBytesWriter_Grow`
  * :c:func:`PyBytesWriter_GrowAndUpdatePointer`
  * :c:func:`PyBytesWriter_Resize`
  * :c:func:`PyBytesWriter_WriteBytes`

  (Contributed by Victor Stinner in :gh:`129813`.)

* :c:type:`PyCriticalSection` and related functions are added to the Stable
  ABI.

  (Contributed in :gh:`149227`.)

* Add a new :c:func:`PyImport_CreateModuleFromInitfunc` C API for creating
  a module from a *spec* and *initfunc*.
  (Contributed by Itamar Oren in :gh:`116146`.)

* Add :c:func:`PyTuple_FromArray` to create a :class:`tuple` from an array.
  (Contributed by Victor Stinner in :gh:`111489`.)

* Add a new module export hook,
  :c:func:`PyModExport_* <PyModExport_modulename>`.

  (Contributed by Petr Viktorin in :pep:`793` and :gh:`140550`.)

* Add functions that are guaranteed to be safe for use in
  :c:member:`~PyTypeObject.tp_traverse` handlers:
  :c:func:`PyObject_GetTypeData_DuringGC`,
  :c:func:`PyObject_GetItemData_DuringGC`,
  :c:func:`PyType_GetModuleState_DuringGC`,
  :c:func:`PyModule_GetState_DuringGC`, :c:func:`PyModule_GetToken_DuringGC`,
  :c:func:`PyType_GetBaseByToken_DuringGC`,
  :c:func:`PyType_GetModule_DuringGC`,
  :c:func:`PyType_GetModuleByToken_DuringGC`.
  (Contributed by Petr Viktorin in :gh:`145925`.)

* Add :c:func:`PyObject_Dump` to dump an object to ``stderr``.
  It should only be used for debugging.
  (Contributed by Victor Stinner in :gh:`141070`.)

* Implement :pep:`820`: ``PySlot`` -- Unified slot system for the C API.
  See :ref:`capi-slots` for documentation.

  This adds:

  * The :c:type:`PySlot` struct;
  * the :c:func:`PyType_FromSlots` function;
  * new slot IDs: :c:macro:`Py_slot_end`, :c:macro:`Py_slot_invalid`;
    :c:macro:`Py_slot_subslots`, :c:macro:`Py_tp_slots`,
    :c:macro:`Py_mod_slots`;
    :c:macro:`Py_tp_name`, :c:macro:`Py_tp_basicsize`,
    :c:macro:`Py_tp_extra_basicsize`, :c:macro:`Py_tp_itemsize`,
    :c:macro:`Py_tp_flags`, :c:macro:`Py_tp_metaclass`,
    :c:macro:`Py_tp_module`;
  * convenience macros: :c:macro:`PySlot_DATA`, :c:macro:`PySlot_FUNC`,
    :c:macro:`PySlot_SIZE`, :c:macro:`PySlot_INT64`, :c:macro:`PySlot_UINT64`,
    :c:macro:`PySlot_STATIC_DATA`, :c:macro:`PySlot_END`,
    :c:macro:`PySlot_PTR`, :c:macro:`PySlot_PTR_STATIC`.

  The :c:func:`PyModule_FromSlotsAndSpec` function and
  ``PyModExport`` :ref:`module export hook <extension-export-hook>` also
  use the new :c:type:`!PySlot` struct.

  These following functions are :term:`soft deprecated`:

  * :c:func:`PyType_FromSpec`
  * :c:func:`PyType_FromSpecWithBases`
  * :c:func:`PyType_FromModuleAndSpec`
  * :c:func:`PyType_FromMetaclass`
  * :c:func:`PyModule_FromDefAndSpec`
  * :c:func:`PyModule_FromDefAndSpec2`
  * :c:func:`PyModule_ExecDef`


  The slots :c:macro:`Py_tp_bases` and :c:macro:`Py_tp_base` are now
  equivalent: they can be set either to a single type or a tuple of types.
  The :c:macro:`Py_tp_bases` slot is preferred; the other is ignored if both
  are specified.

  (Contributed by Petr Viktorin in :gh:`149044`.)

* Add :c:func:`PyUnstable_ThreadState_SetStackProtection` and
  :c:func:`PyUnstable_ThreadState_ResetStackProtection` functions to set
  the stack protection base address and stack protection size of a Python
  thread state.
  (Contributed by Victor Stinner in :gh:`139653`.)

* Add :c:func:`PyUnstable_SetImmortal` C API function to mark objects as :term:`immortal`.
  (Contributed by Kumar Aditya in :gh:`143300`.)

* Restore private provisional ``_Py_InitializeMain()`` function removed in
  Python 3.14.
  (Contributed by Victor Stinner in :gh:`142417`.)

* Add :c:func:`PyUnstable_DumpTraceback` and
  :c:func:`PyUnstable_DumpTracebackThreads` functions to output Python
  stacktraces.
  (Contributed by Alex Malyshev in :gh:`145559`.)

Changed C APIs
--------------

* If the :c:macro:`Py_TPFLAGS_MANAGED_DICT` or :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF`
  flag is set then :c:macro:`Py_TPFLAGS_HAVE_GC` must be set too.
  (Contributed by Sergey Miryanov in :gh:`134786`.)

* :c:macro:`PyDateTime_IMPORT` is now thread safe. Code that directly checks ``PyDateTimeAPI``
  for ``NULL`` should be updated to call :c:macro:`PyDateTime_IMPORT` instead.
  (Contributed by Kumar Aditya in :gh:`141563`.)


Removed C APIs
--------------

* Remove deprecated ``PyUnicode`` functions:

  * :c:func:`!PyUnicode_AsDecodedObject`:
    Use :c:func:`PyCodec_Decode` instead.
  * :c:func:`!PyUnicode_AsDecodedUnicode`:
    Use :c:func:`PyCodec_Decode` instead; note that some codecs (for example, "base64")
    may return a type other than :class:`str`, such as :class:`bytes`.
  * :c:func:`!PyUnicode_AsEncodedObject`:
    Use :c:func:`PyCodec_Encode` instead.
  * :c:func:`!PyUnicode_AsEncodedUnicode`:
    Use :c:func:`PyCodec_Encode` instead; note that some codecs (for example, "base64")
    may return a type other than :class:`bytes`, such as :class:`str`.

  (Contributed by Stan Ulbrych in :gh:`133612`.)

* :c:func:`!PyImport_ImportModuleNoBlock`: deprecated alias
  of :c:func:`PyImport_ImportModule`.
  (Contributed by Bénédikt Tran in :gh:`133644`.)

* :c:func:`!PyWeakref_GetObject` and :c:macro:`!PyWeakref_GET_OBJECT`:
  use :c:func:`PyWeakref_GetRef` instead. The |pythoncapi_compat_project|
  can be used to get :c:func:`!PyWeakref_GetRef` on Python 3.12 and older.
  (Contributed by Bénédikt Tran in :gh:`133644`.)

* Remove deprecated :c:func:`!PySys_ResetWarnOptions`.
  Clear :data:`sys.warnoptions` and :data:`!warnings.filters` instead.

  (Contributed by Nikita Sobolev in :gh:`138886`.)

The following functions are removed in favor of :c:func:`PyConfig_Get`.
The |pythoncapi_compat_project| can be used to get :c:func:`!PyConfig_Get`
on Python 3.13 and older.

* Python initialization functions:

  * :c:func:`!Py_GetExecPrefix`:
    use :c:func:`PyConfig_Get("base_exec_prefix") <PyConfig_Get>`
    (:data:`sys.base_exec_prefix`) instead.
    Use :c:func:`PyConfig_Get("exec_prefix") <PyConfig_Get>`
    (:data:`sys.exec_prefix`) if :ref:`virtual environments <venv-def>`
    need to be handled.
  * :c:func:`!Py_GetPath`:
    use :c:func:`PyConfig_Get("module_search_paths") <PyConfig_Get>`
    (:data:`sys.path`) instead.
  * :c:func:`!Py_GetPrefix`:
    use :c:func:`PyConfig_Get("base_prefix") <PyConfig_Get>`
    (:data:`sys.base_prefix`) instead.
    Use :c:func:`PyConfig_Get("prefix") <PyConfig_Get>`
    (:data:`sys.prefix`) if :ref:`virtual environments <venv-def>`
    need to be handled.
  * :c:func:`!Py_GetProgramFullPath`:
    use :c:func:`PyConfig_Get("executable") <PyConfig_Get>`
    (:data:`sys.executable`) instead.
  * :c:func:`!Py_GetProgramName`:
    use :c:func:`PyConfig_Get("executable") <PyConfig_Get>`
    (:data:`sys.executable`) instead.
  * :c:func:`!Py_GetPythonHome`:
    use :c:func:`PyConfig_Get("home") <PyConfig_Get>` or the
    :envvar:`PYTHONHOME` environment variable instead.

  (Contributed by Bénédikt Tran in :gh:`133644`.)

.. |pythoncapi_compat_project| replace:: |pythoncapi_compat_project_link|_
.. |pythoncapi_compat_project_link| replace:: pythoncapi-compat project
.. _pythoncapi_compat_project_link: https://github.com/python/pythoncapi-compat


Deprecated C APIs
-----------------

* Deprecate :pep:`456` support for providing an external definition
  of the string hashing scheme. Removal is scheduled for Python 3.19.

  Previously, embedders could define :c:macro:`Py_HASH_ALGORITHM` to be
  ``Py_HASH_EXTERNAL`` to indicate that the hashing scheme was provided
  externally but this feature was undocumented, untested and most likely
  unused.

  (Contributed by Bénédikt Tran in :gh:`141226`.)

* For unsigned integer formats in :c:func:`PyArg_ParseTuple`,
  accepting Python integers with value that is larger than the maximal value
  for the C type or less than the minimal value for the corresponding
  signed integer type of the same size is now deprecated.
  (Contributed by Serhiy Storchaka in :gh:`132629`.)

* :c:func:`PyBytes_FromStringAndSize(NULL, len) <PyBytes_FromStringAndSize>`
  and :c:func:`_PyBytes_Resize` are :term:`soft deprecated`,
  use the :c:type:`PyBytesWriter` API instead.
  (Contributed by Victor Stinner in :gh:`129813`.)

* :c:func:`!_PyObject_CallMethodId`, :c:func:`!_PyObject_GetAttrId` and
  :c:func:`!_PyUnicode_FromId` are deprecated since 3.15 and will be removed in
  3.20. Instead, use :c:func:`PyUnicode_InternFromString()` and cache the result in
  the module state, then call :c:func:`PyObject_CallMethod` or
  :c:func:`PyObject_GetAttr`.
  (Contributed by Victor Stinner in :gh:`141049`.)

* Deprecate :c:member:`~PyComplexObject.cval` field of the
  :c:type:`PyComplexObject` type.
  Use :c:func:`PyComplex_AsCComplex` and :c:func:`PyComplex_FromCComplex`
  to convert a Python complex number to/from the C :c:type:`Py_complex`
  representation.
  (Contributed by Sergey B Kirpichev in :gh:`128813`.)

* Functions :c:func:`_Py_c_sum`, :c:func:`_Py_c_diff`, :c:func:`_Py_c_neg`,
  :c:func:`_Py_c_prod`, :c:func:`_Py_c_quot`, :c:func:`_Py_c_pow` and
  :c:func:`_Py_c_abs` are :term:`soft deprecated`.
  (Contributed by Sergey B Kirpichev in :gh:`128813`.)

* :c:member:`~PyConfig.bytes_warning` is deprecated
  since 3.15 and will be removed in 3.17.
  (Contributed by Nikita Sobolev in :gh:`136355`.)

* :c:macro:`!Py_INFINITY` macro is :term:`soft deprecated`,
  use the C11 standard ``<math.h>`` :c:macro:`!INFINITY` instead.
  (Contributed by Sergey B Kirpichev in :gh:`141004`.)

* The following macros are :term:`soft deprecated`:

  - :c:macro:`Py_ALIGNED`: Prefer ``alignas`` instead.
  - :c:macro:`PY_FORMAT_SIZE_T`: Use ``"z"`` directly.
  - :c:macro:`Py_LL` and :c:macro:`Py_ULL`:
    Use standard suffixes, ``LL`` and ``ULL``.
  - :c:macro:`PY_LONG_LONG`, :c:macro:`PY_LLONG_MIN`, :c:macro:`PY_LLONG_MAX`,
    :c:macro:`PY_ULLONG_MAX`, :c:macro:`PY_INT32_T`, :c:macro:`PY_UINT32_T`,
    :c:macro:`PY_INT64_T`, :c:macro:`PY_UINT64_T`, :c:macro:`PY_SIZE_MAX`:
    Use C99 types/limits.
  - :c:macro:`Py_UNICODE_SIZE`: Use ``sizeof(wchar_t)`` directly.
  - :c:macro:`Py_VA_COPY`: Use ``va_copy`` directly.

  The macro :c:macro:`Py_UNICODE_WIDE`, which was scheduled for removal,
  is :term:`soft deprecated` instead.

  (Contributed by Petr Viktorin in :gh:`146175`.)

* :c:macro:`!Py_MATH_El` and :c:macro:`!Py_MATH_PIl` are deprecated
  since 3.15 and will be removed in 3.20.
  (Contributed by Sergey B Kirpichev in :gh:`141004`.)


.. Add C API deprecations above alphabetically, not here at the end.


Build changes
=============

* Removed implicit fallback to the bundled copy of the ``libmpdec`` library.
  Now this should be explicitly enabled with :option:`--with-system-libmpdec`
  set to ``no`` or with :option:`!--without-system-libmpdec`.
  (Contributed by Sergey B Kirpichev in :gh:`115119`.)

* The new configure option :option:`--with-missing-stdlib-config=FILE` allows
  distributors to pass a `JSON <https://www.json.org/json-en.html>`_
  configuration file containing custom error messages for :term:`standard library`
  modules that are missing or packaged separately.
  (Contributed by Stan Ulbrych and Petr Viktorin in :gh:`139707`.)

* The new configure option :option:`--with-pymalloc-hugepages` enables huge
  page support for :ref:`pymalloc <pymalloc>` arenas. When enabled, arena size
  increases to 2 MiB and allocation uses ``MAP_HUGETLB`` (Linux) or
  ``MEM_LARGE_PAGES`` (Windows) with automatic fallback to regular pages.
  On Windows, use ``build.bat --pymalloc-hugepages``.
  At runtime, huge pages must be explicitly enabled by setting the
  :envvar:`PYTHON_PYMALLOC_HUGEPAGES` environment variable to ``1``.

* Annotating anonymous mmap usage is now supported if the Linux kernel supports
  :manpage:`PR_SET_VMA_ANON_NAME <PR_SET_VMA(2const)>` (Linux 5.17 or newer).
  Annotations are visible in ``/proc/<pid>/maps`` if the kernel supports the feature
  and :option:`-X dev <-X>` is passed to Python,
  or Python is built in :ref:`debug mode <debug-build>`.
  (Contributed by Donghee Na in :gh:`141770`.)

* CPython is now built with frame pointers enabled by default
  (:pep:`831`). Pass :option:`--without-frame-pointers` to opt out.

  Authors of C extensions and native libraries built with custom build
  systems should ensure the unwind chain is intact.
  This is usually done by adding ``-fno-omit-frame-pointer`` and
  similar flags to ``CFLAGS``. See :option:`--without-frame-pointers`
  documentation for the specific flags Python uses.

  (Contributed by Pablo Galindo Salgado and Savannah Ostrowski in :gh:`149201`.)

.. _whatsnew315-windows-tail-calling-interpreter:

* 64-bit builds using Visual Studio 2026 (MSVC 18) may now use the new
  :ref:`tail-calling interpreter <whatsnew314-tail-call-interpreter>`.
  Results on Visual Studio 18.1.1 report between
  `15-20% <https://github.com/faster-cpython/ideas/blob/main/results/5800X-msvc.pgo2-vs-msvc.pgo.tc.svg>`__
  speedup on the geometric mean of pyperformance on Windows x86-64 over
  the switch-case interpreter on an AMD Ryzen 7 5800X. We have
  observed speedups ranging from 14% for large pure-Python libraries
  to 40% for long-running small pure-Python scripts on Windows.
  This was made possible by a new feature introduced in MSVC 18,
  which the official Windows 64-bit binaries on python.org__ now use.
  (Contributed by Chris Eibl, Ken Jin, and Brandt Bucher in :gh:`143068`.
  Special thanks to Steve Dower, and the MSVC team including Hulon Jenkins.)

  __ https://www.python.org/downloads/windows/


Porting to Python 3.15
======================

This section lists previously described changes and other bugfixes
that may require changes to your code.

* :class:`sqlite3.Connection` APIs have been cleaned up.

  * All parameters of :func:`sqlite3.connect` except *database* are now keyword-only.
  * The first three parameters of methods :meth:`~sqlite3.Connection.create_function`
    and :meth:`~sqlite3.Connection.create_aggregate` are now positional-only.
  * The first parameter of methods :meth:`~sqlite3.Connection.set_authorizer`,
    :meth:`~sqlite3.Connection.set_progress_handler` and
    :meth:`~sqlite3.Connection.set_trace_callback` is now positional-only.

  (Contributed by Serhiy Storchaka in :gh:`133595`.)

* :data:`resource.RLIM_INFINITY` is now always positive.
  Passing a negative integer value that corresponded to its old value
  (such as ``-1`` or ``-3``, depending on platform) to
  :func:`resource.setrlimit` and :func:`resource.prlimit` is now deprecated.
  (Contributed by Serhiy Storchaka in :gh:`137044`.)

* :meth:`mmap.mmap.resize` has been removed on platforms that don't support the
  underlying syscall, instead of raising a :exc:`SystemError`.

* A resource warning is now emitted for an unclosed
  :func:`xml.etree.ElementTree.iterparse` iterator if it opened a file.
  Use its :meth:`!close` method or the :func:`contextlib.closing` context
  manager to close it.
  (Contributed by Osama Abdelkader and Serhiy Storchaka in :gh:`140601`.)

* If a short option and a single-dash long option are passed to
  :meth:`argparse.ArgumentParser.add_argument`, *dest* is now inferred from
  the single-dash long option. For example, in ``add_argument('-f', '-foo')``,
  *dest* is now ``'foo'`` instead of ``'f'``.
  Pass an explicit *dest* argument to preserve the old behavior.
  (Contributed by Serhiy Storchaka in :gh:`138697`.)

* Padding of input no longer required in :func:`base64.urlsafe_b64decode`.
  Pass a new argument ``padded=True`` or use :func:`base64.b64decode`
  with argument ``altchars=b'-_'`` (this works with older Python versions)
  to make padding required.
  (Contributed by Serhiy Storchaka in :gh:`73613`.)

* Since :meth:`unittest.TestCase.assertWarns` and
  :meth:`unittest.TestCase.assertWarnsRegex` no longer swallow warnings that
  do not match the specified category or regex, your tests may start leaking
  some warnings that were previously masked.
  Use warning filters to silence them or additional :meth:`!assertWarns*`
  to catch and check them.
  (Contributed by Serhiy Storchaka in :gh:`143231`.)
