Open QQ80 opened 1 month ago
Here's a minimal example:
import asyncio
import qasync
from PyQt6.QtWidgets import QApplication, QPushButton
app: QApplication
@qasync.asyncSlot(bool)
async def button_clicked(_checked):
match app.button.text():
case "Wait":
app.button.setText("Cancel wait")
app.waiting_task = asyncio.current_task()
await asyncio.sleep(5)
app.button.setText("Wait")
case "Cancel wait":
app.waiting_task.cancel()
app.button.setText("Wait")
async def main():
global app
app = QApplication.instance()
app_quit_event = asyncio.Event()
app.aboutToQuit.connect(app_quit_event.set)
app.button = QPushButton("Wait")
app.button.clicked.connect(button_clicked)
app.button.show()
await app_quit_event.wait()
qasync.run(main())
The exception is uncaught if "Wait" is pressed, and, while "Cancel wait" is shown, the button is pressed again.
For coroutines decorated with
asyncSlot
, if the enclosing task is cancelled, theasyncio.CancelledError
is left uncaught. This is a problem if another signal triggers the cancelling of that enclosing task, while it isawait
ing for something.I believe the error handler at line 778 of
qasync/__init__.py
should handleasyncio.CancelledError
with something like this:Note that since Python 3.8,
asyncio.CancelledError
is a derived class ofBaseException
but notException
.