GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-159449 - Fix asyncio task unregister race 3.14 by jblespiau · Pull Request #159450 · python/cpython

Conversation

@jblespiau

@jblespiau jblespiau commented Oct 15, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

See #159449

When a thread exits with pending asyncio Tasks, PyThreadState_Clear() moves them onto the shared interp->asyncio_tasks_head list, but each Task still records the _Py_ThreadId() of the thread that created it. unregister_task() skips the stop-the-world pause whenever that id matches the current thread. That also happens for a later thread that reuses the exited thread's pthread_t, and for destructors that run later in PyThreadState_Clear(). The resulting unlocked llist_remove() calls on the shared list race with each other and can leave an already-removed node (next == NULL) linked into it. asyncio.all_tasks(), which asyncio.run() calls on shutdown, then crashes with SIGSEGV in _asyncio_all_tasks(). Record the unique id (PyThreadState.id) of the creating thread state instead, and only take the lock-free path while that thread state is not being cleared. Also drop the assertion in add_tasks_llist() that every linked Task is pending. A Task's state is set before unregister_task() unlinks it, and that removal can be waiting for the stop-the-world pause during which the list is walked. add_one_task() already filters out Tasks that are done.

I don't know if the bug is also present in 3.15, it's worth checking. I am hoping that given we have a reprocuder in the bug, + a bug-fix, it should be doable for the maintainers to port it.

  • Issue: AsyncIO thread-safety issue in Python 3.14's free-threading #159449

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
serhiy-storchaka and others added 30 commits September 3, 2026 00:09
@serhiy-storchaka
[3.14] pythongh-156821: Fix inaccuracies in the xml.parsers.expat doc…
3b57bf8
…umentation (pythonGH-156822) (pythonGH-156853)

Corrected, in the documentation and in the docstrings:

* GetInputContext() returns bytes, and its result extends to the end of the
  buffered input;
* Parse() accepts a bytes-like object as well as a string, and ignores the
  encoding declaration for a string;
* ParseFile() only supports binary files;
* XML_ERROR_XML_DECL was described as XML_ERROR_NO_ELEMENTS;
* UnparsedEntityDeclHandler is not restricted to Expat 1.2;
* GetSpecifiedAttributeCount() needs ordered_attributes.

Documented the intern parameter and attribute, namespace_prefixes,
SkippedEntityHandler, XML_CTYPE_MIXED and XML_CTYPE_NAME, and EXPAT_VERSION,
version_info and features.

Removed obsolete notes about Expat 1.2 and 1.95.0, and :noindex: from the
content model constants, which are not documented elsewhere; completed the
list of attribute types in AttlistDeclHandler.
(cherry picked from commit d16a691)
@miss-islington @serhiy-storchaka
[3.14] pythongh-156797: Escape the namespace URI in xml.sax.saxutils.…
54717b6
…XMLGenerator (pythonGH-156799) (pythonGH-156857)

The namespace declarations were the only attribute values written without
quoteattr(), so a URI containing "&", "<" or a quote character produced a
document which cannot be parsed.
(cherry picked from commit 5056ac5)

Co-authored-by: Serhiy Storchaka <[email protected]>
@serhiy-storchaka
[3.14] pythongh-156347: Fix wrong statements in the curses documentat…
a3084ff
…ion (pythonGH-156354) (pythonGH-156873)

window.encoding does not encode the string arguments on a build with
wide-character support: the curses library converts the characters itself.

In the HOWTO: getch() returns -1, not curses.ERR, when there is no input,
and half-delay mode does the same as no-delay mode.  getkey() returns the
key name only for a special key.  leaveok() is not a synonym for curs_set().
getstr() returns a bytes object, interprets the erase and kill characters,
and limits bytes.  The ACS_* constants are not all larger than 255.
Also document get_wch() before getch(), and read whole characters in the
example.

(cherry picked from commit 161054c)
@miss-islington @serhiy-storchaka
[3.14] pythongh-128805: Clarify the deprecation notice of xml.etree.c…
e68849f
…ElementTree (pythonGH-156779) (pythonGH-156884)

It was read as deprecating xml.etree.ElementTree itself, because the page
does not mention cElementTree anywhere else.
(cherry picked from commit 50ed1ec)

Co-authored-by: Serhiy Storchaka <[email protected]>
@miss-islington @encukou
[3.14] Reword atexit docs (pythonGH-156086) (pythonGH-156879)
80f9604
For the `atexit` module:

- Move common info from `register` to the module level (a lot of this
  was duplicated -- less maintainable and harder to read)
- Use *interpreter shutdown* consistently, introducing it as a more
  general term for the old docs' *program termination*.
- Use the term *exit handler* consistently
- Move warning for a mitigated footgun to a change entry
- Add a new warning about keeping things usable

