Skip to content

Commit

Permalink
Merge pull request #17 from dhomeier/qt65-6-py312-ci
Browse files Browse the repository at this point in the history
Add CI envs for PyQt 6.5-6.7, PySide 6.5-6.7 & Python 3.12; fix Readthedocs and matplotlib 3.9, Qt6 failures
  • Loading branch information
astrofrog authored Aug 16, 2024
2 parents 37dd079 + 92f7247 commit de4f45c
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 30 deletions.
22 changes: 16 additions & 6 deletions .github/workflows/ci_workflows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ jobs:
- linux: py38-test-pyqt514-all
- linux: py39-test-pyqt515
- linux: py310-test-pyqt63-all
- linux: py310-test-pyqt64-all
- linux: py311-test-pyqt64
- linux: py312-test-pyqt65
- linux: py311-test-pyqt66-all
- linux: py311-test-pyqt514
- linux: py311-test-pyqt515-lts-all
Expand All @@ -53,19 +55,22 @@ jobs:
- macos: py311-docs-pyqt64
coverage: false
# Test a few configurations on macOS
# Test a few configurations on macOS 12 (Intel) and 14 (ARM)
- macos: py38-test-pyqt514-all
- macos: py310-test-pyqt515
- macos: py310-test-pyqt64
- macos: py311-test-pyqt515
- macos: py311-test-pyqt66
- macos: py312-test-pyqt67
# Test some configurations on Windows
- windows: py38-test-pyqt514
- windows: py310-test-pyqt63
- windows: py311-test-pyqt65
- windows: py312-test-pyqt66
# Test against latest developer versions of some packages
- linux: py310-test-pyqt515-dev-all
- linux: py311-test-pyqt64-dev
- linux: py312-test-pyqt515-dev
- linux: py312-test-pyqt67-dev-all
allowed_failures:
needs: initial_checks
Expand All @@ -92,13 +97,18 @@ jobs:
# PySide6 6.4 failures due to https://github.com/spyder-ide/qtpy/issues/373
# and https://github.com/matplotlib/matplotlib/issues/24155
# PyQt5 / < 6.6 segfaulting under macOS 14 (on arm64) in TestGlueDataDialog or TestLinkEditor
# Python 3.11.0 failing on Windows in test_image.py on
# > assert df.find_factory(fname) is df.img_data
- linux: py310-test-pyside64-skipexitcode
- linux: py311-test-pyside64-skipexitcode
- linux: py311-test-pyside65-skipexitcode
- linux: py312-test-pyside67-skipexitcode
- macos: py310-test-pyside63-skipexitcode
- macos: py311-test-pyside64-skipexitcode
- macos: py312-test-pyside67-skipexitcode
- macos: py310-test-pyqt515
- windows: py310-test-pyside64
- windows: py312-test-pyside66
- windows: py311-test-pyqt515
# Windows docs build
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: 2
build:
os: "ubuntu-22.04"
tools:
python: "3"
python: "3.12"

sphinx:
builder: html
Expand Down
10 changes: 7 additions & 3 deletions glue_qt/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
try:
from qtpy import PYSIDE2, PYSIDE6
except Exception:
PYSIDE2 = False
PYSIDE2 = PYSIDE6 = False

from glue.config import CFG_DIR as CFG_DIR_ORIG

Expand Down Expand Up @@ -50,11 +50,15 @@ def pytest_configure(config):

if config.getoption('no_optional_skip'):
from glue.tests import helpers
from glue_qt.tests import helpers as qt_helpers
for attr in helpers.__dict__:
if attr.startswith('requires_'):
# The following line replaces the decorators with a function
# that does noting, effectively disabling it.
# that does nothing, effectively disabling it.
setattr(helpers, attr, lambda f: f)
for attr in qt_helpers.__dict__:
if attr.startswith('requires_'):
setattr(qt_helpers, attr, lambda f: f)

# Make sure we don't affect the real glue config dir
import tempfile
Expand Down Expand Up @@ -105,7 +109,7 @@ def pytest_unconfigure(config):
# objgraph.show_most_common_types(limit=100)


