GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing docs.python.org — What’s New In Python 3.12 What’s New In Python 3.12¶
This article explains the new features in Python 3.12, compared to 3.11. Python 3.12 was released on October 2, 2023. For full details, see the changelog. See also PEP 693 – Python 3.12 Release Schedule Summary – Release highlights¶Python 3.12 is a stable release of the Python programming language,
with a mix of changes to the language and the standard library.
The library changes focus on cleaning up deprecated APIs, usability, and correctness.
Of note, the The language changes focus on usability,
as f-strings have had many limitations removed
and ‘Did you mean …’ suggestions continue to improve.
The new type parameter syntax
and This article doesn’t attempt to provide a complete specification of all new features, but instead gives a convenient overview. For full details, you should refer to the documentation, such as the Library Reference and Language Reference. If you want to understand the complete implementation and design rationale for a change, refer to the PEP for a particular new feature; but note that PEPs usually are not kept up-to-date once a feature has been fully implemented. New syntax features: New grammar features: Interpreter improvements:
Python data model improvements:
Significant improvements in the standard library:
Security improvements:
C API improvements: CPython implementation improvements:
New typing features:
Important deprecations, removals or restrictions:
New Features¶PEP 695: Type Parameter Syntax¶Generic classes and functions under PEP 484 were declared using a verbose syntax that left the scope of type parameters unclear and required explicit declarations of variance. PEP 695 introduces a new, more compact and explicit way to create generic classes and functions: def max[T](args: Iterable[T]) -> T: ... class list[T]: def __getitem__(self, index: int, /) -> T: ... def append(self, element: T) -> None: ... In addition, the PEP introduces a new way to declare type aliases
using the type Point = tuple[float, float] Type aliases can also be generic: type Point[T] = tuple[T, T] The new syntax allows declaring type IntFunc[**P] = Callable[P, int] # ParamSpec type LabeledTuple[*Ts] = tuple[str, *Ts] # TypeVarTuple type HashableSequence[T: Hashable] = Sequence[T] # TypeVar with bound type IntOrStrSequence[T: (int, str)] = Sequence[T] # TypeVar with constraints The value of type aliases and the bound and constraints of type variables created through this syntax are evaluated only on demand (see lazy evaluation). This means type aliases are able to refer to other types defined later in the file. Type parameters declared through a type parameter list are visible within the scope of the declaration and any nested scopes, but not in the outer scope. For example, they can be used in the type annotations for the methods of a generic class or in the class body. However, they cannot be used in the module scope after the class is defined. See Type parameter lists for a detailed description of the runtime semantics of type parameters. In order to support these scoping semantics, a new kind of scope is introduced, the annotation scope. Annotation scopes behave for the most part like function scopes, but interact differently with enclosing class scopes. In Python 3.13, annotations will also be evaluated in annotation scopes. See PEP 695 for more details. (PEP written by Eric Traut. Implementation by Jelle Zijlstra, Eric Traut, and others in gh-103764.) PEP 701: Syntactic formalization of f-strings¶PEP 701 lifts some restrictions on the usage of f-strings. Expression components inside f-strings can now be any valid Python expression, including strings reusing the same quote as the containing f-string, multi-line expressions, comments, backslashes, and unicode escape sequences. Let’s cover these in detail:
See PEP 701 for more details. As a positive side-effect of how this feature has been implemented (by parsing f-strings
with the PEG parser), now error messages for f-strings are more precise
and include the exact location of the error. For example, in Python 3.11, the following
f-string raises a >>> my_string = f"{x z y}" + f"{1 + 1}" File "<stdin>", line 1 (x z y) ^^^ SyntaxError: f-string: invalid syntax. Perhaps you forgot a comma? but the error message doesn’t include the exact location of the error within the line and also has the expression artificially surrounded by parentheses. In Python 3.12, as f-strings are parsed with the PEG parser, error messages can be more precise and show the entire line: >>> my_string = f"{x z y}" + f"{1 + 1}" File "<stdin>", line 1 my_string = f"{x z y}" + f"{1 + 1}" ^^^ SyntaxError: invalid syntax. Perhaps you forgot a comma? (Contributed by Pablo Galindo, Batuhan Taskaya, Lysandros Nikolaou, Cristián Maureira-Fredes and Marta Gómez in gh-102856. PEP written by Pablo Galindo, Batuhan Taskaya, Lysandros Nikolaou and Marta Gómez). PEP 684: A Per-Interpreter GIL¶PEP 684 introduces a per-interpreter GIL, so that sub-interpreters may now be created with a unique GIL per interpreter. This allows Python programs to take full advantage of multiple CPU cores. This is currently only available through the C-API, though a Python API is anticipated for 3.13. Use the new PyInterpreterConfig config = { .check_multi_interp_extensions = 1, .gil = PyInterpreterConfig_OWN_GIL, }; PyThreadState *tstate = NULL; PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config); if (PyStatus_Exception(status)) { return -1; } /* The new interpreter is now active in the current thread. */ For further examples how to use the C-API for sub-interpreters with a per-interpreter GIL, see Modules/_xxsubinterpretersmodule.c. (Contributed by Eric Snow in gh-104210, etc.) PEP 669: Low impact monitoring for CPython¶PEP 669 defines a new (Contributed by Mark Shannon in gh-103082.) PEP 688: Making the buffer protocol accessible in Python¶PEP 688 introduces a way to use the buffer protocol
from Python code. Classes that implement the The new PEP 709: Comprehension inlining¶Dictionary, list, and set comprehensions are now inlined, rather than creating a new single-use function object for each execution of the comprehension. This speeds up execution of a comprehension by up to two times. See PEP 709 for further details. Comprehension iteration variables remain isolated and don’t overwrite a variable of the same name in the outer scope, nor are they visible after the comprehension. Inlining does result in a few visible behavior changes:
(Contributed by Carl Meyer and Vladimir Matveev in PEP 709.) Improved Error Messages¶
New Features Related to Type Hints¶This section covers major changes affecting type hints and
the PEP 692: Using
|
imp |
importlib |
|---|---|
|
Insert |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See below |
Replace imp.load_source() with:
import importlib.util import importlib.machinery def load_source(modname, filename): loader = importlib.machinery.SourceFileLoader(modname, filename) spec = importlib.util.spec_from_file_location(modname, filename, loader=loader) module = importlib.util.module_from_spec(spec) # The module is always executed and not cached in sys.modules. # Uncomment the following line to cache the module. # sys.modules[module.__name__] = module loader.exec_module(module) return module
Remove imp functions and attributes with no replacements:
Undocumented functions:
imp.init_builtin()
imp.load_compiled()
imp.load_dynamic()
imp.load_package()
imp.lock_held(), imp.acquire_lock(), imp.release_lock():
the locking scheme has changed in Python 3.3 to per-module locks.
imp.find_module() constants: SEARCH_ERROR, PY_SOURCE,
PY_COMPILED, C_EXTENSION, PY_RESOURCE, PKG_DIRECTORY,
C_BUILTIN, PY_FROZEN, PY_CODERESOURCE, IMP_HOOK.
Remove locale’s locale.format() function, deprecated in Python 3.7:
use locale.format_string() instead.
(Contributed by Victor Stinner in gh-94226.)
The following undocumented sqlite3 features, deprecated in Python
3.10, are now removed:
sqlite3.enable_shared_cache()
sqlite3.OptimizedUnicode
If a shared cache must be used, open the database in URI mode using the
cache=shared query parameter.
The sqlite3.OptimizedUnicode text factory has been an alias for
str since Python 3.3. Code that previously set the text factory to
OptimizedUnicode can either use str explicitly, or rely on the
default value which is also str.
(Contributed by Erlend E. Aasland in gh-92548.)
Remove ssl’s ssl.RAND_pseudo_bytes() function, deprecated in Python 3.6:
use os.urandom() or ssl.RAND_bytes() instead.
(Contributed by Victor Stinner in gh-94199.)
Remove the ssl.match_hostname() function.
It was deprecated in Python 3.7. OpenSSL performs
hostname matching since Python 3.7, Python no longer uses the
ssl.match_hostname() function.
(Contributed by Victor Stinner in gh-94199.)
Remove the ssl.wrap_socket() function, deprecated in Python 3.7:
instead, create a ssl.SSLContext object and call its
ssl.SSLContext.wrap_socket method. Any package that still uses
ssl.wrap_socket() is broken and insecure. The function neither sends a
SNI TLS extension nor validates the server hostname. Code is subject to CWE 295
(Improper Certificate Validation).
(Contributed by Victor Stinner in gh-94199.)
Remove many long-deprecated unittest features:
A number of TestCase method aliases:
Deprecated alias |
Method Name |
Deprecated in |
|---|---|---|
|
3.1 |
|
|
3.1 |
|
|
3.1 |
|
|
3.1 |
|
|
3.1 |
|
|
3.1 |
|
|
3.1 |
|
|
3.2 |
|
|
3.2 |
|
|
3.2 |
|
|
3.2 |
|
|
3.2 |
|
|
3.2 |
|
|
3.2 |
|
|
3.5 |
You can use https://github.com/isidentical/teyit to automatically modernise your unit tests.
Undocumented and broken TestCase method
assertDictContainsSubset (deprecated in Python 3.2).
Undocumented TestLoader.loadTestsFromModule parameter use_load_tests
(deprecated and ignored since Python 3.5).
An alias of the TextTestResult class:
_TextTestResult (deprecated in Python 3.2).
(Contributed by Serhiy Storchaka in gh-89325.)
Remove support for obsolete browsers from webbrowser.
The removed browsers include: Grail, Mosaic, Netscape, Galeon, Skipstone,
Iceape, Firebird, and Firefox versions 35 and below (gh-102871).
Remove the ElementTree.Element.copy() method of the
pure Python implementation, deprecated in Python 3.10, use the
copy.copy() function instead. The C implementation of xml.etree.ElementTree
has no copy() method, only a __copy__() method.
(Contributed by Victor Stinner in gh-94383.)
Remove the suspicious rule from the documentation Makefile and
Doc/tools/rstlint.py, both in favor of sphinx-lint.
(Contributed by Julien Palard in gh-98179.)
Remove the keyfile and certfile parameters from the
ftplib, imaplib, poplib and smtplib modules,
and the key_file, cert_file and check_hostname parameters from the
http.client module,
all deprecated since Python 3.6. Use the context parameter
(ssl_context in imaplib) instead.
(Contributed by Victor Stinner in gh-94172.)
Remove Jython compatibility hacks from several stdlib modules and tests.
(Contributed by Nikita Sobolev in gh-99482.)
Remove _use_broken_old_ctypes_structure_semantics_ flag
from ctypes module.
(Contributed by Nikita Sobolev in gh-99285.)
This section lists previously described changes and other bugfixes that may require changes to your code.
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.)
Remove randrange() functionality deprecated since Python 3.10. Formerly,
randrange(10.0) losslessly converted to randrange(10). Now, it raises a
TypeError. Also, the exception raised for non-integer values such as
randrange(10.5) or randrange('10') has been changed from ValueError to
TypeError. This also prevents bugs where randrange(1e25) would silently
select from a larger range than randrange(10**25).
(Originally suggested by Serhiy Storchaka gh-86388.)
argparse.ArgumentParser changed encoding and error handler
for reading arguments from file (e.g. fromfile_prefix_chars option)
from default text encoding (e.g. locale.getpreferredencoding(False))
to filesystem encoding and error handler.
Argument files should be encoded in UTF-8 instead of ANSI Codepage on Windows.
Remove the asyncore-based smtpd module deprecated in Python 3.4.7
and 3.5.4. A recommended replacement is the
asyncio-based aiosmtpd PyPI module.
shlex.split(): Passing None for s argument now raises an
exception, rather than reading sys.stdin. The feature was deprecated
in Python 3.9.
(Contributed by Victor Stinner in gh-94352.)
The os module no longer accepts bytes-like paths, like
bytearray and memoryview types: only the exact
bytes type is accepted for bytes strings.
(Contributed by Victor Stinner in gh-98393.)
syslog.openlog() and syslog.closelog() now fail if used in subinterpreters.
syslog.syslog() may still be used in subinterpreters,
but now only if syslog.openlog() has already been called in the main interpreter.
These new restrictions do not apply to the main interpreter,
so only a very small set of users might be affected.
This change helps with interpreter isolation. Furthermore, syslog is a wrapper
around process-global resources, which are best managed from the main interpreter.
(Contributed by Donghee Na in gh-99127.)
The undocumented locking behavior of cached_property()
is removed, because it locked across all instances of the class, leading to high
lock contention. This means that a cached property getter function could now run
more than once for a single instance, if two threads race. For most simple
cached properties (e.g. those that are idempotent and simply calculate a value
based on other attributes of the instance) this will be fine. If
synchronization is needed, implement locking within the cached property getter
function or around multi-threaded access points.
sys._current_exceptions() now returns a mapping from thread-id to an
exception instance, rather than to a (typ, exc, tb) tuple.
(Contributed by Irit Katriel in gh-103176.)
When extracting tar files using tarfile or
shutil.unpack_archive(), pass the filter argument to limit features
that may be surprising or dangerous.
See Extraction filters for details.
The output of the tokenize.tokenize() and tokenize.generate_tokens()
functions is now changed due to the changes introduced in PEP 701. This
means that STRING tokens are not emitted any more for f-strings and the
tokens described in PEP 701 are now produced instead: FSTRING_START,
FSTRING_MIDDLE and FSTRING_END are now emitted for f-string “string”
parts in addition to the appropriate tokens for the tokenization in the
expression components. For example for the f-string f"start {1+1} end"
the old version of the tokenizer emitted:
1,0-1,18: STRING 'f"start {1+1} end"'
while the new version emits:
1,0-1,2: FSTRING_START 'f"' 1,2-1,8: FSTRING_MIDDLE 'start ' 1,8-1,9: OP '{' 1,9-1,10: NUMBER '1' 1,10-1,11: OP '+' 1,11-1,12: NUMBER '1' 1,12-1,13: OP '}' 1,13-1,17: FSTRING_MIDDLE ' end' 1,17-1,18: FSTRING_END '"'
Additionally, there may be some minor behavioral changes as a consequence of the changes required to support PEP 701. Some of these changes include:
The type attribute of the tokens emitted when tokenizing some invalid Python
characters such as ! has changed from ERRORTOKEN to OP.
Incomplete single-line strings now also raise tokenize.TokenError as incomplete
multiline strings do.
Some incomplete or invalid Python code now raises tokenize.TokenError instead of
returning arbitrary ERRORTOKEN tokens when tokenizing it.
Mixing tabs and spaces as indentation in the same file is not supported anymore and will
raise a TabError.
The threading module now expects the _thread module to have
an _is_main_interpreter attribute. It is a function with no
arguments that returns True if the current interpreter is the
main interpreter.
Any library or application that provides a custom _thread module
should provide _is_main_interpreter().
(See gh-112826.)
Python no longer uses setup.py to build shared C extension modules.
Build parameters like headers and libraries are detected in configure
script. Extensions are built by Makefile. Most extensions use
pkg-config and fall back to manual detection.
(Contributed by Christian Heimes in gh-93939.)
va_start() with two parameters, like va_start(args, format),
is now required to build Python.
va_start() is no longer called with a single parameter.
(Contributed by Kumar Aditya in gh-93207.)
CPython now uses the ThinLTO option as the default link time optimization policy if the Clang compiler accepts the flag. (Contributed by Donghee Na in gh-89536.)
Add COMPILEALL_OPTS variable in Makefile to override compileall
options (default: -j0) in make install. Also merged the 3
compileall commands into a single command to build .pyc files for all
optimization levels (0, 1, 2) at once.
(Contributed by Victor Stinner in gh-99289.)
Add platform triplets for 64-bit LoongArch:
loongarch64-linux-gnusf
loongarch64-linux-gnuf32
loongarch64-linux-gnu
(Contributed by Zhang Na in gh-90656.)
PYTHON_FOR_REGEN now require Python 3.10 or newer.
Autoconf 2.71 and aclocal 1.16.4 is now required to regenerate
!configure.
(Contributed by Christian Heimes in gh-89886.)
Windows builds and macOS installers from python.org now use OpenSSL 3.0.
PEP 697: Introduce the Unstable C API tier,
intended for low-level tools like debuggers and JIT compilers.
This API may change in each minor release of CPython without deprecation
warnings.
Its contents are marked by the PyUnstable_ prefix in names.
Code object constructors:
PyUnstable_Code_New() (renamed from PyCode_New)
PyUnstable_Code_NewWithPosOnlyArgs() (renamed from PyCode_NewWithPosOnlyArgs)
Extra storage for code objects (PEP 523):
PyUnstable_Eval_RequestCodeExtraIndex() (renamed from _PyEval_RequestCodeExtraIndex)
PyUnstable_Code_GetExtra() (renamed from _PyCode_GetExtra)
PyUnstable_Code_SetExtra() (renamed from _PyCode_SetExtra)
The original names will continue to be available until the respective API changes.
(Contributed by Petr Viktorin in gh-101101.)
PEP 697: Add an API for extending types whose instance memory layout is opaque:
PyType_Spec.basicsize can be zero or negative to specify
inheriting or extending the base class size.
PyObject_GetTypeData() and PyType_GetTypeDataSize()
added to allow access to subclass-specific instance data.
Py_TPFLAGS_ITEMS_AT_END and PyObject_GetItemData()
added to allow safely extending certain variable-sized types, including
PyType_Type.
Py_RELATIVE_OFFSET added to allow defining
members in terms of a subclass-specific struct.
(Contributed by Petr Viktorin in gh-103509.)
Add the new limited C API function PyType_FromMetaclass(),
which generalizes the existing PyType_FromModuleAndSpec() using
an additional metaclass argument.
(Contributed by Wenzel Jakob in gh-93012.)
API for creating objects that can be called using the vectorcall protocol was added to the Limited API:
The Py_TPFLAGS_HAVE_VECTORCALL flag is now removed from a class
when the class’s __call__() method is reassigned.
This makes vectorcall safe to use with mutable types (i.e. heap types
without the immutable flag, Py_TPFLAGS_IMMUTABLETYPE).
Mutable types that do not override tp_call now
inherit the Py_TPFLAGS_HAVE_VECTORCALL flag.
(Contributed by Petr Viktorin in gh-93274.)
The Py_TPFLAGS_MANAGED_DICT and Py_TPFLAGS_MANAGED_WEAKREF
flags have been added. This allows extensions classes to support object
__dict__ and weakrefs with less bookkeeping,
using less memory and with faster access.
API for performing calls using the vectorcall protocol was added to the Limited API:
This means that both the incoming and outgoing ends of the vector call protocol are now available in the Limited API. (Contributed by Wenzel Jakob in gh-98586.)
Add two new public functions,
PyEval_SetProfileAllThreads() and
PyEval_SetTraceAllThreads(), that allow to set tracing and profiling
functions in all running threads in addition to the calling one. (Contributed
by Pablo Galindo in gh-93503.)
Add new function PyFunction_SetVectorcall() to the C API
which sets the vectorcall field of a given PyFunctionObject.
(Contributed by Andrew Frost in gh-92257.)
The C API now permits registering callbacks via PyDict_AddWatcher(),
PyDict_Watch() and related APIs to be called whenever a dictionary
is modified. This is intended for use by optimizing interpreters, JIT
compilers, or debuggers.
(Contributed by Carl Meyer in gh-91052.)
Add PyType_AddWatcher() and PyType_Watch() API to register
callbacks to receive notification on changes to a type.
(Contributed by Carl Meyer in gh-91051.)
Add PyCode_AddWatcher() and PyCode_ClearWatcher()
APIs to register callbacks to receive notification on creation and
destruction of code objects.
(Contributed by Itamar Oren in gh-91054.)
Add PyFrame_GetVar() and PyFrame_GetVarString() functions to
get a frame variable by its name.
(Contributed by Victor Stinner in gh-91248.)
Add PyErr_GetRaisedException() and PyErr_SetRaisedException()
for saving and restoring the current exception.
These functions return and accept a single exception object,
rather than the triple arguments of the now-deprecated
PyErr_Fetch() and PyErr_Restore().
This is less error prone and a bit more efficient.
(Contributed by Mark Shannon in gh-101578.)
Add _PyErr_ChainExceptions1, which takes an exception instance,
to replace the legacy-API _PyErr_ChainExceptions, which is now
deprecated. (Contributed by Mark Shannon in gh-101578.)
Add PyException_GetArgs() and PyException_SetArgs()
as convenience functions for retrieving and modifying
the args passed to the exception’s constructor.
(Contributed by Mark Shannon in gh-101578.)
Add PyErr_DisplayException(), which takes an exception instance,
to replace the legacy-api PyErr_Display(). (Contributed by
Irit Katriel in gh-102755).
PEP 683: Introduce Immortal Objects, which allows objects to bypass reference counts, and related changes to the C-API:
_Py_IMMORTAL_REFCNT: The reference count that defines an objectas immortal.
_Py_IsImmortal Checks if an object has the immortal reference count.
PyObject_HEAD_INIT This will now initialize reference count to_Py_IMMORTAL_REFCNT when used with Py_BUILD_CORE.
SSTATE_INTERNED_IMMORTAL An identifier for interned unicode objectsthat are immortal.
SSTATE_INTERNED_IMMORTAL_STATIC An identifier for interned unicodeobjects that are immortal and static
sys.getunicodeinternedsize This returns the total number of unicodeobjects that have been interned. This is now needed for refleak.py to
correctly track reference counts and allocated blocks
(Contributed by Eddie Elizondo in gh-84436.)
PEP 684: Add the new Py_NewInterpreterFromConfig()
function and PyInterpreterConfig, which may be used
to create sub-interpreters with their own GILs.
(See PEP 684: A Per-Interpreter GIL for more info.)
(Contributed by Eric Snow in gh-104110.)
In the limited C API version 3.12, Py_INCREF() and
Py_DECREF() functions are now implemented as opaque function calls to
hide implementation details.
(Contributed by Victor Stinner in gh-105387.)
Legacy Unicode APIs based on Py_UNICODE* representation has been removed.
Please migrate to APIs based on UTF-8 or wchar_t*.
Argument parsing functions like PyArg_ParseTuple() doesn’t support
Py_UNICODE* based format (e.g. u, Z) anymore. Please migrate
to other formats for Unicode like s, z, es, and U.
tp_weaklist for all static builtin types is always NULL.
This is an internal-only field on PyTypeObject
but we’re pointing out the change in case someone happens to be
accessing the field directly anyway. To avoid breakage, consider
using the existing public C-API instead, or, if necessary, the
(internal-only) _PyObject_GET_WEAKREFS_LISTPTR() macro.
This internal-only PyTypeObject.tp_subclasses may now not be
a valid object pointer. Its type was changed to void* to
reflect this. We mention this in case someone happens to be accessing the
internal-only field directly.
To get a list of subclasses, call the Python method
__subclasses__() (using PyObject_CallMethod(),
for example).
Add support of more formatting options (left aligning, octals, uppercase
hexadecimals, intmax_t, ptrdiff_t, wchar_t C
strings, variable width and precision) in PyUnicode_FromFormat() and
PyUnicode_FromFormatV().
(Contributed by Serhiy Storchaka in gh-98836.)
An unrecognized format character in PyUnicode_FromFormat() and
PyUnicode_FromFormatV() now sets a SystemError.
In previous versions it caused all the rest of the format string to be
copied as-is to the result string, and any extra arguments discarded.
(Contributed by Serhiy Storchaka in gh-95781.)
Fix wrong sign placement in PyUnicode_FromFormat() and
PyUnicode_FromFormatV().
(Contributed by Philip Georgi in gh-95504.)
Extension classes wanting to add a __dict__ or weak reference slot
should use Py_TPFLAGS_MANAGED_DICT and
Py_TPFLAGS_MANAGED_WEAKREF instead of tp_dictoffset and
tp_weaklistoffset, respectively.
The use of tp_dictoffset and tp_weaklistoffset is still
supported, but does not fully support multiple inheritance
(gh-95589), and performance may be worse.
Classes declaring Py_TPFLAGS_MANAGED_DICT should call
_PyObject_VisitManagedDict() and _PyObject_ClearManagedDict()
to traverse and clear their instance’s dictionaries.
To clear weakrefs, call PyObject_ClearWeakRefs(), as before.
The PyUnicode_FSDecoder() function no longer accepts bytes-like
paths, like bytearray and memoryview types: only the exact
bytes type is accepted for bytes strings.
(Contributed by Victor Stinner in gh-98393.)
The Py_CLEAR, Py_SETREF and Py_XSETREF
macros now only evaluate their arguments once. If an argument has side
effects, these side effects are no longer duplicated.
(Contributed by Victor Stinner in gh-98724.)
The interpreter’s error indicator is now always normalized. This means
that PyErr_SetObject(), PyErr_SetString() and the other
functions that set the error indicator now normalize the exception
before storing it. (Contributed by Mark Shannon in gh-101578.)
_Py_RefTotal is no longer authoritative and only kept around
for ABI compatibility. Note that it is an internal global and only
available on debug builds. If you happen to be using it then you’ll
need to start using _Py_GetGlobalRefTotal().
The following functions now select an appropriate metaclass for the newly created type:
Creating classes whose metaclass overrides tp_new
is deprecated, and in Python 3.14+ it will be disallowed.
Note that these functions ignore tp_new of the metaclass, possibly
allowing incomplete initialization.
Note that PyType_FromMetaclass() (added in Python 3.12)
already disallows creating classes whose metaclass overrides tp_new
(__new__() in Python).
Since tp_new overrides almost everything PyType_From* functions do,
the two are incompatible with each other.
The existing behavior – ignoring the metaclass for several steps
of type creation – is unsafe in general, since (meta)classes assume that
tp_new was called.
There is no simple general workaround. One of the following may work for you:
If you control the metaclass, avoid using tp_new in it:
If initialization can be skipped, it can be done in
tp_init instead.
If the metaclass doesn’t need to be instantiated from Python,
set its tp_new to NULL using
the Py_TPFLAGS_DISALLOW_INSTANTIATION flag.
This makes it acceptable for PyType_From* functions.
Avoid PyType_From* functions: if you don’t need C-specific features
(slots or setting the instance size), create types by calling
the metaclass.
If you know the tp_new can be skipped safely, filter the deprecation
warning out using warnings.catch_warnings() from Python.
PyOS_InputHook and PyOS_ReadlineFunctionPointer are no
longer called in subinterpreters. This is
because clients generally rely on process-wide global state (since these
callbacks have no way of recovering extension module state).
This also avoids situations where extensions may find themselves running in a subinterpreter that they don’t support (or haven’t yet been loaded in). See gh-104668 for more info.
PyLongObject has had its internals changed for better performance.
Although the internals of PyLongObject are private, they are used
by some extension modules.
The internal fields should no longer be accessed directly, instead the API
functions beginning PyLong_... should be used instead.
Two new unstable API functions are provided for efficient access to the
value of PyLongObjects which fit into a single machine word:
Custom allocators, set via PyMem_SetAllocator(), are now
required to be thread-safe, regardless of memory domain. Allocators
that don’t have their own state, including “hooks”, are not affected.
If your custom allocator is not already thread-safe and you need
guidance then please create a new GitHub issue
and CC @ericsnowcurrently.
In accordance with PEP 699, the ma_version_tag field in PyDictObject
is deprecated for extension modules. Accessing this field will generate a compiler
warning at compile time. This field will be removed in Python 3.14.
(Contributed by Ramvikrams and Kumar Aditya in gh-101193. PEP by Ken Jin.)
Deprecate global configuration variable:
Py_HashRandomizationFlag: use PyConfig.use_hash_seed
and PyConfig.hash_seed
Py_LegacyWindowsFSEncodingFlag: use PyPreConfig.legacy_windows_fs_encoding
Py_LegacyWindowsStdioFlag: use PyConfig.legacy_windows_stdio
Py_FileSystemDefaultEncoding: use PyConfig.filesystem_encoding
Py_HasFileSystemDefaultEncoding: use PyConfig.filesystem_encoding
Py_FileSystemDefaultEncodeErrors: use PyConfig.filesystem_errors
Py_UTF8Mode: use PyPreConfig.utf8_mode (see Py_PreInitialize())
The Py_InitializeFromConfig() API should be used with
PyConfig instead.
(Contributed by Victor Stinner in gh-77782.)
Creating immutable types with mutable
bases is deprecated and will be disabled in Python 3.14. (gh-95388)
The structmember.h header is deprecated, though it continues to be
available and there are no plans to remove it.
Its contents are now available just by including Python.h,
with a Py prefix added if it was missing:
Type macros like Py_T_INT, Py_T_DOUBLE, etc.
(previously T_INT, T_DOUBLE, etc.)
The flags Py_READONLY (previously READONLY) and
Py_AUDIT_READ (previously all uppercase)
Several items are not exposed from Python.h:
T_OBJECT (use Py_T_OBJECT_EX)
T_NONE (previously undocumented, and pretty quirky)
The macro WRITE_RESTRICTED which does nothing.
The macros RESTRICTED and READ_RESTRICTED, equivalents of
Py_AUDIT_READ.
In some configurations, <stddef.h> is not included from Python.h.
It should be included manually when using offsetof().
The deprecated header continues to provide its original contents under the original names. Your old code can stay unchanged, unless the extra include and non-namespaced macros bother you greatly.
(Contributed in gh-47146 by Petr Viktorin, based on earlier work by Alexander Belopolsky and Matthias Braun.)
PyErr_Fetch() and PyErr_Restore() are deprecated.
Use PyErr_GetRaisedException() and
PyErr_SetRaisedException() instead.
(Contributed by Mark Shannon in gh-101578.)
PyErr_Display() is deprecated. Use PyErr_DisplayException()
instead. (Contributed by Irit Katriel in gh-102755).
_PyErr_ChainExceptions is deprecated. Use _PyErr_ChainExceptions1
instead. (Contributed by Irit Katriel in gh-102192.)
Using PyType_FromSpec(), PyType_FromSpecWithBases()
or PyType_FromModuleAndSpec() to create a class whose metaclass
overrides tp_new is deprecated.
Call the metaclass instead.
The ma_version_tag field in PyDictObject for extension modules
(PEP 699; gh-101193).
Creating immutable types with mutable
bases (gh-95388).
Functions to configure Python’s initialization, deprecated in Python 3.11:
PySys_SetArgvEx():
Set PyConfig.argv instead.
PySys_SetArgv():
Set PyConfig.argv instead.
Py_SetProgramName():
Set PyConfig.program_name instead.
Py_SetPythonHome():
Set PyConfig.home instead.
The Py_InitializeFromConfig() API should be used with
PyConfig instead.
Global configuration variables:
Py_DebugFlag:
Use PyConfig.parser_debug instead.
Py_VerboseFlag:
Use PyConfig.verbose instead.
Py_QuietFlag:
Use PyConfig.quiet instead.
Py_InteractiveFlag:
Use PyConfig.interactive instead.
Py_InspectFlag:
Use PyConfig.inspect instead.
Py_OptimizeFlag:
Use PyConfig.optimization_level instead.
Py_NoSiteFlag:
Use PyConfig.site_import instead.
Py_BytesWarningFlag:
Use PyConfig.bytes_warning instead.
Py_FrozenFlag:
Use PyConfig.pathconfig_warnings instead.
Py_IgnoreEnvironmentFlag:
Use PyConfig.use_environment instead.
Py_DontWriteBytecodeFlag:
Use PyConfig.write_bytecode instead.
Py_NoUserSiteDirectory:
Use PyConfig.user_site_directory instead.
Py_UnbufferedStdioFlag:
Use PyConfig.buffered_stdio instead.
Py_HashRandomizationFlag:
Use PyConfig.use_hash_seed
and PyConfig.hash_seed instead.
Py_IsolatedFlag:
Use PyConfig.isolated instead.
Py_LegacyWindowsFSEncodingFlag:
Use PyPreConfig.legacy_windows_fs_encoding instead.
Py_LegacyWindowsStdioFlag:
Use PyConfig.legacy_windows_stdio instead.
Py_FileSystemDefaultEncoding:
Use PyConfig.filesystem_encoding instead.
Py_HasFileSystemDefaultEncoding:
Use PyConfig.filesystem_encoding instead.
Py_FileSystemDefaultEncodeErrors:
Use PyConfig.filesystem_errors instead.
Py_UTF8Mode:
Use PyPreConfig.utf8_mode instead.
(see Py_PreInitialize())
The Py_InitializeFromConfig() API should be used with
PyConfig instead.
The bundled copy of libmpdecimal.
The PyImport_ImportModuleNoBlock():
Use PyImport_ImportModule() instead.
PyWeakref_GetObject() and PyWeakref_GET_OBJECT():
Use PyWeakref_GetRef() instead.
Py_UNICODE type and the Py_UNICODE_WIDE macro:
Use wchar_t instead.
Python initialization functions:
PySys_ResetWarnOptions():
Clear sys.warnoptions and warnings.filters instead.
Py_GetExecPrefix():
Get sys.exec_prefix instead.
Py_GetPath():
Get sys.path instead.
Py_GetPrefix():
Get sys.prefix instead.
Py_GetProgramFullPath():
Get sys.executable instead.
Py_GetProgramName():
Get sys.executable instead.
Py_GetPythonHome():
Get PyConfig.home
or the PYTHONHOME environment variable instead.
The following APIs are deprecated and will be removed, although there is currently no date scheduled for their removal.
Py_TPFLAGS_HAVE_FINALIZE:
Unneeded since Python 3.8.
PyErr_Fetch():
Use PyErr_GetRaisedException() instead.
PyErr_NormalizeException():
Use PyErr_GetRaisedException() instead.
PyErr_Restore():
Use PyErr_SetRaisedException() instead.
PyModule_GetFilename():
Use PyModule_GetFilenameObject() instead.
PyOS_AfterFork():
Use PyOS_AfterFork_Child() instead.
PySlice_GetIndicesEx():
Use PySlice_Unpack() and PySlice_AdjustIndices() instead.
PyUnicode_AsDecodedObject():
Use PyCodec_Decode() instead.
PyUnicode_AsDecodedUnicode():
Use PyCodec_Decode() instead.
PyUnicode_AsEncodedObject():
Use PyCodec_Encode() instead.
PyUnicode_AsEncodedUnicode():
Use PyCodec_Encode() instead.
PyUnicode_READY():
Unneeded since Python 3.12
PyErr_Display():
Use PyErr_DisplayException() instead.
_PyErr_ChainExceptions():
Use _PyErr_ChainExceptions1() instead.
PyBytesObject.ob_shash member:
call PyObject_Hash() instead.
PyDictObject.ma_version_tag member.
Thread Local Storage (TLS) API:
PyThread_create_key():
Use PyThread_tss_alloc() instead.
PyThread_delete_key():
Use PyThread_tss_free() instead.
PyThread_set_key_value():
Use PyThread_tss_set() instead.
PyThread_get_key_value():
Use PyThread_tss_get() instead.
PyThread_delete_key_value():
Use PyThread_tss_delete() instead.
PyThread_ReInitTLS():
Unneeded since Python 3.7.
Remove the token.h header file. There was never any public tokenizer C
API. The token.h header file was only designed to be used by Python
internals.
(Contributed by Victor Stinner in gh-92651.)
Legacy Unicode APIs have been removed. See PEP 623 for detail.
PyUnicode_WCHAR_KIND
PyUnicode_AS_UNICODE()
PyUnicode_AsUnicode()
PyUnicode_AsUnicodeAndSize()
PyUnicode_AS_DATA()
PyUnicode_FromUnicode()
PyUnicode_GET_SIZE()
PyUnicode_GetSize()
PyUnicode_GET_DATA_SIZE()
Remove the PyUnicode_InternImmortal() function macro.
(Contributed by Victor Stinner in gh-85858.)
Fixed is_global and is_private behavior in IPv4Address,
IPv6Address, IPv4Network and IPv6Network.
Headers with embedded newlines are now quoted on output.
The generator will now refuse to serialize (write) headers
that are improperly folded or delimited, such that they would be parsed as
multiple headers or joined with adjacent data.
If you need to turn this safety feature off,
set verify_generated_headers.
(Contributed by Bas Bloemsaat and Petr Viktorin in gh-121650.)
email.utils.getaddresses() and email.utils.parseaddr() now return
('', '') 2-tuples in more situations where invalid email addresses are
encountered, instead of potentially inaccurate values.
An optional strict parameter was added to these two functions:
use strict=False to get the old behavior, accepting malformed inputs.
getattr(email.utils, 'supports_strict_parsing', False) can be used to
check if the strict paramater is available.
(Contributed by Thomas Dwyer and Victor Stinner for gh-102988 to improve
the CVE-2023-27043 fix.)
The previously undocumented special function sys.getobjects(),
which only exists in specialized builds of Python, may now return objects
from other interpreters than the one it’s called in.
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.)
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.)
The ssl module now rejects TLS certificate chains that contain one
of a set of compromised eMudhra intermediate CA certificates. The affected
certificates are identified by their public key, so cross-signed copies that
reuse the same key are blocked as well. It is a defense-in-depth backstop
that applies even when an application supplies its own root CA bundle, and
regardless of whether the platform trust store has removed trust.
(Contributed by Christian Heimes in gh-160040 for CVE 2026-115557.)