python / python/cpython

unusual behaviour in asyncio.TaskGroup in the presence of GeneratorExit, StopIteration, KeyboardInterrupt and SystemExit

Offen
#95,571 8 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

3.11 3.12 topic-asyncio type-bug
Vorherrschende Sprache
Python
Sterne
77.2k
Forks
36k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

import gc
import asyncio
import logging

logger = logging.getLogger(__name__)


async def keyboard_interrupt():
    raise KeyboardInterrupt

async def system_exit():
    raise SystemExit

async def task_groups():
    async with asyncio.TaskGroup() as tg:
        tg.create_task(system_exit())
        tg.create_task(keyboard_interrupt())




loop = asyncio.SelectorEventLoop()
task = loop.create_task(task_groups())

while not task.done():
    try:
        loop.run_until_complete(asyncio.sleep(0))
    except (SystemExit, KeyboardInterrupt) as e:
        print(f"{e=}")

print(f"{task=} {task.exception()=}")
loop.close()

print("#######################################################")

async def gen_exit():
    async with asyncio.TaskGroup() as tg:
        await asyncio.get_running_loop().create_future()


loop = asyncio.SelectorEventLoop()
task = loop.create_task(gen_exit())
loop.run_until_complete(asyncio.sleep(0))
del task
gc.collect()

print("#######################################################")

gives the following output on 3.12:

e=SystemExit()
e=KeyboardInterrupt()
e=SystemExit()
task=<Task finished name='Task-1' coro=<task_groups() done, defined at /home/graingert/projects/cpython/demo.py:14> exception=SystemExit()> task.exception()=SystemExit()
#######################################################
Exception ignored in: <coroutine object gen_exit at 0x7fd62350cd60>
Traceback (most recent call last):
  File "/home/graingert/projects/cpython/demo.py", line 37, in gen_exit
    async with asyncio.TaskGroup() as tg:
  File "/home/graingert/projects/cpython/Lib/asyncio/taskgroups.py", line 134, in __aexit__
    raise me from None
BaseExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
Task was destroyed but it is pending!
task: <Task pending name='Task-7' coro=<gen_exit() done, defined at /home/graingert/projects/cpython/demo.py:36> wait_for=<Future pending cb=[Task.task_wakeup()]>>
#######################################################

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Führen Sie zuerst den bereitgestellten Python-3.12-Reproducer aus und untersuchen Sie anschließend Lib/asyncio/taskgroups.py im Bereich von TaskGroup.aexit sowie die Aufrufe zur Erstellung von asyncio-Tasks. Verfolgen Sie die Pfade für GeneratorExit, StopIteration, KeyboardInterrupt und SystemExit und ermitteln Sie das erwartete Verhalten, bevor Sie Testabdeckung hinzufügen; das Issue gibt das gewünschte Ergebnis noch nicht vor.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.