# With PySide2, tests can fail in a non-deterministic way on a teardown error
# With PySide2/6, tests can fail in a non-deterministic way on a teardown error
# or with the following error:
#
# AttributeError: 'PySide2.QtGui.QStandardItem' object has no attribute '...'
Expand Down
26 changes: 23 additions & 3 deletions glue_qt/tests/helpers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
# Define decorators that can be used for pytest tests

import pytest

from glue.tests.helpers import PYQT5_INSTALLED, PYQT6_INSTALLED, PYSIDE2_INSTALLED, PYSIDE6_INSTALLED
from glue.tests.helpers import make_skipper

PYQT5_INSTALLED, requires_pyqt5 = make_skipper('PyQt5')
PYQT6_INSTALLED, requires_pyqt6 = make_skipper('PyQt6')
PYSIDE2_INSTALLED, requires_pyside2 = make_skipper('PySide2')
PYSIDE6_INSTALLED, requires_pyside6 = make_skipper('PySide6')

PYQT_INSTALLED = PYQT5_INSTALLED or PYQT6_INSTALLED
PYSIDE_INSTALLED = PYSIDE2_INSTALLED or PYSIDE6_INSTALLED
QT_INSTALLED = PYQT_INSTALLED or PYSIDE_INSTALLED

requires_pyqt = pytest.mark.skipif(str(not PYQT5_INSTALLED and not PYQT6_INSTALLED),
requires_pyqt = pytest.mark.skipif(str(not PYQT_INSTALLED),
reason='An installation of PyQt is required')

requires_pyside = pytest.mark.skipif(str(not PYSIDE2_INSTALLED and not PYSIDE6_INSTALLED),
requires_pyside = pytest.mark.skipif(str(not PYSIDE_INSTALLED),
reason='An installation of PySide is required')

requires_qt = pytest.mark.skipif(str(not QT_INSTALLED),
reason='An installation of Qt is required')

PYQT_GT_59, _ = make_skipper('PyQt5', version='5.10')

requires_pyqt_gt_59_or_pyside = pytest.mark.skipif(str(not (PYQT_GT_59 or PYQT6_INSTALLED or
PYSIDE_INSTALLED)),
reason='Requires PyQt > 5.9 or PySide2/6')
4 changes: 2 additions & 2 deletions glue_qt/tests/test_session_back_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import pytest
import numpy as np

from glue.tests.helpers import requires_astropy, requires_h5py, requires_qt
from glue_qt.tests.helpers import requires_pyqt
from glue.tests.helpers import requires_astropy, requires_h5py
from glue_qt.tests.helpers import requires_pyqt, requires_qt
from glue.core.component import CoordinateComponent, Component
from glue.core.state import GlueUnSerializer
from glue.core.component_id import PixelComponentID
Expand Down
12 changes: 7 additions & 5 deletions glue_qt/viewers/profile/mouse_mode.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from echo import CallbackProperty, delay_callback
from glue.core.state_objects import State
from glue.viewers.matplotlib.mouse_mode import MouseMode
from matplotlib.patches import Rectangle

__all__ = ['NavigateMouseMode', 'RangeMouseMode']

Expand Down Expand Up @@ -155,11 +156,12 @@ def _update_artist(self, *args):
else:
self._lines[0].set_data([self.state.x_min, self.state.x_min], [0, 1])
self._lines[1].set_data([self.state.x_max, self.state.x_max], [0, 1])
self._interval.set_xy([[self.state.x_min, 0],
[self.state.x_min, 1],
[self.state.x_max, 1],
[self.state.x_max, 0],
[self.state.x_min, 0]])
if isinstance(self._interval, Rectangle):
self._interval.set_xy([self.state.x_min, self.state.x_max])
else:
self._interval.set_xy([[self.state.x_min, 0], [self.state.x_min, 1],
[self.state.x_max, 1], [self.state.x_max, 0],
[self.state.x_min, 0]])
else:
if self.state.x_min is not None and self.state.x_max is not None:
self._lines = (self._axes.axvline(self.state.x_min, color=COLOR),
Expand Down
27 changes: 18 additions & 9 deletions glue_qt/viewers/table/tests/test_data_viewer.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import pytest
import numpy as np
from packaging.version import Version
from unittest.mock import MagicMock, patch

from qtpy import QtCore, QtGui
from qtpy import QtCore, QtGui, QT_VERSION
from qtpy.QtCore import Qt

from glue_qt.utils import get_qapp, process_events
from glue.core import Data, DataCollection, BaseData
from glue_qt.utils import qt_to_mpl_color
from glue_qt.app import GlueApplication
from glue.core import Data, DataCollection, BaseData
from glue_qt.tests.helpers import requires_pyqt_gt_59_or_pyside
from glue_qt.utils import get_qapp, process_events, qt_to_mpl_color

from ..data_viewer import DataTableModel, TableViewer

Expand Down Expand Up @@ -178,10 +179,15 @@ def press_key(key):
press_key(Qt.Key_Down)
press_key(Qt.Key_Down)

process_events()

process_events(0.5)
indices = selection.selectedRows()

# On newer Qt6 down keys seem to be a bit "sticky"...

if len(indices) == 0 or indices[0].row() < 2:
press_key(Qt.Key_Down)
indices = selection.selectedRows()

# We make sure that the third row is selected

assert len(indices) == 1
Expand Down Expand Up @@ -460,6 +466,7 @@ def test_incompatible_subset():
assert refresh2.call_count == 0


@requires_pyqt_gt_59_or_pyside
def test_table_incompatible_attribute():
"""
Regression test for a bug where the table viewer generates an
Expand Down Expand Up @@ -628,7 +635,7 @@ def press_key(key):
press_key(Qt.Key_Down)
press_key(Qt.Key_Enter)

process_events()
process_events(0.5)

# Check that the table model is still the same, which it
# should be since we aren't changing the viewer Data
Expand All @@ -641,7 +648,9 @@ def press_key(key):
color = d.subsets[0].style.color
colors[1] = color

check_values_and_color(post_model, data, colors)
# Skip on higher versions, where `PyQt6.QtGui.QBrush` is not correctly cleared on 2nd pass
if Version(QT_VERSION) < Version('6.6'):
check_values_and_color(post_model, data, colors)


def test_table_widget_filter(tmpdir):
Expand Down Expand Up @@ -799,7 +808,7 @@ def test_table_sorts_after_update_data():

d.update_components({d.components[2]: [3.2, 1.2, 4.5, 2.5, 3.4]})

process_events()
process_events(0.5)

data = {'a': [2, 4, 1, 5, 3],
'b': [1.2, 2.5, 3.2, 3.4, 4.5],
Expand Down
11 changes: 10 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tox]
envlist =
py{38,39,310,311}-{codestyle,test,docs}-{pyqt514,pyqt515,pyside514,pyside515,pyqt63,pyside63}-all-{dev,legacy}
py{38,39,310,311,312}-{codestyle,test,docs}-{pyqt514,pyqt515,pyside514,pyside515,pyqt63,pyqt64,pyqt66,pyqt67,pyqt65,pyqt63,pyside66,pyside67}-all-{dev,legacy}
requires = pip >= 18.0
setuptools >= 30.3.0

Expand All @@ -27,10 +27,19 @@ deps =
pyqt63: PyQt6-Qt6==6.3.*
pyqt64: PyQt6==6.4.*
pyqt64: PyQt6-Qt6==6.4.*
pyqt65: PyQt6-Qt6==6.5.*
pyqt65: PyQt6==6.5.*
pyqt66: PyQt6-Qt6==6.6.*
pyqt66: PyQt6==6.6.*
pyqt67: PyQt6-Qt6==6.7.*
pyqt67: PyQt6==6.7.*
pyside514: PySide2==5.14.*
pyside515: PySide2==5.15.*
pyside63: PySide6==6.3.*
pyside64: PySide6==6.4.*
pyside65: PySide6==6.5.*
pyside66: PySide6==6.6.*
pyside67: PySide6==6.7.*
dev: git+https://github.com/numpy/numpy
dev: git+https://github.com/astropy/astropy
lts: astropy==5.0.*
Expand Down

0 comments on commit de4f45c

Please sign in to comment.