What’s new in Python 3.15 — Python 3.15.0a8 documentation
index
modules
next
previous
Python
3.15.0a8 Documentation
What’s New in Python
What’s new in Python 3.15
Theme
What’s new in Python 3.15
Editor
Hugo van Kemenade
This article explains the new features in Python 3.15, compared to 3.14.
For full details, see the
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
PEP 810
Explicit lazy imports for faster startup times
PEP 814
Add frozendict built-in type
PEP 799
A dedicated profiling package for organizing Python
profiling tools
PEP 799
Tachyon: High frequency statistical sampling profiler
PEP 798
Unpacking in comprehensions
PEP 686
Python now uses UTF-8 as the default encoding
PEP 728
TypedDict
with typed extra items
PEP 747
Annotating type forms with TypeForm
PEP 800
: Disjoint bases in the type system
PEP 782
A new PyBytesWriter C API to create a Python bytes object
PEP 803
Stable ABI for Free-Threaded Builds
The JIT compiler has been significantly upgraded
Improved error messages
The official Windows 64-bit binaries now use the tail-calling interpreter
New features
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
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
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:
lazy
import
json
lazy
from
pathlib
import
Path
"Starting up..."
# json and pathlib not loaded yet
data
json
loads
'{"key": "value"}'
# json loads here
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
-X
lazy_imports
command-line
option and the
PYTHON_LAZY_IMPORTS
environment variable. Both
accept three values:
all
makes all imports lazy by default,
none
disables lazy imports entirely (even explicit
lazy
statements become
eager), and
normal
(the default) respects the
lazy
keyword in source
code. The
sys.set_lazy_imports()
and
sys.get_lazy_imports()
functions allow changing and querying this mode at runtime.
For more selective control,
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:
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
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
SyntaxError
. Neither star imports nor future imports can be lazy
lazy
from
module
import
and
lazy
from
__future__
import
...
both
raise
SyntaxError
).
See also
PEP 810
for the full specification and rationale.
(Contributed by Pablo Galindo Salgado and Dino Viehland in
gh-142349
.)
PEP 814
: Add frozendict built-in type
A new
immutable
type,
frozendict
, is added to the
builtins
module.
It does not allow modification after creation. A
frozendict
is not a subclass of
dict
it inherits directly from
object
. A
frozendict
is
hashable
as long as all of its keys and values are hashable. A
frozendict
preserves
insertion order, but comparison does not take order into account.
For example:
>>>
frozendict
>>>
frozendict({'x': 1, 'y': 2})
>>>
'z'
Traceback (most recent call last):
File
"
, line
, in
'z'
~^^^^^
TypeError
'frozendict' object does not support item assignment
>>>
frozendict
>>>
hash
==
hash
True
>>>
==
True
The following standard library modules have been updated to accept
frozendict
copy
decimal
json
marshal
plistlib
(only for serialization),
pickle
pprint
and
xml.etree.ElementTree
eval()
and
exec()
accept
frozendict
for
globals
, and
type()
and
str.maketrans()
accept
frozendict
for
dict
Code checking for
dict
type using
isinstance(arg,
dict)
can be
updated to
isinstance(arg,
(dict,
frozendict))
to accept also the
frozendict
type, or to
isinstance(arg,
collections.abc.Mapping)
to accept also other mapping types such as
MappingProxyType
See also
PEP 814
for the full specification and rationale.
(Contributed by Victor Stinner and Donghee Na in
gh-141510
.)
PEP 799
: A dedicated profiling package
A new
profiling
module has been added to organize Python’s built-in
profiling tools under a single, coherent namespace. This module contains:
profiling.tracing
: deterministic function-call tracing (relocated from
cProfile
).
profiling.sampling
: a new statistical sampling profiler (named Tachyon).
The
cProfile
module remains as an alias for backwards compatibility.
The
profile
module is deprecated and will be removed in Python 3.17.
See also
PEP 799
for further details.
(Contributed by Pablo Galindo and László Kiss Kollár in
gh-138122
.)
Tachyon: High frequency statistical sampling profiler
A new statistical sampling profiler (Tachyon) has been added as
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
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
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
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
. 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
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
.)
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,
itertools.chain()
, and
itertools.chain.from_iterable()
. For
example:
>>>
lists
[[
],
],
]]
>>>
for
in
lists
# equivalent to [x for L in lists for x in L]
[1, 2, 3, 4, 5]
>>>
sets
[{
},
},
}]
>>>
for
in
sets
# equivalent to {x for s in sets for x in s}
{1, 2, 3, 4}
>>>
dicts
[{
'a'
},
'b'
},
'a'
}]
>>>
**
for
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
for
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
in
agen())
is equivalent to
(x
async
for
in
agen()
for
in
a)
See also
PEP 798
for further details.
(Contributed by Adam Hartz in
gh-143055
.)
PEP 803
abi3t
– Stable ABI for Free-Threaded Builds
C extensions that target the
Stable ABI
can now be
compiled for the new
Stable ABI for Free-Threaded Builds
(also known
as
abi3t
), which makes them compatible with
free-threaded builds
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
basicsize
and
PyObject_GetTypeData()
, rather than making
PyObject
part of the instance struct; and
Switching from a
PyInit_
function to a new export hook,
PyModExport_*
, introduced for this
purpose in
PEP 793
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 did
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
Py_TARGET_ABI3T
as discussed
in
Compiling for Stable ABI
Improved error messages
The interpreter now provides more helpful suggestions in
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:
@dataclass
class
Circle
radius
float
@property
def
area
self
->
float
return
pi
self
radius
**
class
Container
def
__init__
self
inner
Circle
->
None
self
inner
inner
circle
Circle
radius
4.0
container
Container
circle
container
area
Running this code now produces a clearer suggestion:
Traceback (most recent call last):
File
"/home/pablogsal/github/python/main/lel.py"
, line
42
, in
container
area
^^^^^^^^^^^^^^
AttributeError
'Container' object has no attribute 'area'. Did you mean '.inner.area' instead of '.area'?
The interpreter now tries to provide a suggestion when
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:
>>>
class
...
pass
>>>
()
>>>
abcde
>>>
del
abcdf
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
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
opt-in 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
PYTHONUTF8=0
environment variable or the
-X
utf8=0
command-line option.
See also
PEP 686
for further details.
(Contributed by Adam Turner in
gh-133711
; PEP 686 written by Inada Naoki.)
Unraisable exceptions are now highlighted with color by default. This can be
controlled by
environment variables
(Contributed by Peter Bierma in
gh-134170
.)
The
__repr__()
of
ImportError
and
ModuleNotFoundError
now shows “name” and “path” as
name=
and
path=
if they were given
as keyword arguments at construction time.
(Contributed by Serhiy Storchaka, Oleg Iarygin, and Yoav Nir in
gh-74185
.)
The
__dict__
and
__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
-W
option and the
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
Decimal
and
Fraction
),
not only integers or floats, although this does not improve precision.
(Contributed by Serhiy Storchaka in
gh-67795
.)
Added
bytearray.take_bytes(n=None,
/)
to take
bytes out of a
bytearray
without copying. This enables optimizing code
which must return
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
take_bytes()
are listed below.
Suggested optimizing refactors
Description
Old
New
Return
bytes
after working with
bytearray
def
read
()
->
bytes
buffer
bytearray
1024
...
return
bytes
buffer
def
read
()
->
bytes
buffer
bytearray
1024
...
return
buffer
take_bytes
()
Empty a buffer getting the bytes
buffer
bytearray
1024
...
data
bytes
buffer
buffer
clear
()
buffer
bytearray
1024
...
data
buffer
take_bytes
()
Split a buffer at a specific separator
buffer
bytearray
'abc
\n
def'
buffer
find
\n
data
bytes
buffer
[:
])
del
buffer
[:
assert
data
==
'abc'
assert
buffer
==
bytearray
'def'
buffer
bytearray
'abc
\n
def'
buffer
find
\n
data
buffer
take_bytes
Split a buffer at a specific separator; discard after the separator
buffer
bytearray
'abc
\n
def'
buffer
find
\n
data
bytes
buffer
[:
])
buffer
clear
()
assert
data
==
'abc'
assert
len
buffer
==
buffer
bytearray
'abc
\n
def'
buffer
find
\n
buffer
resize
data
buffer
take_bytes
()
(Contributed by Cody Maloney in
gh-139871
.)
Many functions related to compiling or parsing Python code, such as
compile()
ast.parse()
symtable.symtable()
and
importlib.abc.InspectLoader.source_to_code()
, now allow the module
name to be passed. It is needed to unambiguously
filter
syntax warnings by module name.
(Contributed by Serhiy Storchaka in
gh-135801
.)
Allowed defining the
__dict__
and
__weakref__
__slots__
for any class.
(Contributed by Serhiy Storchaka in
gh-41779
.)
Allowed defining any
__slots__
for a class derived from
tuple
(including classes created by
collections.namedtuple()
).
(Contributed by Serhiy Storchaka in
gh-41779
.)
The
slice
type now supports subscription,
making it a
generic type
(Contributed by James Hilton-Balfe in
gh-128335
.)
The class
memoryview
now supports the
float
complex
and
double
complex
C types: formatting characters
'F'
and
'D'
respectively.
(Contributed by Sergey B Kirpichev in
gh-146151
.)
Allow the
count
argument of
bytes.replace()
to be a keyword.
(Contributed by Stan Ulbrych in
gh-147856
.)
Unary plus is now accepted in
match
literal patterns, mirroring
the existing support for unary minus.
(Contributed by Bartosz Sławecki in
gh-145239
.)
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
BooleanOptionalAction
action supports now single-dash
long options and alternate prefix characters.
(Contributed by Serhiy Storchaka in
gh-138525
.)
Changed the
suggest_on_error
parameter of
argparse.ArgumentParser
to
default to
True
. This enables suggestions for mistyped arguments by default.
(Contributed by Jakob Schluse in
gh-140450
.)
Added backtick markup support in description and epilog text to highlight
inline code when color output is enabled.
(Contributed by Savannah Ostrowski in
gh-142390
.)
array
Support the
float
complex
and
double
complex
C types:
formatting characters
'F'
and
'D'
respectively.
(Contributed by Sergey B Kirpichev in
gh-146151
.)
Support half-floats (16-bit IEEE 754 binary interchange format): formatting
character
'e'
(Contributed by Sergey B Kirpichev in
gh-146238
.)
base64
Added the
pad
parameter in
z85encode()
(Contributed by Hauke Dämpfling in
gh-143103
.)
Added the
padded
parameter in
b32encode()
b32decode()
b32hexencode()
b32hexdecode()
b64encode()
b64decode()
urlsafe_b64encode()
, and
urlsafe_b64decode()
(Contributed by Serhiy Storchaka in
gh-73613
.)
Added the
wrapcol
parameter in
b16encode()
b32encode()
b32hexencode()
b64encode()
b85encode()
, and
z85encode()
(Contributed by Serhiy Storchaka in
gh-143214
and
gh-146431
.)
Added the
ignorechars
parameter in
b16decode()
b32decode()
b32hexdecode()
b64decode()
b85decode()
, and
z85decode()
(Contributed by Serhiy Storchaka in
gh-144001
and
gh-146431
.)
binascii
Added functions for Base32 encoding:
b2a_base32()
and
a2b_base32()
(Contributed by James Seo in
gh-146192
.)
Added functions for Ascii85, Base85, and Z85 encoding:
b2a_ascii85()
and
a2b_ascii85()
b2a_base85()
and
a2b_base85()
(Contributed by James Seo and Serhiy Storchaka in
gh-101178
.)
Added the
padded
parameter in
b2a_base32()
a2b_base32()
b2a_base64()
, and
a2b_base64()
(Contributed by Serhiy Storchaka in
gh-73613
.)
Added the
wrapcol
parameter in
b2a_base64()
(Contributed by Serhiy Storchaka in
gh-143214
.)
Added the
alphabet
parameter in
b2a_base64()
and
a2b_base64()
(Contributed by Serhiy Storchaka in
gh-145980
.)
Added the
ignorechars
parameter in
a2b_hex()
unhexlify()
, and
a2b_base64()
(Contributed by Serhiy Storchaka in
gh-144001
and
gh-146431
.)
calendar
Calendar pages generated by the
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
.)
The
calendar
’s
command-line
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
.)
collections
Added
collections.Counter.__xor__()
and
collections.Counter.__ixor__()
to compute the symmetric difference
between
Counter
objects.
(Contributed by Raymond Hettinger in
gh-138682
.)
concurrent.futures
Improved error reporting when a child process in a
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
__enter__()
__exit__()
__aenter__()
, and
__aexit__()
in
ExitStack
and
contextlib.AsyncExitStack
, for
consistency with the
with
and
async
with
statements.
(Contributed by Serhiy Storchaka in
gh-144386
.)
dataclasses
Annotations for generated
__init__
methods no longer include internal
type names.
dbm
Added new
reorganize()
methods to
dbm.dumb
and
dbm.sqlite3
which allow to recover unused free space previously occupied by deleted entries.
(Contributed by Andrea Oliveri in
gh-134004
.)
difflib
Introduced the optional
color
parameter to
difflib.unified_diff()
enabling color output similar to
git diff
This can be controlled by
environment variables
(Contributed by Douglas Thor in
gh-133725
.)
Improved the styling of HTML diff pages generated by the
difflib.HtmlDiff
class, and migrated the output to the HTML5 standard.
(Contributed by Jiahao Li in
gh-134580
.)
functools
singledispatchmethod()
now supports non-
descriptor
callables.
(Contributed by Serhiy Storchaka in
gh-140873
.)
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
.)
hashlib
Ensure that hash functions guaranteed to be always
available
exist as
attributes of
hashlib
even if they will not work at runtime due to
missing backend implementations. For instance,
hashlib.md5
will no
longer raise
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
HTTPConnection
and
HTTPSConnection
constructors. This parameter overrides the default maximum number of allowed
response headers.
(Contributed by Alexander Enrique Urieles Nieto in
gh-131724
.)
http.cookies
Allow ‘
’ double quotes in cookie values.
(Contributed by Nick Burns and Senthil Kumaran in
gh-92936
.)
http.server
The logging of
BaseHTTPRequestHandler
as used by the
command-line interface
is colored by default.
This can be controlled with
environment variables
(Contributed by Hugo van Kemenade in
gh-146292
.)
inspect
Add parameters
inherit_class_doc
and
fallback_to_class_doc
for
getdoc()
(Contributed by Serhiy Storchaka in
gh-132686
.)
json
Add the
array_hook
parameter to
load()
and
loads()
functions:
allow a callback for JSON literal array types to customize Python lists in
the resulting decoded object. Passing combined
frozendict
to
object_pairs_hook
param and
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
setlocale()
now supports language codes with
-modifiers.
-modifiers are no longer silently removed in
getlocale()
but included in the language code.
(Contributed by Serhiy Storchaka in
gh-137729
.)
Undeprecate the
locale.getdefaultlocale()
function.
(Contributed by Victor Stinner in
gh-130796
.)
math
Add
math.isnormal()
and
math.issubnormal()
functions.
(Contributed by Sergey B Kirpichev in
gh-132908
.)
Add
math.fmax()
math.fmin()
and
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
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
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
mmap.mmap.set_name()
method
to annotate an anonymous memory mapping
if Linux kernel supports
PR_SET_VMA_ANON_NAME
(Linux 5.17 or newer).
(Contributed by Donghee Na in
gh-142419
.)
os
Add
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
.)
os.path
Add support of the all-but-last mode in
realpath()
(Contributed by Serhiy Storchaka in
gh-71189
.)
The
strict
parameter to
os.path.realpath()
accepts a new value,
os.path.ALLOW_MISSING
If used, errors other than
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
.)
pickle
Add support for pickling private methods and nested classes.
(Contributed by Zackery Spytz and Serhiy Storchaka in
gh-77188
.)
pprint
Add an
expand
keyword argument for
pprint.pprint()
pprint.pformat()
pprint.pp()
. If true, the output will be
formatted similar to pretty-printed
json.dumps()
when
indent
is supplied.
(Contributed by Stefan Todoran, Semyon Moroz and Hugo van Kemenade in
gh-112632
.)
Add t-string support to
pprint
(Contributed by Loïc Simon and Hugo van Kemenade in
gh-134551
.)
re
re.prefixmatch()
and a corresponding
re.Pattern.prefixmatch()
have been added as alternate, more explicit names for the existing
and now
soft deprecated
re.match()
and
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
(Contributed by Gregory P. Smith in
gh-86519
.)
resource
Add new constants:
RLIMIT_NTHR
RLIMIT_UMTXP
RLIMIT_THREADS
RLIM_SAVED_CUR
, and
RLIM_SAVED_MAX
(Contributed by Serhiy Storchaka in
gh-137512
.)
shelve
Added new
reorganize()
method to
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
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
command-line interface
has several new features:
SQL keyword completion on
(Contributed by Long Tan in
gh-133393
.)
Prompts, error messages, and help text are now colored.
This is enabled by default, see
Controlling color
for
details.
(Contributed by Stan Ulbrych and Łukasz Langa in
gh-133461
.)
Table, index, trigger, view, column, function, and schema completion on
(Contributed by Long Tan in
gh-136101
.)
ssl
Indicate through
ssl.HAS_PSK_TLS13
whether the
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
ssl.SSLContext.set_groups()
sets the groups allowed for doing
key agreement, extending the previous
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.
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.
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
ssl.SSLContext.set_ciphersuites()
for setting TLS 1.3
ciphers. For TLS 1.2 or earlier,
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:
ssl.get_sigalgs()
returns a list of all available TLS signature
algorithms. This call requires OpenSSL 3.4 or later.
ssl.SSLContext.set_client_sigalgs()
sets the signature algorithms
allowed for certificate-based client authentication.
ssl.SSLContext.set_server_sigalgs()
sets the signature algorithms
allowed for the server to complete the TLS handshake.
ssl.SSLSocket.client_sigalg()
returns the signature algorithm
selected for client authentication on the current connection. This call
requires OpenSSL 3.5 or later.
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
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
os.pidfd_open()
select.poll()
macOS and other BSD variants use
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
symtable.Function.get_cells()
and
symtable.Symbol.is_cell()
methods.
(Contributed by Yashp002 in
gh-143504
.)
sys
Add
sys.abi_info
namespace to improve access to ABI information.
(Contributed by Klaus Zimmermann in
gh-137476
.)
sys.monitoring
The
other events
PY_THROW
PY_UNWIND
RAISE
EXCEPTION_HANDLED
, and
RERAISE
) can now be turned on and disabled on a per code
object basis. Returning
DISABLE
from a callback for
one of these events disables the event for the entire code object (for the
current tool), rather than raising
ValueError
as in prior versions.
(Contributed by Gabriele N. Tornetta in
gh-146182
.)
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
.)
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
.)
extract()
and
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,
LinkFallbackError
(Contributed by Petr Viktorin for
CVE 2025-4330
and
CVE 2024-12718
.)
extract()
and
extractall()
no longer extract rejected members when
errorlevel()
is zero.
(Contributed by Matt Prodani and Petr Viktorin in
gh-112887
and
CVE 2025-4435
.)
extract()
and
extractall()
now replace slashes by backslashes in symlink targets on Windows to prevent
creation of corrupted links.
(Contributed by Christoph Walcher in
gh-57911
.)
timeit
The output of the
timeit
command-line interface is colored by default.
This can be controlled with
environment variables
(Contributed by Hugo van Kemenade in
gh-146609
.)
The command-line interface now colorizes error tracebacks
by default. This can be controlled with
environment variables
(Contributed by Yi Hong in
gh-139374
.)
Make the target time of
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
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
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
pack_content()
place_content()
and
grid_content()
which use Tk commands with new names (introduced
in Tk 8.6) instead of
*_slaves()
methods which use Tk commands
with outdated names.
(Contributed by Serhiy Storchaka in
gh-143754
.)
Added
Event
attributes
user_data
for Tk virtual events
and
detail
for
Enter
Leave
FocusIn
FocusOut
and
ConfigureRequest
events.
(Contributed by Matthias Kievernagel and Serhiy Storchaka in
gh-47655
.)
tomllib
The
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:
tbl
key
"a string"
moar-tbl
key
},
Add
\xHH
notation to basic strings for codepoints under 255,
and the
\e
escape for the escape character:
null
"null byte:
\x00
; letter a:
\x61
csi
\e
["
Seconds in datetime and time values are now optional.
The following are now valid:
dt
2010-02-03 14:15
14:15
(Contributed by Taneli Hukkinen in
gh-142956
.)
types
Expose the write-through
locals()
proxy type
as
types.FrameLocalsProxyType
This represents the type of the
frame.f_locals
attribute,
as described in
PEP 667
typing
PEP 747
: Add
TypeForm
, a new special form for annotating
values that are themselves type expressions.
TypeForm[T]
means “a type form object describing
(or a type
assignable to
)”. At runtime,
TypeForm(x)
simply returns
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
TypedDict
classes, or
list[int]
) expose precise signatures:
from
typing
import
Any
TypeForm
def
cast
](
typ
TypeForm
],
value
Any
->
...
(Contributed by Jelle Zijlstra in
gh-145033
.)
Code like
class
ExtraTypeVars(P1[S],
Protocol[T,
T2]):
...
now raises
TypeError
, because
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 in runtime before.
(Contributed by Nikita Sobolev in
gh-137191
.)
PEP 800
: Add
@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
is a disjoint base, then
child classes of that class cannot inherit from other disjoint bases that are
not parent or child classes of
. (Contributed by Jelle Zijlstra in
gh-148639
.)
TypeVarTuple
now accepts
bound
covariant
contravariant
, and
infer_variance
keyword arguments, matching the
interface of
TypeVar
and
ParamSpec
bound
semantics remain undefined in the specification.
unicodedata
The Unicode database has been updated to Unicode 17.0.0.
Add
unicodedata.isxidstart()
and
unicodedata.isxidcontinue()
functions to check whether a character can start or continue a
Unicode Standard Annex #31
identifier.
(Contributed by Stan Ulbrych in
gh-129117
.)
Add the
iter_graphemes()
function to iterate over grapheme clusters according to rules defined in
Unicode Standard Annex #29, “Unicode Text Segmentation”
Add
grapheme_cluster_break()
indic_conjunct_break()
and
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
block()
function to return the
Unicode block
assigned to a character.
(Contributed by Stan Ulbrych in
gh-66802
.)
unittest
unittest.TestCase.assertLogs()
will now accept a formatter
to control how messages are formatted.
(Contributed by Garry Cairns in
gh-134567
.)
urllib.parse
Add the
missing_as_none
parameter to
urlsplit()
urlparse()
and
urldefrag()
functions.
Add the
keep_empty
parameter to
urlunsplit()
and
urlunparse()
functions.
This allows to distinguish between empty and not defined URI components
and preserve 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
lib64
->
lib
symlink.
This means purelib and platlib of virtual environments no longer share the
same
lib
directory on platforms where
sys.platlibdir
is not
equal to
lib
(Contributed by Rui Xi in
gh-133951
.)
warnings
Improve filtering by module in
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
wave
Added
wave.Wave_read.getformat()
wave.Wave_write.getformat()
and
wave.Wave_write.setformat()
for explicit frame format handling.
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
.)
xml.parsers.expat
Add
SetAllocTrackerActivationThreshold()
and
SetAllocTrackerMaximumAmplification()
to
xmlparser
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
SetBillionLaughsAttackProtectionActivationThreshold()
and
SetBillionLaughsAttackProtectionMaximumAmplification()
to
xmlparser
objects to tune protections against
billion laughs
attacks.
(Contributed by Bénédikt Tran in
gh-90949
.)
zlib
Allow combining two Adler-32 checksums via
adler32_combine()
(Contributed by Callum Attryde and Bénédikt Tran in
gh-134635
.)
Allow combining two CRC-32 checksums via
crc32_combine()
(Contributed by Bénédikt Tran in
gh-134635
.)
Optimizations
mimalloc
is now used as the default allocator for
raw memory allocations such as via
PyMem_RawMalloc()
for better performance on
free-threaded builds
(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
csv.Sniffer.sniff()
delimiter detection is now up to 1.6x faster.
(Contributed by Maurycy Pawłowski-Wieroński in
gh-137628
.)
Upgraded JIT compiler
Results from the
pyperformance
benchmark suite report
6-7%
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%
speedup over the
tail calling 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
Better machine code generation
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
for all supported platforms.
(Contributed by Savannah Ostrowski in
gh-140973
.)
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
.)
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
.)
More JIT optimizations
More
constant-propagation
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
.)
Reference count
s 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 inplace 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
.)
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
.)
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
collections.abc
collections.abc.ByteString
has been removed from
collections.abc.__all__
collections.abc.ByteString
has been
deprecated since Python 3.12, and is scheduled for removal in Python 3.17.
ctypes
Removed the undocumented function
ctypes.SetPointerType()
which has been deprecated since Python 3.13.
(Contributed by Bénédikt Tran in
gh-133866
.)
datetime
strptime()
now raises
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
glob.glob0()
and
glob.glob1()
functions, which have been deprecated since Python 3.13. Use
glob.glob()
and pass a directory to its
root_dir
argument instead.
(Contributed by Barney Gale in
gh-137466
.)
http.server
Removed the
CGIHTTPRequestHandler
class
and the
--cgi
flag from the
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
importlib.resources.files()
function.
(Contributed by Semyon Moroz in
gh-138044
.)
pathlib
Removed deprecated
pathlib.PurePath.is_reserved()
Use
os.path.isreserved()
to detect reserved paths on Windows.
(Contributed by Nikita Sobolev in
gh-133875
.)
platform
Removed the
platform.java_ver()
function,
which was deprecated since Python 3.13.
(Contributed by Alexey Makridenko in
gh-133604
.)
sre_*
Removed
sre_compile
sre_constants
and
sre_parse
modules.
(Contributed by Stan Ulbrych in
gh-135994
.)
sysconfig
Removed the
check_home
parameter of
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
RLock
objects. This was deprecated
in Python 3.14.
(Contributed by Bénédikt Tran in
gh-134087
.)
typing
typing.ByteString
has been removed from
typing.__all__
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
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
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
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
Wave_read
and
Wave_write
classes,
which were deprecated since Python 3.13.
(Contributed by Bénédikt Tran in
gh-133873
.)
zipimport
Remove deprecated
zipimport.zipimporter.load_module()
Use
zipimport.zipimporter.exec_module()
instead.
(Contributed by Jiahao Li in
gh-133656
.)
Deprecated
New deprecations
base64
Accepting the
and
characters with an alternative alphabet in
b64decode()
and
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
-b
and
-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
BytesWarning
will be raised
for these cases; use a type checker instead.
(Contributed by Nikita Sobolev in
gh-136355
.)
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
collections.abc.ByteString
was subclassed or used as the second
argument to
isinstance()
or
issubclass()
, but warnings were not
previously emitted if it was merely imported or accessed from the
collections.abc
module.
hashlib
In hash function constructors such as
new()
or the
direct hash-named constructors such as
md5()
and
sha256()
, the optional initial data parameter could
also be passed as a keyword argument named
data=
or
string=
in
various
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
.)
re
re.match()
and
re.Pattern.match()
are now
soft deprecated
in favor of the new
re.prefixmatch()
and
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
We
do not
plan to remove the older
match()
name, as it has been
used in code for over 30 years. Code supporting older versions of Python
should continue to use
match()
, while new code should prefer
prefixmatch()
. See
prefixmatch() vs. match()
(Contributed by Gregory P. Smith in
gh-86519
and
Hugo van Kemenade in
gh-148100
.)
struct
Calling the
Struct.__new__()
without required argument now is
deprecated and will be removed in Python 3.20. Calling
__init__()
method on initialized
Struct
objects is deprecated and will be removed in Python 3.20.
(Contributed by Sergey B Kirpichev and Serhiy Storchaka in
gh-143715
.)
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
typing.ByteString
was subclassed or used as the second argument to
isinstance()
or
issubclass()
, but warnings were not previously emitted if it was
merely imported or accessed from the
typing
module.
__version__
The
__version__
version
and
VERSION
attributes have been
deprecated in these standard library modules and will be removed in
Python 3.20. Use
sys.version_info
instead.
argparse
csv
ctypes
ctypes.macholib
decimal
(use
decimal.SPEC_VERSION
instead)
http.server
imaplib
ipaddress
json
logging
__date__
also deprecated)
optparse
pickle
platform
re
socketserver
tabnanny
tarfile
tkinter.font
tkinter.ttk
wsgiref.simple_server
xml.etree.ElementTree
xml.sax.expatreader
xml.sax.handler
zlib
(Contributed by Hugo van Kemenade and Stan Ulbrych in
gh-76007
.)
Pending removal in Python 3.16
The import system:
Setting
__loader__
on a module while
failing to set
__spec__.loader
is deprecated. In Python 3.16,
__loader__
will cease to be set or
taken into consideration by the import system or the standard library.
array
The
'u'
format code (
wchar_t
has been deprecated in documentation since Python 3.3
and at runtime since Python 3.13.
Use the
'w'
format code (
Py_UCS4
for Unicode characters instead.
asyncio
asyncio.iscoroutinefunction()
is deprecated
and will be removed in Python 3.16;
use
inspect.iscoroutinefunction()
instead.
(Contributed by Jiahao Li and Kumar Aditya in
gh-122875
.)
asyncio
policy system is deprecated and will be removed in Python 3.16.
In particular, the following classes and functions are deprecated:
asyncio.AbstractEventLoopPolicy
asyncio.DefaultEventLoopPolicy
asyncio.WindowsSelectorEventLoopPolicy
asyncio.WindowsProactorEventLoopPolicy
asyncio.get_event_loop_policy()
asyncio.set_event_loop_policy()
Users should use
asyncio.run()
or
asyncio.Runner
with
loop_factory
to use the desired event loop implementation.
For example, to use
asyncio.SelectorEventLoop
on Windows:
import
asyncio
async
def
main
():
...
asyncio
run
main
(),
loop_factory
asyncio
SelectorEventLoop
(Contributed by Kumar Aditya in
gh-127949
.)
builtins
Bitwise inversion on boolean types,
~True
or
~False
has been deprecated since Python 3.12,
as it produces surprising and unintuitive results (
-2
and
-1
).
Use
not
instead for the logical negation of a Boolean.
In the rare case that you need the bitwise inversion of
the underlying integer, convert to
int
explicitly (
~int(x)
).
functools
Calling the Python implementation of
functools.reduce()
with
function
or
sequence
as keyword arguments has been deprecated since Python 3.14.
logging
Support for custom logging handlers with the
strm
argument is deprecated
and scheduled for removal in Python 3.16. Define handlers with the
stream
argument instead. (Contributed by Mariusz Felisiak in
gh-115032
.)
mimetypes
Valid extensions start with a ‘.’ or are empty for
mimetypes.MimeTypes.add_type()
Undotted extensions are deprecated and will
raise a
ValueError
in Python 3.16.
(Contributed by Hugo van Kemenade in
gh-75223
.)
shutil
The
ExecError
exception
has been deprecated since Python 3.14.
It has not been used by any function in
shutil
since Python 3.4,
and is now an alias of
RuntimeError
symtable
The
Class.get_methods
method
has been deprecated since Python 3.14.
sys
The
_enablelegacywindowsfsencoding()
function
has been deprecated since Python 3.13.
Use the
PYTHONLEGACYWINDOWSFSENCODING
environment variable instead.
sysconfig
The
sysconfig.expand_makefile_vars()
function
has been deprecated since Python 3.14.
Use the
vars
argument of
sysconfig.get_paths()
instead.
tarfile
The undocumented and unused
TarFile.tarfile
attribute
has been deprecated since Python 3.13.
Pending removal in Python 3.17
datetime
strptime()
calls using a format string containing
%e
(day of month) without a year.
This has been deprecated since Python 3.15.
(Contributed by Stan Ulbrych in
gh-70647
.)
collections.abc
collections.abc.ByteString
is scheduled for removal in Python 3.17.
Use
isinstance(obj,
collections.abc.Buffer)
to test if
obj
implements the
buffer protocol
at runtime. For use
in type annotations, either use
Buffer
or a union
that explicitly specifies the types your code supports (e.g.,
bytes
bytearray
memoryview
).
ByteString
was originally intended to be an abstract class that
would serve as a supertype of both
bytes
and
bytearray
However, since the ABC never had any methods, knowing that an object was an
instance of
ByteString
never actually told you anything useful
about the object. Other common buffer types such as
memoryview
were also never understood as subtypes of
ByteString
(either at
runtime or by static type checkers).
See
PEP 688
for more details.
(Contributed by Shantanu Jain in
gh-91896
.)
encodings
Passing non-ascii
encoding
names to
encodings.normalize_encoding()
is deprecated and scheduled for removal in Python 3.17.
(Contributed by Stan Ulbrych in
gh-136702
.)
typing
Before Python 3.14, old-style unions were implemented using the private class
typing._UnionGenericAlias
. This class is no longer needed for the implementation,
but it has been retained for backward compatibility, with removal scheduled for Python
3.17. Users should use documented introspection helpers like
typing.get_origin()
and
typing.get_args()
instead of relying on private implementation details.
typing.ByteString
, deprecated since Python 3.9, is scheduled for removal in
Python 3.17.
Use
isinstance(obj,
collections.abc.Buffer)
to test if
obj
implements the
buffer protocol
at runtime. For use
in type annotations, either use
Buffer
or a union
that explicitly specifies the types your code supports (e.g.,
bytes
bytearray
memoryview
).
ByteString
was originally intended to be an abstract class that
would serve as a supertype of both
bytes
and
bytearray
However, since the ABC never had any methods, knowing that an object was an
instance of
ByteString
never actually told you anything useful
about the object. Other common buffer types such as
memoryview
were also never understood as subtypes of
ByteString
(either at
runtime or by static type checkers).
See
PEP 688
for more details.
(Contributed by Shantanu Jain in
gh-91896
.)
Pending removal in Python 3.18
No longer accept a boolean value when a file descriptor is expected.
(Contributed by Serhiy Storchaka in
gh-82626
.)
decimal
The non-standard and undocumented
Decimal
format
specifier
'N'
, which is only supported in the
decimal
module’s
C implementation, has been deprecated since Python 3.13.
(Contributed by Serhiy Storchaka in
gh-89902
.)
Pending removal in Python 3.19
ctypes
Implicitly switching to the MSVC-compatible struct layout by setting
_pack_
but not
_layout_
on non-Windows platforms.
hashlib
In hash function constructors such as
new()
or the
direct hash-named constructors such as
md5()
and
sha256()
, their optional initial data parameter could
also be passed a keyword argument named
data=
or
string=
in
various
hashlib
implementations.
Support for the
string
keyword argument name is now deprecated
and slated for removal in Python 3.19.
Before Python 3.13, the
string
keyword parameter was not correctly
supported depending on the backend implementation of hash functions.
Prefer passing the initial data as a positional argument for maximum
backwards compatibility.
Pending removal in Python 3.20
Calling the
__new__()
method of
struct.Struct
without the
format
argument is deprecated and will be removed in Python 3.20. Calling
__init__()
method on initialized
Struct
objects is deprecated and will be removed in Python 3.20.
(Contributed by Sergey B Kirpichev and Serhiy Storchaka in
gh-143715
.)
The
__version__
version
and
VERSION
attributes have been
deprecated in these standard library modules and will be removed in
Python 3.20. Use
sys.version_info
instead.
argparse
csv
ctypes
ctypes.macholib
decimal
(use
decimal.SPEC_VERSION
instead)
http.server
imaplib
ipaddress
json
logging
__date__
also deprecated)
optparse
pickle
platform
re
socketserver
tabnanny
tarfile
tkinter.font
tkinter.ttk
wsgiref.simple_server
xml.etree.ElementTree
xml.sax.expatreader
xml.sax.handler
zlib
(Contributed by Hugo van Kemenade and Stan Ulbrych in
gh-76007
.)
Pending removal in future versions
The following APIs will be removed in the future,
although there is currently no date scheduled for their removal.
argparse
Nesting argument groups and nesting mutually exclusive
groups are deprecated.
Passing the undocumented keyword argument
prefix_chars
to
add_argument_group()
is now
deprecated.
The
argparse.FileType
type converter is deprecated.
builtins
Generators:
throw(type,
exc,
tb)
and
athrow(type,
exc,
tb)
signature is deprecated: use
throw(exc)
and
athrow(exc)
instead,
the single argument signature.
Currently Python accepts numeric literals immediately followed by keywords,
for example
0in
1or
0if
1else
. It allows confusing and
ambiguous expressions like
[0x1for
in
y]
(which can be interpreted as
[0x1
for
in
y]
or
[0x1f
or
in
y]
). A syntax warning is raised
if the numeric literal is immediately followed by one of keywords
and
else
for
if
in
is
and
or
. In a future release it
will be changed to a syntax error. (
gh-87999
Support for
__index__()
and
__int__()
method returning non-int type:
these methods will be required to return an instance of a strict subclass of
int
Support for
__float__()
method returning a strict subclass of
float
: these methods will be required to return an instance of
float
Support for
__complex__()
method returning a strict subclass of
complex
: these methods will be required to return an instance of
complex
Passing a complex number as the
real
or
imag
argument in the
complex()
constructor is now deprecated; it should only be passed
as a single positional argument.
(Contributed by Serhiy Storchaka in
gh-109218
.)
calendar
calendar.January
and
calendar.February
constants are
deprecated and replaced by
calendar.JANUARY
and
calendar.FEBRUARY
(Contributed by Prince Roshan in
gh-103636
.)
codecs
: use
open()
instead of
codecs.open()
. (
gh-133038
codeobject.co_lnotab
: use the
codeobject.co_lines()
method
instead.
datetime
utcnow()
use
datetime.datetime.now(tz=datetime.UTC)
utcfromtimestamp()
use
datetime.datetime.fromtimestamp(timestamp,
tz=datetime.UTC)
gettext
: Plural value must be an integer.
importlib
cache_from_source()
debug_override
parameter is
deprecated: use the
optimization
parameter instead.
importlib.metadata
EntryPoints
tuple interface.
Implicit
None
on return values.
logging
: the
warn()
method has been deprecated
since Python 3.3, use
warning()
instead.
mailbox
: Use of StringIO input and text mode is deprecated, use
BytesIO and binary mode instead.
os
: Calling
os.register_at_fork()
in a multi-threaded process.
os.path
os.path.commonprefix()
is deprecated, use
os.path.commonpath()
for path prefixes. The
os.path.commonprefix()
function is being deprecated due to having a misleading name and module.
The function is not safe to use for path prefixes despite being included in a
module about path manipulation, meaning it is easy to accidentally
introduce path traversal vulnerabilities into Python programs by using this
function.
pydoc.ErrorDuringImport
: A tuple value for
exc_info
parameter is
deprecated, use an exception instance.
re
: More strict rules are now applied for numerical group references
and group names in regular expressions. Only sequence of ASCII digits is now
accepted as a numerical reference. The group name in bytes patterns and
replacement strings can now only contain ASCII letters and digits and
underscore.
(Contributed by Serhiy Storchaka in
gh-91760
.)
shutil
rmtree()
’s
onerror
parameter is deprecated in
Python 3.12; use the
onexc
parameter instead.
ssl
options and protocols:
ssl.SSLContext
without protocol argument is deprecated.
ssl.SSLContext
set_npn_protocols()
and
selected_npn_protocol()
are deprecated: use ALPN
instead.
ssl.OP_NO_SSL*
options
ssl.OP_NO_TLS*
options
ssl.PROTOCOL_SSLv3
ssl.PROTOCOL_TLS
ssl.PROTOCOL_TLSv1
ssl.PROTOCOL_TLSv1_1
ssl.PROTOCOL_TLSv1_2
ssl.TLSVersion.SSLv3
ssl.TLSVersion.TLSv1
ssl.TLSVersion.TLSv1_1
threading
methods:
threading.Condition.notifyAll()
: use
notify_all()
threading.Event.isSet()
: use
is_set()
threading.Thread.isDaemon()
threading.Thread.setDaemon()
use
threading.Thread.daemon
attribute.
threading.Thread.getName()
threading.Thread.setName()
use
threading.Thread.name
attribute.
threading.currentThread()
: use
threading.current_thread()
threading.activeCount()
: use
threading.active_count()
typing.Text
gh-92332
).
The internal class
typing._UnionGenericAlias
is no longer used to implement
typing.Union
. To preserve compatibility with users using this private
class, a compatibility shim will be provided until at least Python 3.17. (Contributed by
Jelle Zijlstra in
gh-105499
.)
unittest.IsolatedAsyncioTestCase
: it is deprecated to return a value
that is not
None
from a test case.
urllib.parse
deprecated functions:
urlparse()
instead
splitattr()
splithost()
splitnport()
splitpasswd()
splitport()
splitquery()
splittag()
splittype()
splituser()
splitvalue()
to_bytes()
wsgiref
SimpleHandler.stdout.write()
should not do partial
writes.
xml.etree.ElementTree
: Testing the truth value of an
Element
is deprecated. In a future release it
will always return
True
. Prefer explicit
len(elem)
or
elem
is
not
None
tests instead.
sys._clear_type_cache()
is deprecated:
use
sys._clear_internal_caches()
instead.
Soft deprecations
There are no plans to remove
soft deprecated
APIs.
re.match()
and
re.Pattern.match()
are now
soft deprecated
in favor of the new
re.prefixmatch()
and
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
We
do not
plan to remove the older
match()
name, as it has been
used in code for over 30 years. Code supporting older versions of Python
should continue to use
match()
, while new code should prefer
prefixmatch()
. See
prefixmatch() vs. match()
(Contributed by Gregory P. Smith in
gh-86519
and
Hugo van Kemenade in
gh-148100
.)
C API changes
New features
Add
PyArg_ParseArray()
and
PyArg_ParseArrayAndKeywords()
functions to parse arguments of functions using the
METH_FASTCALL
calling convention.
(Contributed by Victor Stinner in
gh-144175
.)
Add the following functions for the new
frozendict
type:
PyAnyDict_Check()
PyAnyDict_CheckExact()
PyFrozenDict_Check()
PyFrozenDict_CheckExact()
PyFrozenDict_New()
(Contributed by Victor Stinner in
gh-141510
.)
Add
PySys_GetAttr()
PySys_GetAttrString()
PySys_GetOptionalAttr()
, and
PySys_GetOptionalAttrString()
functions as replacements for
PySys_GetObject()
(Contributed by Serhiy Storchaka in
gh-108512
.)
Add
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:
Py_mod_abi
PyABIInfo_Check()
PyABIInfo_VAR
and
Py_mod_abi
(Contributed by Petr Viktorin in
gh-137210
.)
Implement
PEP 782
, the
PyBytesWriter API
Add functions:
PyBytesWriter_Create()
PyBytesWriter_Discard()
PyBytesWriter_FinishWithPointer()
PyBytesWriter_FinishWithSize()
PyBytesWriter_Finish()
PyBytesWriter_Format()
PyBytesWriter_GetData()
PyBytesWriter_GetSize()
PyBytesWriter_GrowAndUpdatePointer()
PyBytesWriter_Grow()
PyBytesWriter_Resize()
PyBytesWriter_WriteBytes()
(Contributed by Victor Stinner in
gh-129813
.)
Add a new
PyImport_CreateModuleFromInitfunc()
C-API for creating
a module from a
spec
and
initfunc
(Contributed by Itamar Oren in
gh-116146
.)
Add
PyTuple_FromArray()
to create a
tuple
from an array.
(Contributed by Victor Stinner in
gh-111489
.)
Add functions that are guaranteed to be safe for use in
tp_traverse
handlers:
PyObject_GetTypeData_DuringGC()
PyObject_GetItemData_DuringGC()
PyType_GetModuleState_DuringGC()
PyModule_GetState_DuringGC()
PyModule_GetToken_DuringGC()
PyType_GetBaseByToken_DuringGC()
PyType_GetModule_DuringGC()
PyType_GetModuleByToken_DuringGC()
(Contributed by Petr Viktorin in
gh-145925
.)
Add
PyObject_Dump()
to dump an object to
stderr
It should only be used for debugging.
(Contributed by Victor Stinner in
gh-141070
.)
Add
PyUnstable_ThreadState_SetStackProtection()
and
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
PyUnstable_SetImmortal()
C-API function to mark objects as
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
.)
Changed C APIs
If the
Py_TPFLAGS_MANAGED_DICT
or
Py_TPFLAGS_MANAGED_WEAKREF
flag is set then
Py_TPFLAGS_HAVE_GC
must be set too.
(Contributed by Sergey Miryanov in
gh-134786
.)
PyDateTime_IMPORT
is now thread safe. Code that directly checks
PyDateTimeAPI
for
NULL
should be updated to call
PyDateTime_IMPORT
instead.
(Contributed by Kumar Aditya in
gh-141563
.)
Porting to Python 3.15
Private functions promoted to public C APIs:
The
pythoncapi-compat project
can be used to get most of these new
functions on Python 3.14 and older.
Removed C APIs
Remove deprecated
PyUnicode
functions:
PyUnicode_AsDecodedObject()
Use
PyCodec_Decode()
instead.
PyUnicode_AsDecodedUnicode()
Use
PyCodec_Decode()
instead; Note that some codecs (for example, “base64”)
may return a type other than
str
, such as
bytes
PyUnicode_AsEncodedObject()
Use
PyCodec_Encode()
instead.
PyUnicode_AsEncodedUnicode()
Use
PyCodec_Encode()
instead; Note that some codecs (for example, “base64”)
may return a type other than
bytes
, such as
str
(Contributed by Stan Ulbrych in
gh-133612
.)
PyImport_ImportModuleNoBlock()
: deprecated alias
of
PyImport_ImportModule()
(Contributed by Bénédikt Tran in
gh-133644
.)
PyWeakref_GetObject()
and
PyWeakref_GET_OBJECT
use
PyWeakref_GetRef()
instead. The
pythoncapi-compat project
can be used to get
PyWeakref_GetRef()
on Python 3.12 and older.
(Contributed by Bénédikt Tran in
gh-133644
.)
Remove deprecated
PySys_ResetWarnOptions()
Clear
sys.warnoptions
and
warnings.filters
instead.
(Contributed by Nikita Sobolev in
gh-138886
.)
The following functions are removed in favor of
PyConfig_Get()
The
pythoncapi-compat project
can be used to get
PyConfig_Get()
on Python 3.13 and older.
Python initialization functions:
Py_GetExecPrefix()
use
PyConfig_Get("base_exec_prefix")
sys.base_exec_prefix
) instead.
Use
PyConfig_Get("exec_prefix")
sys.exec_prefix
) if
virtual environments
need to be handled.
Py_GetPath()
use
PyConfig_Get("module_search_paths")
sys.path
) instead.
Py_GetPrefix()
use
PyConfig_Get("base_prefix")
sys.base_prefix
) instead.
Use
PyConfig_Get("prefix")
sys.prefix
) if
virtual environments
need to be handled.
Py_GetProgramFullPath()
use
PyConfig_Get("executable")
sys.executable
) instead.
Py_GetProgramName()
use
PyConfig_Get("executable")
sys.executable
) instead.
Py_GetPythonHome()
use
PyConfig_Get("home")
or the
PYTHONHOME
environment variable instead.
(Contributed by Bénédikt Tran in
gh-133644
.)
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
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
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
.)
PyBytes_FromStringAndSize(NULL,
len)
and
_PyBytes_Resize()
are
soft deprecated
use the
PyBytesWriter
API instead.
(Contributed by Victor Stinner in
gh-129813
.)
_PyObject_CallMethodId()
_PyObject_GetAttrId()
and
_PyUnicode_FromId()
are deprecated since 3.15 and will be removed in
3.20. Instead, use
PyUnicode_InternFromString()
and cache the result in
the module state, then call
PyObject_CallMethod()
or
PyObject_GetAttr()
(Contributed by Victor Stinner in
gh-141049
.)
Deprecate
cval
field of the
PyComplexObject
type.
Use
PyComplex_AsCComplex()
and
PyComplex_FromCComplex()
to convert a Python complex number to/from the C
Py_complex
representation.
(Contributed by Sergey B Kirpichev in
gh-128813
.)
Functions
_Py_c_sum()
_Py_c_diff()
_Py_c_neg()
_Py_c_prod()
_Py_c_quot()
_Py_c_pow()
and
_Py_c_abs()
are
soft deprecated
(Contributed by Sergey B Kirpichev in
gh-128813
.)
bytes_warning
is deprecated
since 3.15 and will be removed in 3.17.
(Contributed by Nikita Sobolev in
gh-136355
.)
Py_INFINITY
macro is
soft deprecated
use the C11 standard
INFINITY
instead.
(Contributed by Sergey B Kirpichev in
gh-141004
.)
The following macros are
soft deprecated
Py_ALIGNED
: Prefer
alignas
instead.
PY_FORMAT_SIZE_T
: Use
"z"
directly.
Py_LL
and
Py_ULL
Use standard suffixes,
LL
and
ULL
PY_LONG_LONG
PY_LLONG_MIN
PY_LLONG_MAX
PY_ULLONG_MAX
PY_INT32_T
PY_UINT32_T
PY_INT64_T
PY_UINT64_T
PY_SIZE_MAX
Use C99 types/limits.
Py_UNICODE_SIZE
: Use
sizeof(wchar_t)
directly.
Py_VA_COPY
: Use
va_copy
directly.
The macro
Py_UNICODE_WIDE
, which was scheduled for removal,
is
soft deprecated
instead.
(Contributed by Petr Viktorin in
gh-146175
.)
Py_MATH_El
and
Py_MATH_PIl
are deprecated
since 3.15 and will be removed in 3.20.
(Contributed by Sergey B Kirpichev in
gh-141004
.)
Build changes
Removed implicit fallback to the bundled copy of the
libmpdec
library.
Now this should be explicitly enabled with
--with-system-libmpdec
set to
no
or with
--without-system-libmpdec
(Contributed by Sergey B Kirpichev in
gh-115119
.)
The new configure option
--with-missing-stdlib-config=FILE
allows
distributors to pass a
JSON
configuration file containing custom error messages for
standard library
modules that are missing or packaged separately.
(Contributed by Stan Ulbrych and Petr Viktorin in
gh-139707
.)
The new configure option
--with-pymalloc-hugepages
enables huge
page support for
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
PYTHON_PYMALLOC_HUGEPAGES
environment variable to
Annotating anonymous mmap usage is now supported if Linux kernel supports
PR_SET_VMA_ANON_NAME
(Linux 5.17 or newer).
Annotations are visible in
/proc/
if the kernel supports the feature
and
-X
dev
is passed to the Python or Python is built in
debug mode
(Contributed by Donghee Na in
gh-141770
.)
64-bit builds using Visual Studio 2026 (MSVC 18) may now use the new
tail-calling interpreter
Results on Visual Studio 18.1.1 report between
15-20%
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.)
Porting to Python 3.15
This section lists previously described changes and other bugfixes
that may require changes to your code.
sqlite3.Connection
APIs have been cleaned up.
All parameters of
sqlite3.connect()
except
database
are now keyword-only.
The first three parameters of methods
create_function()
and
create_aggregate()
are now positional-only.
The first parameter of methods
set_authorizer()
set_progress_handler()
and
set_trace_callback()
is now positional-only.
(Contributed by Serhiy Storchaka in
gh-133595
.)
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
resource.setrlimit()
and
resource.prlimit()
is now deprecated.
(Contributed by Serhiy Storchaka in
gh-137044
.)
mmap.mmap.resize()
has been removed on platforms that don’t support the
underlying syscall, instead of raising a
SystemError
A resource warning is now emitted for an unclosed
xml.etree.ElementTree.iterparse()
iterator if it opened a file.
Use its
close()
method or the
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
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
base64.urlsafe_b64decode()
Pass a new argument
padded=True
or use
base64.b64decode()
with argument
altchars=b'-_'
(this works with older Python versions)
to make padding required.
(Contributed by Serhiy Storchaka in
gh-73613
.)
Table of Contents
What’s new in Python 3.15
Summary – Release highlights
New features
PEP 810
: Explicit lazy imports
PEP 814
: Add frozendict built-in type
PEP 799
: A dedicated profiling package
Tachyon: High frequency statistical sampling profiler
PEP 798
: Unpacking in Comprehensions
PEP 803
abi3t
– Stable ABI for Free-Threaded Builds
Improved error messages
Other language changes
New modules
math.integer
Improved modules
argparse
array
base64
binascii
calendar
collections
concurrent.futures
contextlib
dataclasses
dbm
difflib
functools
hashlib
http.client
http.cookies
http.server
inspect
json
locale
math
mimetypes
mmap
os
os.path
pickle
pprint
re
resource
shelve
socket
sqlite3
ssl
subprocess
symtable
sys
sys.monitoring
tarfile
timeit
tkinter
tomllib
types
typing
unicodedata
unittest
urllib.parse
venv
warnings
wave
xml.parsers.expat
zlib
Optimizations
base64 & binascii
csv
Upgraded JIT compiler
Removed
collections.abc
ctypes
datetime
glob
http.server
importlib.resources
pathlib
platform
sre_*
sysconfig
threading
typing
wave
zipimport
Deprecated
New deprecations
Pending removal in Python 3.16
Pending removal in Python 3.17
Pending removal in Python 3.18
Pending removal in Python 3.19
Pending removal in Python 3.20
Pending removal in future versions
Soft deprecations
C API changes
New features
Changed C APIs
Porting to Python 3.15
Removed C APIs
Deprecated C APIs
Build changes
Porting to Python 3.15
Previous topic
What’s New in Python
Next topic
What’s new in Python 3.14
This page
Report a bug
Improve this page
Show source
index
modules
next
previous
Python
3.15.0a8 Documentation
What’s New in Python
What’s new in Python 3.15
Theme
2001 Python Software Foundation.
This page is licensed under the Python Software Foundation License Version 2.
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
See
History and License
for more information.
The Python Software Foundation is a non-profit corporation.
Please donate.
Found a bug
Created using
Sphinx
8.2.3.
US