Implement the modified UTF-7 encoding used for international IMAP4
mailbox names (RFC 3501, section 5.1.3). It differs from UTF-7:
"&" is the shift character ("&-" encodes a literal "&"), "," replaces
"/" in the Base64 alphabet, and all non-printable-ASCII characters are
Base64-encoded.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
gh-88574: Do not swallow the line after a terminating literal in imaplib (GH-153317)
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.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
gh-143990: Preserve the size when creating a Font from a named font (GH-153267)
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.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
gh-153056: Fix a data race compiling the string.Template pattern in free-threading builds (#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
gh-143990: Allow tkinter.font.Font to wrap a font description (GH-152025)
With exists=True and no name, Font now wraps the font description as is,
without creating a new named font, so that it is used without loss of
precision by actual(), measure() and metrics(). Its name attribute is then
the description rather than a string. Keyword options now override the
corresponding settings of the given font instead of being ignored.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gh-153200: Fix math.isqrt() for int subclasses with overridden comparison operators (GH-153203)
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.
Victor Stinner [Mon, 6 Jul 2026 15:44:21 +0000 (17:44 +0200)]
gh-152785: Upgrade Ubuntu from 24.04 to 26.04 in GitHub Actions (#152717)
* Replace "ubuntu-24.04" with "ubuntu-26.04".
* 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.
* Install Ubuntu libmpdec-dev package, rather than installing libmpdec
from source (tarball).
* No longer run https://apt.llvm.org/llvm.sh, since ubuntu-26.04 provides
clang-21 by default.
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Add tests for syntax error messages that had no test coverage (GH-153192)
"illegal target for annotation" and "cannot use dict unpacking here"
were not tested at all, and "f-string: expecting '!', or ':', or '}'"
was only tested for its t-string variant.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
gh-153171: Produce specialized syntax errors for 'not' after an operator in more positions (GH-153175)
Move the invalid_factor rule from term to factor and the
invalid_arithmetic rule from shift_expr to sum, so that they are
tried at all positions where the invalid construct can occur.
Previously a generic "invalid syntax" error was reported for
constructs like "1 << 2 + not x" or "1 * + not x".
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
gh-152026: Track mark-saving contexts with a counter (GH-153160)
Replace the state->repeat checks that guard mark saving and restoring
with an explicit save_marks counter maintained where repeat and
possessive contexts are entered and left. Each push is now paired
with a pop decided by the same condition.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Add a wrapper for the IMAP ID command (RFC 2971). It takes a mapping
of field names to values and returns the server identification
information from the untagged ID response.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
gh-143921: Narrow the control character check in imaplib commands (GH-153067)
Only NUL, CR and LF are rejected now. 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.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
gh-43699: Defer the drag cursor in tkinter.dnd until the pointer moves (GH-152371)
The drag cursor is now changed only once the pointer starts moving past
a small threshold rather than on the initial button press, so that a
plain click no longer flashes it.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
gh-59396: Use themed widgets in tkinter.filedialog (GH-152036)
The FileDialog, LoadFileDialog and SaveFileDialog dialogs are now built from
the themed tkinter.ttk widgets by default instead of the classic tkinter
widgets, and gained a use_ttk parameter that selects between the classic Tk
widgets and the themed ttk widgets.
They were also brought closer to the native Tk file dialog: the buttons and
field labels gained Alt key accelerators, the default ring follows the keyboard
focus, the Escape key cancels the dialog, the focus traverses the widgets in
their visual order, and the directory and file lists gained a horizontal
scrollbar and type-ahead selection. The dialog is now transient and centered
over its parent, and the SaveFileDialog overwrite confirmation uses a themed
message box.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gh-79638: Restore "Treat an unreachable robots.txt as disallow all" (GH-152525)
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.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gh-75952: Document negative offsets in tkinter geometry strings (GH-152531)
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.
Co-authored-by: Claude Opus 4.8 <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.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
gh-69134: Wait until mapped in SimpleDialog keyboard tests (GH-152690)
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 each of
these tests, as GH-152599 did for the other keyboard tests.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
gh-151819: Clarify the conditional-pattern email example in re docs (GH-153072)
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.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
gh-40038: Quote imaplib command arguments when necessary (GH-152703)
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.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gh-153030: Fix quadratic complexity in incremental parsing in HTMLParser (GH-153031)
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.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gh-83386: Enable test_hang_gh83386 for ProcessPoolExecutor (GH-152976)
The hang this test guards against (interpreter exit after
shutdown(wait=False) with running futures) was fixed for
ProcessPoolExecutor by the executor management rewrite years ago, but
the test still skipped it citing the issue. The skip also hid a latent
NameError in the subprocess template, which only selects a start method
in the process pool variants; rewrite it to use the same
mp_context=get_context() shape as the sibling templates. Remove a stale
comment claiming ProcessPoolExecutor often hangs with wait=False.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
gh-151644: Fix data race in sys.setdlopenflags/getdlopenflags under free-threading (gh-151768)
In free-threading builds, concurrent calls to sys.getdlopenflags() and
sys.setdlopenflags() race on interp->imports.dlopenflags. Fix by
using FT_ATOMIC_LOAD_INT_RELAXED / FT_ATOMIC_STORE_INT_RELAXED in
_PyImport_GetDLOpenFlags and _PyImport_SetDLOpenFlags, consistent with
how analogous interpreter-state integer fields (lazy_imports_mode,
pystats_enabled) are protected.
Relaxed ordering is correct here: dlopenflags is a standalone config
integer with no ordering relationship to other memory.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Henry Schreiner [Fri, 3 Jul 2026 18:11:16 +0000 (14:11 -0400)]
gh-150579: use lazy imports for concurrent.futures (GH-150585)
This module has a manual lazy import hack using `__getattr__`. Now that lazy imports exist and cannot be disabled, this could use lazy imports instead.
Key differences: this will now show up in sys.lazy_modules when accessed. Error messages should be a bit better without the wrapper `__getattr__` involved. That's the only differences I can think of.
Signed-off-by: Henry Schreiner <henryfs@princeton.edu> Co-authored-by: Gregory P. Smith <greg@krypto.org>
gh-115634: Fix ProcessPoolExecutor deadlock with max_tasks_per_child (GH-140900)
The idle worker semaphore counts task completions, not idle workers, so
it can hold a stale token released by a worker that later exited upon
reaching its max_tasks_per_child limit. The worker replacement path
consumed such tokens and skipped spawning a replacement, deadlocking
the remaining queued tasks once no workers were left.
Replace dead workers based on len(self._processes) without consulting
the semaphore. The submit() path is unchanged, preserving on-demand
spawning and idle worker reuse.
Replace the documentation note added in GH-140897 with a versionchanged
entry now that the bug is fixed.
gh-144067: Document terminal leak when initscr() follows setupterm() (GH-152624)
The curses library keeps a single current terminal: calling initscr()
or newterm() after setupterm() abandons the terminal that setupterm()
allocated without freeing it. This cannot be fixed safely in code
(freeing the terminal would break the capsule API and pending terminfo
queries), so document the behavior, with a cross-reference from
initscr() and newterm().
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
gh-152789: Skip curses tests needing newterm() on ncurses before 6.5 (GH-152880)
ncurses before 6.5 can crash on repeated newterm(). Fall back to initscr()
in TestCurses and skip ScreenTests and SLKTests, which need several screens.
The shared initscr() screen also needs its rendition and background reset
between tests.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>