| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- # Copyright (C) 2023 The Qt Company Ltd.
- # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
- from __future__ import annotations
- from .events import (
- QAsyncioEventLoopPolicy, QAsyncioEventLoop, QAsyncioHandle, QAsyncioTimerHandle
- )
- from .futures import QAsyncioFuture
- from .tasks import QAsyncioTask
- from typing import Coroutine, Any
- import asyncio
- __all__ = [
- "QAsyncioEventLoopPolicy", "QAsyncioEventLoop",
- "QAsyncioHandle", "QAsyncioTimerHandle",
- "QAsyncioFuture", "QAsyncioTask"
- ]
- def run(coro: Coroutine | None = None,
- keep_running: bool = True, quit_qapp: bool = True, *, handle_sigint: bool = False,
- debug: bool | None = None) -> Any:
- """
- Run the QtAsyncio event loop.
- If there is no instance of a QCoreApplication, QGuiApplication or
- QApplication yet, a new instance of QCoreApplication is created.
- :param coro: The coroutine to run. Optional if keep_running is
- True.
- :param keep_running: If True, QtAsyncio (the asyncio event loop) will
- continue running after the coroutine finished, or
- run "forever" if no coroutine was provided.
- If False, QtAsyncio will stop after the
- coroutine finished. A coroutine must be provided if
- this argument is set to False.
- :param quit_qapp: If True, the QCoreApplication will quit when
- QtAsyncio (the asyncio event loop) stops.
- If False, the QCoreApplication will remain active
- after QtAsyncio stops, and can continue to be used.
- :param handle_sigint: If True, the SIGINT signal will be handled by the
- event loop, causing it to stop.
- :param debug: If True, the event loop will run in debug mode.
- If False, the event loop will run in normal mode.
- If None, the default behavior is used.
- """
- # Event loop policies are expected to be deprecated with Python 3.13, with
- # subsequent removal in Python 3.15. At that point, part of the current
- # logic of the QAsyncioEventLoopPolicy constructor will have to be moved
- # here and/or to a loop factory class (to be provided as an argument to
- # asyncio.run()). In particular, this concerns the logic of setting up the
- # QCoreApplication and the SIGINT handler.
- #
- # More details:
- # https://discuss.python.org/t/removing-the-asyncio-policy-system-asyncio-set-event-loop-policy-in-python-3-15/37553 # noqa: E501
- default_policy = asyncio.get_event_loop_policy()
- asyncio.set_event_loop_policy(
- QAsyncioEventLoopPolicy(quit_qapp=quit_qapp, handle_sigint=handle_sigint))
- ret = None
- exc = None
- if keep_running:
- if coro:
- asyncio.ensure_future(coro)
- asyncio.get_event_loop().run_forever()
- else:
- if coro:
- ret = asyncio.run(coro, debug=debug)
- else:
- exc = RuntimeError(
- "QtAsyncio was set not to keep running after the coroutine "
- "finished, but no coroutine was provided.")
- asyncio.set_event_loop_policy(default_policy)
- if ret:
- return ret
- if exc:
- raise exc
|