Changelog

Python next

Release date: XXXX-XX-XX

macOS

  • gh-151163: Updated macOS installer to include SQLite version 3.53.2.

  • gh-150644: When system logging is enabled (with config.use_system_logger, messages are now tagged as public. This allows the macOS 26 system logger to view messages without special configuration.

Windows

  • gh-152433: ssl: improve UWP build compatibility.

  • gh-152433: Restores the mmap module when CPython is built from source for specific Windows API sets.

  • gh-152433: Use the Windows API GetFileSizeEx() for memory mapped files, rather than the older GetFileSize().

  • gh-151163: Updated Windows builds to include SQLite version 3.53.2.

  • gh-151159: Updated bundled version of OpenSSL to 3.5.7.

  • gh-150836: Make installed tkinter work with Tcl/Tk 9 builds that embed the Tk script library in the Tk DLL on Windows.

  • gh-149786: Fixes virtual environment launchers on Windows free-threaded builds.

  • gh-124111: Updated Windows builds to use Tcl/Tk 9.0.3.

  • gh-138489: Windows distributions now include a build-details.json file (see PEP 739). The legacy installer does not install it, but all other distributions from python.org and all preset configurations in the PC\layout script will include one.

  • gh-140146: Prevent tkinter from hanging on Windows if stdin is redirected to a pipe in an interactive session. This is helpful for testing interactive usage of tkinter from a script, for example as part of the cpython test suite.

Tools/Demos

  • gh-150258: Update the tooltip on the Tachyon flame graph to show both absolute and relative percentages.

  • gh-111501: PS1 is no longer exported by venv activate script

Tests

  • gh-151626: Fix several tests in test.test_inspect, test.test_import, test.test_importlib, test.test_py_compile and test.test_compileall that failed when the test suite was run with PYTHONPYCACHEPREFIX set. These tests now neutralize the pycache prefix where they assume the default __pycache__ bytecode layout.

  • gh-151096: Fix test_embed failing when CPython is configured with a split exec prefix (--exec-prefix differing from --prefix).

  • gh-151130: Add more tests for PyWeakref_* C API.

  • gh-150966: Avoid prematurely terminating failing live sampling profiler test targets, which made stderr assertions flaky on ASAN buildbots.

  • gh-150387: Fix hang in test.test_profiling.test_sampling_profiler.test_live_collector_ui.TestLiveModeErrors.test_run_failed_script_live on slow buildbots. The test now always queues a final q keystroke so the live TUI loop exits even when the profiler collects enough samples to enter the post-finished input loop.

  • gh-150114: On Linux, regrtest now logs the total memory usage of all Python processes. Read the private memory in /proc/pid/smaps. Patch by Victor Stinner.

  • gh-149776: Fix test_socket on Linux kernel 7.1 and newer: skip UDP Lite tests if it’s not supported. Patch by Victor Stinner.

  • gh-148853: Fix tests failing on FreeBSD in test.support’s in_systemd_nspawn_sync_suppressed() due to unreadable /run directory.

Security

  • gh-153030: Fixed quadratic complexity in incremental parsing of long unterminated constructs (such as tags or comments) in html.parser.HTMLParser, which could be exploited for a denial of service.

  • gh-152216: Update bundled libexpat to version 2.8.2.

  • gh-151987: The tarfile.TarFile.extract() method now applies the given filter when it extracts a link target from the archive as a fallback.

  • gh-151981: In tarfile, seeking a stream now stops when end of the stream is reached.

  • gh-151544: Modules/Setup.local is no longer used as a landmark to discover whether Python is running in a source tree, as it could potentially affect actual installs. The pybuilddir.txt file is now the sole indicator of running in a source tree.

  • gh-151558: Fixed an vulnerability in the tarfile data and tar extraction filters where crafted archives could create a symlink pointing outside the destination directory. This was a bypass of CVE 2025-4330.

  • gh-151159: Update macOS installer to use OpenSSL 3.5.7.

  • gh-151159: Update Android and iOS installers to use OpenSSL 3.5.7.

  • gh-150599: Fix a possible stack buffer overflow in bz2 when a bz2.BZ2Decompressor is reused after a decompression error. The decompressor now becomes unusable after libbz2 reports an error.

  • gh-150743: http.client now limits the number of chunked-response trailer lines it will read to max_response_headers (100 by default), and the number of interim (1xx) responses it will skip to 100. A malicious or broken server could previously stream trailer lines or 100 Continue responses forever, hanging the client even when a socket timeout was in use. Reported by @YLChen-007 via GHSA-w4q2-g22w-6fr4.

  • gh-149835: shutil.move() now resolves symlinks via os.path.realpath() when checking whether the destination is inside the source directory, preventing a symlink-based bypass of that guard.

  • gh-149698: Update bundled libexpat to version 2.8.1 for the fix for CVE 2026-45186.

  • gh-87451: The ftplib module’s undocumented ftpcp function no longer trusts the IPv4 address value returned from the source server in response to the PASV command by default, completing the fix for CVE-2021-4189. As with ftplib.FTP, the former behavior can be re-enabled by setting the trust_server_pasv_ipv4_address attribute on the source ftplib.FTP instance to True. Thanks to Qi Deng at Aurascape AI for the report.

  • gh-149474: Fix the binary writer in profiling.sampling not firing the audit (PEP 578) when creating the output file. The writer and the reader now accept any path-like object. Patch by Maurycy Pawłowski-Wieroński.

  • gh-149486: tarfile.data_filter() now validates link targets using the same normalised value that is written to disk, strips trailing separators from the member name when resolving a symlink’s directory, and rejects link members that would replace the destination directory itself. This closes several path-traversal bypasses of the data extraction filter.

  • gh-149079: Fix a potential denial of service in unicodedata.normalize(). The canonical ordering step of Unicode normalization used a quadratic-time insertion sort for reordering combining characters, which could be exploited with crafted input containing many combining characters in non-canonical order. Replaced with a linear-time counting sort for long runs.

  • gh-149018: Improved protection against XML hash-flooding attacks in xml.parsers.expat and xml.etree.ElementTree when Python is compiled with libExpat 2.8.0 or later.

  • gh-143927: Normalize all line endings (CR, CRLF, and LF) to LF+TAB when writing multi-line configparser values.

Library

  • gh-153761: Fix cancelling asyncio.loop.sock_accept() dropping a pending connection.

  • gh-153695: Hashing a sqlite3.Row that contains an unhashable value now raises TypeError instead of SystemError. Patch by tonghuaroot.

  • gh-153658: Fix sqlite3.Connection.iterdump() raising sqlite3.OperationalError when a table name contains a single quote. Patch by tonghuaroot.

  • gh-98078: Fix asyncio SSL transports not sending the fatal TLS alert to the peer when the TLS handshake fails or when receiving corrupted data, and not sending the close_notify alert to the peer when the TLS shutdown fails. The peer can now tell why the connection was dropped (for example, certificate verification failure or no TLS version in common) instead of seeing the connection abruptly closed.

  • gh-153502: imaplib.IMAP4.copy(), move(), fetch(), store(), search(), sort(), thread() and expunge() now accept a keyword-only uid argument that selects the corresponding UID command, as a more convenient alternative to uid().

  • gh-153494: imaplib.IMAP4.search(), sort() and thread() (and the corresponding uid commands) now encode str search criteria to the declared charset, so international search text can be passed as ordinary str. When charset is None (as it must be under UTF8=ACCEPT), the criteria are sent using the connection encoding instead. A criterion passed as bytes is sent unchanged, for use with a charset that Python has no codec for.

  • gh-153513: Values of several Tcl object types returned by tkinter are now converted to the corresponding Python type instead of being wrapped in a _tkinter.Tcl_Obj: index, window, nsName and parsedVarName objects to str, and pixel screen distances with no unit suffix to int or float.

  • gh-151292: Store the sample count in profiling.sampling binary format, as a 64-bit integer, widening from previously used 32-bit integer. This breaks the existing recordings. Long or thread-heavy profiling sessions will no longer fail because of OverflowError. Patch by Maurycy Pawłowski-Wieroński.

  • gh-153417: Error messages from imaplib.IMAP4.select() and imaplib.IMAP4.uid() no longer raise BytesWarning under -bb when the mailbox or command argument is bytes.

  • gh-153422: winfo_exists(), winfo_ismapped() and winfo_viewable() methods of tkinter widgets and edit_modified() of tkinter.Text now return a bool instead of an integer or, depending on wantobjects, a string.

  • gh-49555: imaplib now encodes non-ASCII mailbox names as modified UTF-7 (RFC 3501, section 5.1.3) in the default mode, so international mailbox names can be passed as ordinary str; under UTF8=ACCEPT they are sent as UTF-8 instead. A name that is not valid modified UTF-7, such as one with a bare &, is now encoded correctly instead of being sent as is. A str that is already valid modified UTF-7, or a bytes object, is sent unchanged.

  • gh-153406: email.utils.parsedate_to_datetime() now raises ValueError instead of OverflowError when the parsed year or timezone offset is out of range, matching its documented behavior.

  • gh-153333: The readprofile method of tkinter.Tk now reads the user’s profile scripts using the encoding declared in the file, instead of the locale encoding.

  • gh-153083: Defer GC tracking of an array.array to the end of its construction. Patch by Donghee Na.

  • gh-153292: Fix data race in repr of threading.RLock in free-threading build.

  • gh-153293: Fix the live sampling profiler TUI keeping stale aggregated opcode statistics after a stats reset.

  • gh-143990: A tkinter.font.Font created from a named font, including by copy(), now copies its configured options rather than the options resolved by Tcl’s font actual, preserving a size specified in pixels (a negative size).

  • gh-148286: Fix undefined behavior in compression.zstd.ZstdDecompressor.unused_data when a complete frame was decompressed in a single call.

  • gh-153210: Fix crash on array import under a memory pressure.

  • gh-153256: Added the tk_print() method to tkinter.Canvas and tkinter.Text which prints the contents of the widget using the native print dialog. It requires Tk 8.7/9.0 or newer.

  • gh-153259: Added the tkinter.systray module which provides the SysTrayIcon class as an interface to the system tray icon and the notify() function which sends a desktop notification. They require Tk 8.7/9.0 or newer.

  • gh-72880: Added the tkinter.fontchooser module which provides the FontChooser class as an interface to the native font selection dialog.

  • gh-153200: Fix math.isqrt() returning an incorrect result for arguments not less than 2**64 that are instances of an int subclass with an overridden comparison operator.

  • gh-66788: Add the utf-7-imap codec, implementing the modified UTF-7 encoding used for international IMAP4 mailbox names (RFC 3501, section 5.1.3).

  • gh-89869: Add imaplib.IMAP4.login_plain(), which authenticates using the PLAIN SASL mechanism (RFC 4616). Unlike login(), it supports non-ASCII user names and passwords.

  • gh-98092: Add imaplib.IMAP4.id(), a wrapper for the IMAP ID command (RFC 2971).

  • gh-153133: Fix a socket leak in asyncio.loop.create_connection() when the transport cannot be created.

  • gh-153068: Fix cProfile.Profile.enable() to no longer overwrite errors from sys.monitoring.

  • gh-153062: Fix a crash when concurrently iterating an itertools.tee() iterator on the free-threaded build.

  • gh-153056: Fix string.Template raising a spurious ValueError when the pattern attribute is a compiled regular expression object, which the documentation allows. On the free-threaded build this also occurred as a data race on the first concurrent use.

  • gh-59396: tkinter.scrolledtext.ScrolledText gained a use_ttk parameter to use the themed tkinter.ttk frame and scroll bar instead of the classic tkinter widgets.

  • gh-143921: Narrow the control character check in imaplib commands: only NUL, CR and LF are now rejected. Other control characters are valid in quoted strings and can occur in mailbox names returned by the server, so they are now accepted and sent quoted.

  • gh-153037: Fix ZstdFile raising AttributeError instead of io.UnsupportedOperation when iterating over a file that is not open for reading.

  • gh-135661: Fix html.parser.HTMLParser: an abruptly closed empty comment (<!--> or <!--->) no longer extends up to a later --> in the same feed() call.

  • gh-153009: Fix compilation of curses on platforms that define the stdscr macro. Patch by Bénédikt Tran.

  • gh-152851: Prevent a crash when allocation fails while copying a BLAKE-2s/2b object. Patch by Bénédikt Tran.

  • gh-54930: Error responses of http.server.BaseHTTPRequestHandler to malformed request lines now include a status line and headers instead of being sent in the bare HTTP/0.9 style. Only a valid HTTP/0.9 request (a two-word GET request line) now receives an HTTP/0.9 style response.

  • gh-152997: On platforms providing the C library’s iconv(3) function, the codecs module now exposes every encoding known to iconv for which Python has no built-in codec. Such an encoding can be used by its name (for example "cp1133") or, to force the iconv-based engine even when a built-in codec exists, with an "iconv:" prefix (for example "iconv:latin1").

  • gh-119592: Fix concurrent.futures.ProcessPoolExecutor stranding submitted work forever when a worker process exited upon reaching its max_tasks_per_child limit after shutdown() was called with wait=False: a replacement worker is now spawned and the remaining work executed as documented. If the executor has instead been garbage collected without shutdown() (gh-152967), or a replacement worker cannot be started, the remaining futures now fail with BrokenProcessPool instead of never resolving. A worker exit racing shutdown(wait=False) can also no longer crash the executor management thread.

  • gh-150579: concurrent.futures now uses lazy imports for its executor submodules instead of a module __getattr__ hook.

  • gh-152951: collections.deque prevent rare crash when calling extend under high memory pressure conditions.

  • gh-150880: Normalize non-extended Windows paths before appending the wildcard used by os.listdir() and os.scandir(), making paths with trailing spaces behave consistently with other filesystem APIs.

  • gh-152068: Fixes a bug when a line was split (particularly on macOS Terminal.app) in the middle of a colorized keyword, causing the ANSI Color Reset sequence (ESC0m) to not be properly printed, causing the output to be colored when it shouldn’t

  • gh-152849: Out-of-range float and integer timestamps now raise OverflowError with the same message. Patch by tonghuaroot.

  • gh-152847: Reject a POSIX TZ transition rule with non-digit characters in the day-of-year field in the pure-Python zoneinfo parser. Patch by tonghuaroot.

  • gh-152905: On glibc, locale.nl_langinfo() now decodes the LC_TIME items (such as the month and day names) using the wide locale data, so the result no longer depends on the LC_CTYPE encoding.

  • gh-152586: tempfile._TemporaryFileWrapper has been renamed to the public tempfile.TemporaryFileWrapper. The old private name is kept as a deprecated alias and will be removed in Python 3.21.

  • gh-77508: Add imaplib.IMAP4.move(), a wrapper for the IMAP MOVE command (RFC 6851), analogous to copy().

  • gh-49680: Add the translate_line_endings parameter to imaplib.IMAP4.append(). By default line endings in the message are translated to CRLF, as before; passing False sends the message literal exactly as given, preserving bare CR or LF octets.

  • gh-152718: Fix unbounded memory allocation in the profiling.sampling binary profile reader when a file declares more string or frame entries than it contains.

  • gh-108280: Connecting imaplib to a server that does not send a valid IMAP4 greeting (for example a POP3 server answering on the IMAP port) now raises an error reporting the server’s response instead of imaplib.IMAP4.error: None.

  • gh-151126: Fix a crash caused by failing to set MemoryError on allocation failure when passing ctypes.Structure or ctypes.Union instances by value to ctypes foreign functions.

  • gh-63121: imaplib now refreshes the cached capability list after a successful login() or authenticate(), using the CAPABILITY response sent by the server or, if none was sent, by querying it, so that capabilities that become available only after authentication (such as ENABLE on Gmail) are recognized. Capabilities advertised in the server greeting are now also used, avoiding a redundant CAPABILITY command.

  • gh-88574: imaplib no longer fails when a server sends a spurious blank line after the counted data of a literal, including after a literal that terminates a response (such as a mailbox name returned by LIST). Such blank lines are now skipped without swallowing the following line.

  • gh-152502: Detect the curses mouse interface (getmouse(), has_mouse(), the BUTTON* constants, and others) and the window is_* state-query methods with configure capability probes or library macros instead of gating them on ncurses-specific macros. They are now also available with other curses implementations that provide them, such as NetBSD curses and PDCurses (the latter underpins windows-curses).

  • gh-151842: Fix a crash in _interpreters.capture_exception() when MemoryError happens. Patch by Amrutha Modela.

  • gh-40038: imaplib now again quotes command arguments when necessary, for example mailbox names containing a space. Such quoting was inadvertently disabled when the module was ported to Python 3, and the arguments are now quoted according to the RFC 3501 grammar. For backward compatibility, an argument already enclosed in double quotes is left unchanged, so code that quotes arguments itself keeps working.

  • gh-50966: Fix unbounded recursion in turtle when a mouse event handler that moves the turtle is reentered while the screen is being redrawn, for example with screen.ondrag(turtle.goto). This could previously crash the interpreter.

  • gh-152638: Deprecate tkinter.filedialog.askopenfiles(). Opening several files at once is error-prone and the returned list cannot be used in a with statement; iterate over the names returned by tkinter.filedialog.askopenfilenames() and open them one by one instead.

  • gh-152587: In tkinter, the name parameter of the wait_variable(), setvar() and getvar() methods and the value parameter of setvar() are now required. Their former default values ('PY_VAR' and '1') were not meaningful.

  • gh-152569: Fix asyncio.wait() leaking waiting tasks via the await-graph when racing a future that never resolves. The waiting task is now discarded from every future’s awaited_by set once wait() returns, even for pending futures.

  • gh-110357: Importing hashlib no longer logs an error to stderr when a normally guaranteed hash algorithm is unavailable in the current runtime (for example under an OpenSSL FIPS configuration or a build using --without-builtin-hashlib-hashes). Code that actually uses the missing algorithm still gets a clear ValueError.

  • gh-152503: Fix curses.window.in_wch(), curses.window.in_wchstr() and curses.window.getbkgrnd() returning garbage text when curses is built against a curses library that does not NUL-terminate the cchar_t text array (such as NetBSD curses).

  • gh-152356: Fix a hang in profiling.sampling run --blocking on Windows when the target process exits. The profiler now finalizes binary profiles instead of continuing to sample the exited process.

  • gh-152470: The wide-character curses functions and methods curses.window.get_wch(), curses.window.get_wstr(), curses.unget_wch(), curses.erasewchar(), curses.killwchar() and curses.wunctrl() now also work when Python is not built against a wide-character-aware curses library, on an 8-bit locale, where each character is a single byte in the relevant encoding. curses.ungetch() now also accepts a one-character string, like curses.unget_wch(); on a wide-character build it can be any character (previously a multibyte character raised OverflowError).

  • gh-78335: Update the docstrings of tkinter and tkinter.ttk widget classes to list all supported widget options, including options added in Tk 9.0 and 9.1. tkinter.Menubutton and tkinter.Message previously had no option list at all.

  • gh-152431: Fix asyncio.StreamWriter.start_tls() to keep the linked StreamReader transport in sync with the upgraded transport.

  • gh-103878: The tkinter.filedialog functions that return a filename (askopenfilename(), asksaveasfilename() and askdirectory()) now consistently return an empty string when the dialog is cancelled, instead of an empty tuple or b'' on some platforms. askopenfilenames() likewise always returns an empty tuple, and askopenfiles() an empty list.

  • gh-151126: Fix two crashes in tkinter and socket modules initialization under a memory pressure. Sets missing MemoryError.

  • gh-133031: curses.textpad.Textbox now supports entering and reading back the full Unicode range, including combining characters, when curses is built with wide-character support.

  • gh-133031: curses.textpad.Textbox now enters and reads back the