Similarly clarify docs for the `atexit` attribute in `weakref`.
(cherry picked from commit 1d28836)

Co-authored-by: Petr Viktorin <[email protected]>
@miss-islington @graingert
[3.14] pythongh-82406: Add 3.10.6 change notes for inspect.is*function (
e3c7518
pythonGH-94987) (python#156881)

Document when these functions started checking code flags for "duck-typed" function-like objects.
(cherry picked from commit 1059e80)

Co-authored-by: Thomas Grainger <[email protected]>
@miss-islington @encukou @tonghuaroot
[3.14] pythongh-156002: Bound zipfile decompression for bzip2/LZMA/Zs…
31980e8
…tandard (pythonGH-156003) (pythonGH-156362) (pythonGH-156737)

[3.15] pythongh-156002: Bound zipfile decompression for bzip2/LZMA/Zstandard (pythonGH-156003) (pythonGH-156362)

Patch by @tonghuaroot.

zipfile.ZipExtFile._read1() bounds the output of each decompress() call
for DEFLATE members by passing a max_length to zlib, but for bzip2, LZMA,
and Zstandard members it called decompress() with no bound. A whole
compressed chunk was therefore expanded into a single allocation before
the data[:self._left] clip ran, so a consumer that deliberately reads in
small chunks to limit memory (for example zf.open(name).read(8192)) was
silently unprotected for non-DEFLATE members. A small, spec-conformant
archive member declaring a large uncompressed size could drive multi-GB
peak memory.

_read1() now passes a per-call bound to the non-DEFLATE decompress()
(mirroring the DEFLATE branch) and drains the decompressor's internal
buffer across calls by checking needs_input before reading more
compressed input. zipfile's LZMADecompressor wrapper forwards max_length
and exposes needs_input so the bound also holds for LZMA members.

(cherry picked from commit f897dbf)
(cherry picked from commit 1b424c0)

Co-authored-by: Petr Viktorin <[email protected]>
Co-authored-by: tonghuaroot <[email protected]>
@miss-islington @StanFromIreland
@picnixz @eendebakpt @nedbat @dg-pb @hugovk
[3.14] Add a page detailing the time complexity of operations on buil…
958c1b6
…t-in types (pythonGH-154363) (python#156337)

* Add a page detailing the time complexity of operations on built-in types (pythonGH-154363)
(cherry picked from commit c3f7c33)

Co-authored-by: Stan Ulbrych <[email protected]>
Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Pieter Eendebak <[email protected]>
Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: dgpb <[email protected]>

* Remove 3.15-only frozendict mentions

---------

Co-authored-by: Stan Ulbrych <[email protected]>
Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Pieter Eendebak <[email protected]>
Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: dgpb <[email protected]>
Co-authored-by: Hugo van Kemenade <[email protected]>
@miss-islington @serhiy-storchaka @claude
[3.14] pythongh-89735: Document requirements for the *headers* argume…
a8a1871
…nt (pythonGH-155640) (pythonGH-156899)

Both handlers look up the header name in lowercase, and the basic
one needs get_all(), so a plain dict does not work.
(cherry picked from commit 1414d2a)

Co-authored-by: Serhiy Storchaka <[email protected]>
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
@miss-islington @aisk
[3.14] pythongh-94242: Clarify comments for _MAX_WINDOWS_WORKERS in c…
74c1e1e
…oncurrent.futures.process (pythonGH-135537) (python#156906)

pythongh-94242: Clarify comments for _MAX_WINDOWS_WORKERS in concurrent.futures.process (pythonGH-135537)
(cherry picked from commit c8ea867)

Co-authored-by: An Long <[email protected]>
@miss-islington @johnzhou721
[3.14] pythongh-136061: Simplify idlelib.editor.EditorWindow.load_ext…
92cab34
…ension methodname processing (pythonGH-156912)

(cherry picked from commit 0625799)

Co-authored-by: John <[email protected]>
@miss-islington @sergey-miryanov
[3.14] pythonGH-146096: Fix segfault in BaseExceptionGroup repr (pyth…
1cb0003
…onGH-146141) (pythonGH-156904)

(cherry picked from commit ced6460)

Co-authored-by: Sergey Miryanov <[email protected]>
@encukou @sethmlarson @StanFromIreland
[3.14] pythongh-155292: Don't consider Unicode codepoint attributes o…
1e54caa
…utside RFC 3454 (pythonGH-155293) (pythonGH-156020)

Due to a bug, some Unicode codepoint attributes were considered
for characters not yet defined in Unicode 3.2.0 or attributes
which changed in later Unicode versions. RFC 3454 (StringPrep)
requires using Unicode 3.2.0 strictly.

(cherry picked from commit 7e109d0)
The cherry-pick needed reworking as pythonGH-144815 wasn't backported to 3.14
and below, so unassigned characters don't have bidi values.

Co-authored-by: Seth Larson <[email protected]>
Co-authored-by: Stan Ulbrych <[email protected]>
Co-authored-by: Petr Viktorin <[email protected]>
@serhiy-storchaka @claude
[3.14] pythongh-156894: Fix the position of syntax errors which cover…
113ad29
… a range (pythonGH-156901) (pythonGH-156927)

The callers of _PyTokenizer_syntaxerror_known_range() pass columns in bytes,
but SyntaxError.offset and end_offset are columns in characters.

(cherry picked from commit 59a6913)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
@serhiy-storchaka @terryjreedy
[3.14] pythongh-156896: Stop scrubbing tkinter submodules upon idleli…
eac1dcf
…b.run import (pythonGH-156915) (python#156959)

pythongh-156896: Stop scrubbing tkinter submodules upon idlelib.run import (python#156915)

Instead, invoke the scrubbing within run.main, which is called after
the import when starting the IDLE user process.

To manually test that scrub_tkinter_submodules
is called when proper, start (or restart) Shell, enter
`import tkinter; dir(tkinter), and check that that font,
messagebox, ttk, and the dialog modules are missing.

It is obvious from the code that the function is not otherwise
called.  To test anyway, continue with `import tkinter.ttk;
import idlelib.run; tkinter.ttk` and check for proper output.

(cherry picked from commit e50d233)

Co-authored-by: Terry Jan Reedy <[email protected]>
@miss-islington @graingert
[3.14] pythongh-127057: reschedule proactor datagram read loop after …
9e97d9f
…ConnectionResetError (pythonGH-156726) (python#156977)

pythongh-127057: reschedule proactor datagram read loop after ConnectionResetError  (pythonGH-156726)
(cherry picked from commit 0ea2971)

Co-authored-by: Thomas Grainger <[email protected]>
@miss-islington @IvyXu420 @StanFromIreland
[3.14] pythongh-156970: Set Mock.return_value's docstring (pythonGH…
5532330
…-156971) (python#156982)

(cherry picked from commit e620377)

Co-authored-by: Ivy Xu <[email protected]>
Co-authored-by: Stan Ulbrych <[email protected]>
@miss-islington
[3.14] pythongh-156091: Fix crash compiling deeply nested inlined com…
dd36d01
…prehensions (pythonGH-156957) (python#156993)
@miss-islington @owenthcarey @savannahostrowski
[3.14] pythongh-127296: Document that argparse count action starts fr…
384ac4d
…om a non-zero default (pythonGH-156908) (python#156998)

pythongh-127296: Document that argparse count action starts from a non-zero default (pythonGH-156908)
(cherry picked from commit 7a91841)

Co-authored-by: Owen Carey <[email protected]>
Co-authored-by: Savannah Ostrowski <[email protected]>
@deadlovelll
[3.14] pythongh-156988: Fix asyncio call graph loss at sync generators (
b8ce418
python#157005)
@miss-islington @serhiy-storchaka @claude
[3.14] pythongh-154511: Consolidate IDLE's mouse wheel handling in ut…
a9152fb
…il (pythonGH-156974) (pythonGH-157022)

Move wheel_event there from idlelib.tree and add x11_buttons(widget) and
bind_wheel(widget, func), used by the editor, the tree and test_sidebar.
wheel_event now reads the direction from the event, not the platform.

Move its test from test_tree, and test the fix_ functions of util too.
(cherry picked from commit 57594aa)

Co-authored-by: Serhiy Storchaka <[email protected]>
Co-authored-by: Claude Opus 5 <[email protected]>
@serhiy-storchaka
[3.14] pythongh-154357: Fix tkinter, ttk and IDLE tests depending on …
90464d6
…the window manager (pythonGH-154370) (pythonGH-157064)

The window manager can take the focus from the application, ignore
lift() and resize a toplevel on its own.

* Hide the root window in the dialog tests, so that it does not compete
  for the focus.
* Take the focus right before generating a key event.
* Tolerate additional focus events.
* Do not check focus_get() and focus_displayof() without the focus.
* Resize the toplevel to fit its content in wait_until_mapped().

(cherry picked from commit 3b56438)
@miss-islington
[3.14] pythongh-157048: check for buffer errors before mutating in By…
c6af0c4
…tesIO.__init__ (pythonGH-157049) (python#157068)
@miss-islington @vstinner
[3.14] pythongh-156939: Fix struct.pack('0p', bytes) (pythonGH-157071) (
3a27a35
python#157130)

pythongh-156939: Fix struct.pack('0p', bytes) (pythonGH-157071)

If the Pascal string is empty (size=0), do not write the size prefix.
Previously, a NUL byte was written outsize the buffer (buffer
overflow). In practice, the write remains into allocated memory
and is silently ignored: no memory is corrupted.
(cherry picked from commit 23525c9)

Co-authored-by: Victor Stinner <[email protected]>
@bhuvi27
[3.14] pythongh-150771: Fix email serialization for shift_jis and euc…
665ceff
…-jp (pythonGH-151120) (python#152952)

Encode the payload with output_charset instead of input_charset.
(cherry picked from commit 0777a58)
@miss-islington @gpshead
[3.14] pythongh-157142: Fix linking _freeze_module with built-in test…
2eb55ca
… modules (pythonGH-157143) (python#157149)

pythongh-157142: Fix linking _freeze_module with built-in test modules (pythonGH-157143)

Programs/_freeze_module is linked with Modules/getpath_noop.o rather than
Modules/getpath.o, and getpath_noop.c only defined _PyConfig_InitPathConfig().
With MODULE_BUILDTYPE=static (the default on wasm), _testinternalcapi.o is
part of LIBRARY_OBJS_OMIT_FROZEN and its get_getpath_codeobject() left
_Py_Get_Getpath_CodeObject() as an undefined reference. Define a stub for it.
(cherry picked from commit c8da735)

Co-authored-by: Gregory P. Smith <[email protected]>
@miss-islington @LindaSummer
[3.14] pythongh-154937: Fix _thread._shutdown() racing with `_threa…
eef282b
…d.start_joinable_thread` on `ThreadHandle.ident` (pythonGH-155085) (python#155124)

pythongh-154937: Fix `_thread._shutdown()` racing with `_thread.start_joinable_thread` on `ThreadHandle.ident` (pythonGH-155085)
(cherry picked from commit a4095ee)

Co-authored-by: Edward Xu <[email protected]>
@miss-islington @dariushoule
[3.14] pythongh-155752: Do not crash when GenericAlias parameters cha…
96964c8
…nge during substitution (pythonGH-155761) (python#155771)

pythongh-155752: Do not crash when GenericAlias parameters change during substitution (pythonGH-155761)

An alias argument can gain __typing_subst__ after __parameters__ has been cached, including during a preparation or substitution callback. Check that the argument is present before indexing the substitution arguments.
(cherry picked from commit c0006fa)

Co-authored-by: Darius Houle <[email protected]>
@miss-islington @iamsharduld
[3.14] pythongh-150922: Fix test_cmd libedit assertion in test_bang_c…
eb382a3
…ompletion_without_do_shell (pythonGH-156623) (python#157156)

pythongh-150922: Fix test_cmd libedit assertion in test_bang_completion_without_do_shell (pythonGH-156623)

GNU readline retypes the full completed word after tab completion, but
libedit redraws only the untyped suffix following a cursor-forward
escape sequence. Assert on the common suffix ('ello') instead of the
literal 'hello' bytes so the test passes on both backends.
(cherry picked from commit 0b4c7da)

Co-authored-by: Shardul Deshpande <[email protected]>
@miss-islington @gpshead
[3.14] pythongh-157159: improve the tabnanny usage message (pythonGH-…
aa41833
…157160) (python#157164)

pythongh-157159: improve the tabnanny usage message (pythonGH-157160)

The usage message embedded sys.argv[0], which under `python -m tabnanny`
is the absolute path of tabnanny.py, and a meaningless virtual path when
the standard library is in a zip archive or embedded in an executable.
Print f"Usage: {sys.executable} -m tabnanny [-v] file_or_directory ..."
instead, and make the test expect that fixed form.
(cherry picked from commit 5ddd59f)

Co-authored-by: Gregory P. Smith <[email protected]>
@jblespiau
jblespiau requested review from a team, Eclips4, Fidget-Spinner, JacobCoffee, ZeroIntensity, brandtbucher, brettcannon, carljm, diegorusso, ericsnowcurrently, freakboy3742, iritkatriel, isidentical, itamaro, markshannon, methane, mhsmith, ncoghlan, savannahostrowski, sethmlarson, webknjaz and willingc as code owners October 15, 2026 08:33
@jblespiau

jblespiau commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

Not done against the correct branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jblespiau jblespiau closed this Oct 15, 2026
@StanFromIreland
StanFromIreland removed request for a team October 15, 2026 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting review

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

20 participants

@jblespiau @serhiy-storchaka @miss-islington @encukou @deadlovelll @bhuvi27 @vstinner @StanFromIreland @lpyu001 @nedbat @zooba @chris-eibl @pablogsal @mhsmith @edvilme @aisk @freakboy3742 @liuzhijie-0614 @zware @kumaraditya303
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.