Skip to content

Commit 3cbeb35

Browse files
authored
Merge pull request #78 from CabbageDevelopment/dev
Merging lastest dev changes to master
2 parents 920b0e3 + 9601d68 commit 3cbeb35

File tree

5 files changed

+53
-9
lines changed

5 files changed

+53
-9
lines changed

.github/workflows/test.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
strategy:
1010
fail-fast: false
1111
matrix:
12-
os: [ubuntu-latest, windows-latest]
12+
os: [ubuntu-20.04, windows-latest]
1313
python: ["3.6", "3.7", "3.8", "3.9"]
1414
qt:
1515
- package: PyQt5
@@ -20,8 +20,10 @@ jobs:
2020
qt_api: "pyside2"
2121
- package: PySide6
2222
qt_api: "pyside6"
23-
# exclude:
24-
# - {os: windows-latest, qt: {package: PySide2}}
23+
exclude:
24+
- os: windows-latest
25+
python: "3.6"
26+
qt: { package: PyQt6, qt_api: "pyqt6" }
2527

2628
steps:
2729
- name: Checkout
@@ -43,13 +45,13 @@ jobs:
4345
pipenv run --python ${{ matrix.python }} pip install ${{ matrix.qt.package }} pytest
4446
4547
- name: Install Libxcb dependencies
46-
if: matrix.os == 'ubuntu-latest'
48+
if: matrix.os == 'ubuntu-20.04'
4749
run: |
4850
sudo apt-get update
4951
sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev
5052
5153
- name: Run headless test
52-
uses: GabrielBB/xvfb-action@v1.6
54+
uses: coactions/setup-xvfb@v1
5355
env:
5456
QT_API: ${{ matrix.qt.qt_api }}
5557
with:

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
repos:
22
# Black formats the Python code.
33
- repo: https://github.com/psf/black
4-
rev: stable
4+
rev: 23.3.0
55
hooks:
66
- id: black
77
language_version: python3

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# qasync
22

3-
[![Maintenance](https://img.shields.io/maintenance/yes/2022)](https://pypi.org/project/qasync)
3+
[![Maintenance](https://img.shields.io/maintenance/yes/2023)](https://pypi.org/project/qasync)
44
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/qasync)](https://pypi.org/project/qasync)
55
[![PyPI - License](https://img.shields.io/pypi/l/qasync)](/LICENSE)
66
[![PyPI](https://img.shields.io/pypi/v/qasync)](https://pypi.org/project/qasync)

qasync/__init__.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import contextlib
2424
import functools
2525
import importlib
26+
import inspect
2627
import itertools
2728
import logging
2829
import os
@@ -373,6 +374,7 @@ def run_forever(self):
373374

374375
try:
375376
self.__log_debug("Starting Qt event loop")
377+
asyncio.events._set_running_loop(self)
376378
rslt = -1
377379
try:
378380
rslt = self.__app.exec_()
@@ -381,6 +383,7 @@ def run_forever(self):
381383
self.__log_debug("Qt event loop ended with result %s", rslt)
382384
return rslt
383385
finally:
386+
asyncio.events._set_running_loop(None)
384387
self._after_run_forever()
385388
self.__is_running = False
386389

@@ -785,8 +788,25 @@ def outer_decorator(fn):
785788
@Slot(*args, **kwargs)
786789
@functools.wraps(fn)
787790
def wrapper(*args, **kwargs):
788-
task = asyncio.ensure_future(fn(*args, **kwargs))
789-
task.add_done_callback(_error_handler)
791+
# Qt ignores trailing args from a signal but python does
792+
# not so inspect the slot signature and if it's not
793+
# callable try removing args until it is.
794+
task = None
795+
while len(args):
796+
try:
797+
inspect.signature(fn).bind(*args, **kwargs)
798+
except TypeError:
799+
if len(args):
800+
# Only convert args to a list if we need to pop()
801+
args = list(args)
802+
args.pop()
803+
continue
804+
else:
805+
task = asyncio.ensure_future(fn(*args, **kwargs))
806+
task.add_done_callback(_error_handler)
807+
break
808+
if task is None:
809+
raise TypeError("asyncSlot was not callable from Signal. Potential signature mismatch.")
790810
return task
791811

792812
return wrapper

tests/test_qeventloop.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,28 @@ def test_loop_not_running(loop):
221221
assert not loop.is_running()
222222

223223

224+
def test_get_running_loop_fails_after_completion(loop):
225+
"""Verify that after loop stops, asyncio._get_running_loop() correctly returns None."""
226+
227+
async def is_running_loop():
228+
nonlocal loop
229+
assert asyncio._get_running_loop() == loop
230+
231+
loop.run_until_complete(is_running_loop())
232+
assert asyncio._get_running_loop() is None
233+
234+
235+
def test_loop_can_run_twice(loop):
236+
"""Verify that loop is correctly reset as asyncio._get_running_loop() when restarted."""
237+
238+
async def is_running_loop():
239+
nonlocal loop
240+
assert asyncio._get_running_loop() == loop
241+
242+
loop.run_until_complete(is_running_loop())
243+
loop.run_until_complete(is_running_loop())
244+
245+
224246
def test_can_function_as_context_manager(application):
225247
"""Verify that a QEventLoop can function as its own context manager."""
226248
with qasync.QEventLoop(application) as loop:

0 commit comments

Comments
 (0)