From 4a68220ed2f431a25c8fb5897dfe1b9595fd3102 Mon Sep 17 00:00:00 2001 From: John Zhou Date: Thu, 10 Jul 2025 19:10:57 -0500 Subject: [PATCH 1/4] Remove references to event loop policies. --- qasync/__init__.py | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/qasync/__init__.py b/qasync/__init__.py index 3363e97..ef8535e 100644 --- a/qasync/__init__.py +++ b/qasync/__init__.py @@ -1,6 +1,13 @@ """ Implementation of the PEP 3156 Event-Loop with Qt. +This package is originally at https://github.com/CabbageDevelopment/qasync, +licensed under the BSD license; +It is modified since the original was unmaintained for two years. References +to Event Loop Policies was removed, since it's scheduled to be deprecated in +Python 3.16. + +Copyright (c) 2025 Xinyuan Zhou Copyright (c) 2018 Gerard Marull-Paretas Copyright (c) 2014 Mark Harviston Copyright (c) 2014 Arve Knudsen @@ -13,6 +20,7 @@ "Gerard Marull-Paretas , " "Mark Harviston , " "Arve Knudsen ", + "Xinyuan Zhou ", ) __all__ = ["QEventLoop", "QThreadExecutor", "asyncSlot", "asyncClose"] @@ -812,29 +820,23 @@ def wrapper(*args, **kwargs): return outer_decorator - -class QEventLoopPolicyMixin: - def new_event_loop(self): - return QEventLoop(QApplication.instance() or QApplication(sys.argv)) - - -class DefaultQEventLoopPolicy( - QEventLoopPolicyMixin, - asyncio.DefaultEventLoopPolicy, -): - pass - - @contextlib.contextmanager -def _set_event_loop_policy(policy): - old_policy = asyncio.get_event_loop_policy() - asyncio.set_event_loop_policy(policy) +def _use_qeventloop(): + app = QApplication.instance() or QApplication([]) + loop = QEventLoop(app) + old_loop = asyncio.get_event_loop() + asyncio.set_event_loop(loop) try: - yield + yield loop finally: - asyncio.set_event_loop_policy(old_policy) + loop.close() + asyncio.set_event_loop(old_loop) + +def run(main, *args, **kwargs): + """ + Run the given coroutine using a QEventLoop without setting a global policy. + """ + with _use_qeventloop() as loop: + return loop.run_until_complete(main(*args, **kwargs)) -def run(*args, **kwargs): - with _set_event_loop_policy(DefaultQEventLoopPolicy()): - return asyncio.run(*args, **kwargs) From 529b9a7575a03e377dfd6566147fdb4fd8952631 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 13 Jul 2025 22:27:15 -0500 Subject: [PATCH 2/4] Apply suggestions from code review --- qasync/__init__.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/qasync/__init__.py b/qasync/__init__.py index ef8535e..bae6c07 100644 --- a/qasync/__init__.py +++ b/qasync/__init__.py @@ -1,13 +1,6 @@ """ Implementation of the PEP 3156 Event-Loop with Qt. -This package is originally at https://github.com/CabbageDevelopment/qasync, -licensed under the BSD license; -It is modified since the original was unmaintained for two years. References -to Event Loop Policies was removed, since it's scheduled to be deprecated in -Python 3.16. - -Copyright (c) 2025 Xinyuan Zhou Copyright (c) 2018 Gerard Marull-Paretas Copyright (c) 2014 Mark Harviston Copyright (c) 2014 Arve Knudsen @@ -20,7 +13,6 @@ "Gerard Marull-Paretas , " "Mark Harviston , " "Arve Knudsen ", - "Xinyuan Zhou ", ) __all__ = ["QEventLoop", "QThreadExecutor", "asyncSlot", "asyncClose"] From 79911bce379ec2b123f9e5563ef1a238a1716b9a Mon Sep 17 00:00:00 2001 From: John Date: Mon, 14 Jul 2025 10:23:25 -0500 Subject: [PATCH 3/4] Update __init__.py --- qasync/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qasync/__init__.py b/qasync/__init__.py index bae6c07..a904b78 100644 --- a/qasync/__init__.py +++ b/qasync/__init__.py @@ -814,7 +814,7 @@ def wrapper(*args, **kwargs): @contextlib.contextmanager def _use_qeventloop(): - app = QApplication.instance() or QApplication([]) + app = QApplication.instance() or QApplication([sys.argv]) loop = QEventLoop(app) old_loop = asyncio.get_event_loop() asyncio.set_event_loop(loop) @@ -825,10 +825,10 @@ def _use_qeventloop(): asyncio.set_event_loop(old_loop) -def run(main, *args, **kwargs): +def run(future): """ - Run the given coroutine using a QEventLoop without setting a global policy. + Run the given coroutine using a QEventLoop. """ with _use_qeventloop() as loop: - return loop.run_until_complete(main(*args, **kwargs)) + return loop.run_until_complete(future) From 5a58db2c495697f7731e5a0b9db39b4e6ebb5b40 Mon Sep 17 00:00:00 2001 From: John Zhou Date: Mon, 14 Jul 2025 13:50:49 -0500 Subject: [PATCH 4/4] fix remaining issues --- qasync/__init__.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/qasync/__init__.py b/qasync/__init__.py index a904b78..4a270d9 100644 --- a/qasync/__init__.py +++ b/qasync/__init__.py @@ -813,9 +813,12 @@ def wrapper(*args, **kwargs): return outer_decorator @contextlib.contextmanager -def _use_qeventloop(): +def _use_qeventloop(loop_factory): app = QApplication.instance() or QApplication([sys.argv]) - loop = QEventLoop(app) + if loop_factory is None: + loop = QEventLoop(app) + else: + loop = loop_factory(app) old_loop = asyncio.get_event_loop() asyncio.set_event_loop(loop) try: @@ -824,11 +827,12 @@ def _use_qeventloop(): loop.close() asyncio.set_event_loop(old_loop) - -def run(future): +# A run function matching the signature of asyncio.run +def run(main_coro, *, debug=None, loop_factory=None): """ Run the given coroutine using a QEventLoop. """ - with _use_qeventloop() as loop: - return loop.run_until_complete(future) - + with _use_qeventloop(loop_factory) as loop: + if debug is not None: + loop.set_debug(debug) + return loop.run_until_complete(main_coro)