Compute probe coordinates from each widget's own realized geometry
instead of hardcoding pixels such as (5, 5) or width - 5, which land on
a different element, or miss it entirely, at a high display scaling.
(cherry picked from commit 87411d0742f070b1424c08b41cf3af49d377b215)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[3.14] gh-153631: Move to `macos-26` runner for iOS (GH-153632) (#153674)
Switches iOS CI to use the macos-26 runner, and makes a small change to the iOS
build script to improve build stability. xcodebuild doesn't guarantee that the
CoreSimulatorService is running before starting a simulator. If the service
isn't running, xcodebuild reports that no simulators are available, and fails to
start the test app. However, simctl blocks until the simulator is available, and
simctl is used to evaluate the default simulator. So - the iOS build script now
unconditionally determines the default simulator, even if a specific simulator
is requested.
(cherry picked from commit 2dc1a91af801ea896e21f6c6e6cc41f57e8268d9)
[3.14] gh-153037: Make ZstdFile.__next__ raise io.UnsupportedOperation on non-readable files (GH-153045) (#153639)
gh-153037: Make ZstdFile.__next__ raise io.UnsupportedOperation on non-readable files (GH-153045)
Make `ZstdFile.__next__` raise `io.UnsupportedOperation` on non-readable files, consistent with other compression modules.
(cherry picked from commit ed716551e13d1e46a5cd17955657d64b8824626a)
[3.14] gh-90431: Document cancellation behavior of asyncio.wait() and asyncio.as_completed() (GH-153616) (#153618)
gh-90431: Document cancellation behavior of asyncio.wait() and asyncio.as_completed() (GH-153616)
(cherry picked from commit dd2faeb33d5fa0d2635b91ece6eaebd34c61408c)
[3.14] gh-152614: Add raises to `QueueShutDown` in `asyncio.Queue.put_no_wait` and `asyncio.Queue.get_nowait` documentation methods (GH-152681) (#153566)
gh-152614: Add raises to `QueueShutDown` in `asyncio.Queue.put_no_wait` and `asyncio.Queue.get_nowait` documentation methods (GH-152681)
(cherry picked from commit d1a5b54abaca2b443c7642ef3a7be8e1cd077ae3)
[3.14] gh-86726: Fix and improve tkinter documentation and docstrings (GH-153549) (GH-153552)
Correct inaccurate return-type and option descriptions in the tkinter
reference, and add missing module and class docstrings.
(cherry picked from commit 77cb7560c07feed0d5b144c0c1735e1620c96f51)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
[3.14] gh-126877: Fix the configure check for Tcl/Tk with optimizing compilers (GH-153543) (GH-153554)
The check assigned the addresses of Tcl_Init() and Tk_Init() to unused
variables, which optimizing compilers can eliminate, so it linked even
when the libraries were missing. Call the functions instead.
(cherry picked from commit ff0a9ae269fa38c21f01bdea1a7ff5d439c4f681)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Victor Stinner [Sat, 11 Jul 2026 09:47:03 +0000 (11:47 +0200)]
[3.14] gh-152785: Upgrade Ubuntu from 24.04 to 26.04 in GitHub Actions (#152717) (#153416) (#153526)
* [3.15] gh-152785: Upgrade Ubuntu from 24.04 to 26.04 in GitHub Actions (#152717) (#153416)
gh-152785: Upgrade Ubuntu from 24.04 to 26.04 in GitHub Actions (#152717)
* Replace "ubuntu-24.04" with "ubuntu-26.04" on most jobs.
* Replace "ubuntu-latest" with "ubuntu-26.04" for Cross build Linux.
* Replace "ubuntu-latest" with "ubuntu-slim" for small workloads.
* Update ".github/actionlint.yaml" to allow "ubuntu-26.04"
and "ubuntu-26.04-arm" images.
Backport changes:
* Keep Ubuntu 24.04 and llvm.sh to install LLVM 19 and LLVM 20.
* WASI uses ubuntu-26.04, not ubuntu-26.04-arm.
- selectmode: new 'single' and 'multiple' modes
- set(): includes the tree column '#0'
- insert()/selection(): item ids keep the passed value's type
- heading_callback: avoid a double click on the second click
- theme_create_image: don't assert the exact (now scaled) width
(cherry picked from commit d6855c8ad00ffa2bee318b510d0e90573dddbbab)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Neil Schemenauer [Fri, 10 Jul 2026 16:47:33 +0000 (09:47 -0700)]
[3.14] gh-153062: Fix a crash iterating itertools.tee on the free-threaded build (gh-153063) (gh-153476)
itertools.tee branches share a linked list of teedataobject cells. On the free-threaded build, iterating one branch from multiple threads, or iterating sibling branches concurrently, raced on the shared cells and each branch's position, corrupting refcounts and crashing.
Lock each teedataobject while reading, extending, or clearing it, and snapshot each branch's position under the tee object's own lock, revalidating before advancing, so the two locks are never nested. Concurrent iteration of one tee is undefined and may raise RuntimeError as documented, but no longer crashes.
The free-threading snapshot and revalidation add per-element overhead on the default build, where the GIL already serializes access. Guard that path under Py_GIL_DISABLED so the default build keeps the original iteration and the free-threaded path is unchanged.
[3.14] gh-143750: Compile OpenSSL with TSan for TSan CI (#153316) (#153355)
Compile OpenSSL with TSan in the TSan CI job so that data races between
Python code and OpenSSL internals are visible to the sanitizer.
Also skip test_ssl_in_multiple_threads under TSan: concurrent calls to
SSLContext.load_cert_chain on the same context race on the SSL_CTX
default password callback. The race is fixed in 3.15+ (GH-143818), but
with TSan-instrumented OpenSSL it is now reported on 3.14.
[3.14] gh-152132: Fix bugs in Py_RunMain() (GH-153461) (GH-153466) (#153467)
[3.15] gh-152132: Fix bugs in Py_RunMain() (GH-153461) (GH-153466)
* Check for signals more often. Previously, a pending exception could
be removed by PyErr_Clear().
* Only call _PyInterpreterState_SetNotRunningMain() if
_PyInterpreterState_SetRunningMain() has been called.
* Convert _PyPathConfig_UpdateGlobal() PyStatus error to an
exception.
(cherry picked from commit cecafebc2e30ab2aac5f046ed5c9fbc75d6bfb51)
Co-authored-by: Victor Stinner <vstinner@python.org>
[3.14] gh-153406: Raise ValueError, not OverflowError, for out-of-range dates in email.utils.parsedate_to_datetime (GH-153407) (#153434)
email.utils.parsedate_to_datetime documented that it raises ValueError for an invalid date, but it leaked OverflowError when the parsed year or timezone offset was too large for the datetime and timedelta constructors, and that OverflowError also escaped the modern header parsing path since DateHeader.parse only caught ValueError. Wrap the datetime and timezone construction so an OverflowError is re-raised as a ValueError with the original chained as the cause, which restores the documented contract and lets the existing header handler record an InvalidDateDefect instead of raising.
(cherry picked from commit 37a26b9b94b147b5d683bfce0ef5a4c2fbc21085)
Victor Stinner [Thu, 9 Jul 2026 19:37:45 +0000 (21:37 +0200)]
[3.14] gh-152132: Fix Py_RunMain() to return an exit code (#153446) (#153455)
gh-152132: Fix Py_RunMain() to return an exit code (#153446)
* Fix Py_RunMain() to return an exit code, rather than calling
Py_Exit(), when running a script, a command, or the REPL.
* _PyRun_SimpleFile() now logs errors to stderr, for example if setting
__main__.__file__ fails.
* Add tests on Py_RunMain() exitcode.
* Rename functions:
* Change _PyRun_SimpleString(), _PyRun_SimpleFile(), _PyRun_AnyFile() and
_PyRun_InteractiveLoop() return type to PyObject*.
* pymain_repl() now displays the error if PySys_Audit() or
import _pyrepl failed.
* PyRun_SimpleFileExFlags() and PyRun_AnyFileExFlags() now log
PyUnicode_DecodeFSDefault() error. So these functions can no longer
return -1 with an exception set.
[3.14] gh-153422: Assert bool return type in tkinter tests (GH-153429) (GH-153439) (GH-153442)
The tests for PhotoImage.transparency_get(), Text.debug() and
Treeview.exists() now assert the exact bool type, and the documentation
and docstrings use "true"/"false" instead of "1"/"0".
(cherry picked from commit 1604c80008d72b4c9a5bd789900ecf9aff402c1e)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
[3.14] gh-153417: Fix BytesWarning in imaplib error messages for bytes arguments (GH-153423) (GH-153431)
IMAP4.select() and IMAP4.uid() formatted the mailbox and command argument
with %s in their error messages, which raised BytesWarning under -bb when the
argument was bytes and masked the real error. Use %r instead, which is safe
for bytes and also quotes the value.
(cherry picked from commit 11f1b70f4c981b781aaa94427dc1fceb637b2187)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
[3.14] gh-152132: Test all PyRun functions in test_capi.test_run (GH-153352) (#153412)
gh-152132: Test all PyRun functions in test_capi.test_run (GH-153352)
PyRun_InteractiveOneObjectEx() now raises TypeError if the second
parameter type is not str.
(cherry picked from commit cd9994e2831ea743e5423c1db56ca2ca42154e0a)
Co-authored-by: Victor Stinner <vstinner@python.org>
identify(5, 5) could run before the notebook reached its requested size,
so the pixel fell outside the first tab and returned ''. Guard it with a
new opt-in wait_until_mapped(full_size=True).
(cherry picked from commit 53b04980284b668c27fc6d5adb0de19d38efe95b)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
[3.14] gh-47005: fix do_open() to let regular headers override unredirected … (GH-146506) (#153378)
gh-47005: fix do_open() to let regular headers override unredirected … (GH-146506)
AbstractHTTPHandler.do_open() was building the request header dict by
starting with unredirected_hdrs and only inserting regular headers that
were not already present, giving unredirected headers priority. This
contradicts get_header() and header_items(), both of which give regular
headers the higher priority.
Fix by unconditionally updating with req.headers so that a header set
via add_header() always overrides one set via add_unredirected_header().
[3.14] gh-153056: Fix a data race compiling the string.Template pattern in free-threading builds (GH-153057) (#153303)
gh-153056: Fix a data race compiling the string.Template pattern in free-threading builds (GH-153057)
* gh-153056: Fix a data race compiling the string.Template pattern in free-threading builds
Template compiles its substitution pattern lazily and caches it on the class. On the free-threaded build two concurrent first uses could race: a thread that observed the pattern another thread had just compiled would try to recompile it, and re.compile() rejects flags on an already-compiled pattern, raising a spurious ValueError. Return the already-compiled pattern instead.
As a side effect, a subclass that supplies an already-compiled pattern now works too; previously it raised the same ValueError at class definition.
* Trim test comments and NEWS wording
* Document that the pattern attribute accepts a string or a compiled regex
* Comment the three states of pattern and note the documented-behavior fix in NEWS
[3.14] gh-150191: temporarily skip two openssl tests which have internal data races under TSAN (GH-153320) (#153349)
gh-150191: temporarily skip two openssl tests which have internal data races under TSAN (GH-153320)
(cherry picked from commit c11af48fddb1fd5b38e2f026c333e8487f3bcc53)
[3.14] gh-143990: Preserve the size when creating a Font from a named font (GH-153267) (GH-153323) (GH-153341)
tkinter.font.Font now copies the options of a named font (via "font
configure") instead of the options resolved by "font actual", which
would resolve a size specified in pixels (a negative size) to points.
A font description is still resolved, as it cannot be parsed otherwise.
Font.copy(), which has always been equivalent to constructing a Font
from the original font, is updated to match and now preserves the size
too.
[3.14] gh-88574: Do not swallow the line after a terminating literal in imaplib (GH-153317) (GH-153325)
GH-152751 skipped a spurious blank line after a literal unconditionally,
corrupting a response that ends with a literal (such as a mailbox name
returned by LIST): its empty trailer was mistaken for the blank and the
following line was swallowed.
The blank is now skipped only inside an unclosed parenthesis. After a
literal that ends the response it instead arrives before the next
response and is skipped there.
(cherry picked from commit 6b81784f57c6e7ddef61c8db26bb896b3633dcae)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
[3.14] gh-86017: Document displayof for Font.actual() and clarify Font.copy() (GH-153288) (GH-153330)
Explain the displayof argument of tkinter.font.Font.actual() and describe
what Font.copy() returns, including for a wrapped font description.
(cherry picked from commit fa5eafd19c3d395b4498e21b4e1b8faac2ebdb0a)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
[3.14] gh-143921: Reject NUL, CR and LF in IMAP commands (GH-143922, GH-153067) (GH-153137)
Combined backport of GH-143922, which rejected all control characters,
and GH-153067, which narrowed the check to NUL, CR and LF. Other
control characters are valid in quoted strings and are sent quoted.
[3.14] gh-83274: Don't crash when a Tcl interpreter is deallocated in the wrong thread (GH-152323) (GH-153277)
Deallocating the interpreter from a thread other than the one it was created
in ran Tcl_DeleteInterp() there, which makes Tcl abort the process
("Tcl_AsyncDelete: async handler deleted by the wrong thread").
Tkapp_Dealloc() now leaks the interpreter in that case and reports a
RuntimeWarning instead.
Co-authored-by: An Long <aisk@users.noreply.github.com> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: sobolevn <mail@sobolevn.me>
[3.14] gh-153200: Fix math.isqrt() for int subclasses with overridden comparison operators (GH-153203) (GH-153225)
The final check-and-correct comparison in the arbitrary precision path
could call a comparison operator overridden in an int subclass.
Compare by value with int's tp_richcompare.
[3.14] gh-152682: Fix NULL dereference on OOM in `symtable_visit_type_param_bound_or_default` (GH-152684) (#152696)
In `symtable_visit_type_param_bound_or_default()`, when a reserved name
(e.g. `__classdict__`) is used as a type parameter, `PyUnicode_FromFormat()`
is called to build the SyntaxError message. If the allocation fails and
returns NULL, the subsequent `PyErr_SetObject()` and `Py_DECREF()` calls
would dereference NULL, causing a segfault.
Fix by returning 0 immediately when `PyUnicode_FromFormat()` returns NULL.
This propagates the MemoryError set by `PyUnicode_FromFormat()`.
[3.14] gh-153141: Fix mutable default argument in _SharedMemoryTracker.__init__ (GH-153142) (#153146)
gh-153141: Fix mutable default argument in _SharedMemoryTracker.__init__ (GH-153142)
Fix default argument for segment_names in _SharedMemoryTracker constructor to not use a mutable list.
(cherry picked from commit d733b104d53e96584a6881d2772df65ad82573a0)
[3.14] gh-79638: Restore "Treat an unreachable robots.txt as disallow all" (GH-152525) (GH-153108)
This change was accidentally reverted by f0daba1652c (gh-106693,
GH-149514), which only intended to revert the ob_sval change.
The tests were already restored by GH-149569.
(cherry picked from commit 70100b9ea0b43a95226eee45652a5735bb91e9c7)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[3.14] gh-69134: Wait until mapped in SimpleDialog keyboard tests (GH-152690) (GH-153105)
The SimpleDialog keyboard tests generate key events after focus_force(),
which on Windows are dropped until the toplevel is mapped, so they could
fail intermittently (seen on the Windows10 buildbot as
test_return_no_default). Wait until the window is mapped in these tests,
as GH-152599 did for the other keyboard tests.
[3.14] gh-76607: Improve documentation of the tkinter cursor option (GH-152481) (GH-153111)
Link to the cursors(3tk) manual page for the available cursor names and
note that they are platform-dependent.
(cherry picked from commit ea5703735f2ff4ba7bc3b0c7e746a44cb9b25081)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Tk geometry strings can contain a negative offset (e.g. 200x100+-9+-8)
when a window edge is positioned beyond the corresponding screen edge.
Note this in the geometry() and winfo_geometry() documentation.
(cherry picked from commit 19b5e8e1f510eb2fdd3f6261006b61f8cf441101)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
[3.14] gh-54930: Send a status line in error responses to malformed request lines (GH-152980) (GH-153093)
Previously such error responses were sent in the bare HTTP/0.9 style,
without a status line and headers.
(cherry picked from commit 2ab620b41af57e24c11c131bec02f682561ecfaa)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
A Tk variable wrapper unsets its Tcl variable when garbage collected, so a
reference must be kept while a widget uses it. Otherwise Tk recreates the Tcl
variable but never unsets it again, leaking it.
(cherry picked from commit 820b6ca22d72482e2e68dd738cc370535c83655e)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
[3.14] gh-151819: Clarify the conditional-pattern email example in re docs (GH-153072) (GH-153074)
The example pattern does not fail to match '<user@host.com' outright --
re.search finds 'user@host.com' in it; it only fails to match the
whole string. Reword to say so.
(cherry picked from commit fe9c7213e6576e27ebff6ef039706cd463593310)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
[3.14] gh-40038: Quote imaplib command arguments when necessary (GH-152703) (GH-153069)
Argument quoting was inadvertently disabled when imaplib was ported to
Python 3 (bpo-1210 commented out the ``_checkquote()`` call, bpo-9638
then removed it), so since Python 3.0 commands failed for arguments
containing protocol-sensitive characters, such as a space in a mailbox
name.
Quoting is restored and reimplemented per the RFC 3501 grammar, so that
arguments that need quoting are escaped and quoted, while flags, sequence
sets and list wildcards are left intact.
For backward compatibility, an argument already enclosed in double quotes
is left unchanged, so code that quotes arguments itself keeps working.
(cherry picked from commit 600e86490fddf4732e8b993058ca011cc6387464)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[3.14] gh-153030: Fix quadratic complexity in incremental parsing in HTMLParser (GH-153031) (GH-153039)
When an unterminated construct (e.g. a tag or comment) spanned many
feed() calls, rescanning the growing buffer and concatenating new data
onto it were both quadratic. New data is now accumulated in a list and
only joined and parsed once enough has piled up.
(cherry picked from commit bcf98ddbc40ec9b3ee87da0124a5660b19b7e606)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Harjoth Khara <harjoth.khara@gmail.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Stan Ulbrych <stan@python.org>
[3.14] gh-135661: Fix abrupt closing of empty comment in HTMLParser (GH-153007) (GH-153025)
An abruptly closed empty comment ("<!-->" or "<!--->") no longer extends
up to a later "-->" in the same feed() call.
test_htmlparser now also feeds each string source as a single chunk, in
addition to one character at a time, to exercise different input buffering.
(cherry picked from commit ed370d3337c1ac4f7295b444a4807c0b72287608)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>