What’s new in Python 3.16

Editor:

TBD

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

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.16 moves towards release, so it’s worth checking back even after reading earlier versions.

Summary — release highlights

New features

Other language changes

New modules

  • None yet.

Improved modules

gzip

  • gzip.open() now accepts an optional argument mtime which is passed on to the constructor of the GzipFile class. (Contributed by Marin Misur in gh-91372.)

lzma

  • Add support of new BCJ filters ARM64 and RISC-V via lzma.FILTER_ARM64 and lzma.FILTER_RISCV. Note that the new filters will work only if runtime library supports them. ARM64 filter requires lzma 5.4.0 or newer while RISC-V requires 5.6.0 or newer. (Contributed by Chien Wong in gh-115988.)

os

  • Add os.pidfd_getfd() for duplicating a file descriptor from another process via a pidfd. Available on Linux 5.6+. (Contributed by Maurycy Pawłowski-Wieroński in gh-149464.)

xml

  • Add support for multiple multi-byte encodings in the XML parser: “cp932”, “cp949”, “cp950”, “Big5”,”EUC-JP”, “GB2312”, “GBK”, “johab”, and “Shift_JIS”. Add partial support (only the BMP characters) for multi-byte encodings “Big5-HKSCS”, “EUC_JIS-2004”, “EUC_JISX0213”, “Shift_JIS-2004”, “Shift_JISX0213”, “utf-8-sig” and non-standard aliases like “UTF8” (without hyphen). The parser now raises ValueError for known unsupported multi-byte encodings such us “ISO-2022-JP” or “raw-unicode-escape” instead of failing later, when encounter non-ASCII data. (Contributed by Serhiy Storchaka in gh-62259.)

Optimizations

module_name

  • TODO

Removed

annotationlib

asyncio

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.

mimetypes

shutil

  • The ExecError exception which has been deprecated since Python 3.14. It has not been used by any function in shutil since Python 3.4. (Contributed by Stan Ulbrych in gh-149567.)

symtable

  • The symtable.Class.get_methods() method which has been deprecated since Python 3.14.

sys

  • The _enablelegacywindowsfsencoding() function which has been deprecated since Python 3.13. Use the PYTHONLEGACYWINDOWSFSENCODING environment variable instead. (Contributed by Stan Ulbrych in gh-149595.)

sysconfig

  • The sysconfig.expand_makefile_vars() function which has been deprecated since Python 3.14. Use the vars argument of sysconfig.get_paths() instead. (Contributed by Stan Ulbrych in gh-149499.)

tarfile

  • The undocumented and unused tarfile.TarFile.tarfile attribute has been deprecated since Python 3.13.

Deprecated

  • abc

  • ast:

    • Classes slice, Index, ExtSlice, Suite, Param, AugLoad and AugStore, deprecated since Python 3.9, are no longer imported by from ast import * and issue a deprecation warning on use. The classes are slated for removal in Python 3.21. These types are not generated by the parser or accepted by the code generator.

    • The dims property of ast.Tuple objects, deprecated since Python 3.9, now issues a deprecation warning on use. This property is slated for removal in 3.21. Use ast.Tuple.elts instead.

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:

  • webbrowser:

    • webbrowser.MacOSXOSAScript is deprecated in favour of webbrowser.MacOS. (gh-137586)

  • 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.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.

  • http.cookies:

  • imaplib:

    • Altering IMAP4.file is now deprecated and slated for removal in Python 3.19. This property is now unused and changing its value does not automatically close the current file.

      Before Python 3.14, this property was used to implement the corresponding read() and readline() methods for IMAP4 but this is no longer the case since then.

Pending removal in Python 3.20

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 x, 1or x, 0if 1else 2. It allows confusing and ambiguous expressions like [0x1for x in y] (which can be interpreted as [0x1 for x in y] or [0x1f or x 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:

  • 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.

Porting to Python 3.16

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

Build changes

  • Remove the bundled copy of the libmpdec decimal library from the CPython source tree to simplify maintenence and updates. The decimal module will now unconditionally use the system’s libmpdec decimal library. Also remove the now unused --with-system-libmpdec configure flag. This change has no impact on binary releases of Python, which have been built against a separate copy of libmpdec for the past several releases.

    (Contributed by Sergey B Kirpichev in gh-115119.)

  • Add a --with-build-details-suffix configure flag to allow Linux distributions that co-install multiple versions of Python in the same tree to avoid build-details.json clashes.

    (Contributed by Stefano Rivera in gh-131372.)

C API changes

New features

  • TODO

Porting to Python 3.16

  • TODO

Deprecated C APIs

  • TODO

Removed C APIs