Skip to content

Commit

Permalink
build: drop support for python 3.8, test 3.12 (#368)
Browse files Browse the repository at this point in the history
* chore: drop py3.8, support 3.13

* formatting

* change matrix

* change matrix

* change pinning

* switch py313 to windows

* ignore failed to disconnect

* fix pyside6

* no 3.13 yet

* style(pre-commit.ci): auto fixes [...]

* pin pyside

* update readme

* don't test stack viewer on pyside

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
tlambert03 and pre-commit-ci[bot] authored Oct 12, 2024
1 parent a585acb commit d58003b
Show file tree
Hide file tree
Showing 28 changed files with 135 additions and 61 deletions.
28 changes: 12 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,25 @@ jobs:
fail-fast: false
matrix:
platform: [macos-13, windows-latest]
python-version: ["3.8", "3.11"]
backend: [pyside2, pyqt5]
include:
- platform: macos-13
python-version: "3.10"
backend: pyside6
- platform: macos-13
python-version: "3.11"
backend: pyqt6
python-version: ["3.10", "3.12"]
backend: [pyside6, pyqt6]
exclude:
- platform: windows-latest
python-version: "3.10"
backend: pyside6
- platform: windows-latest
python-version: "3.11"
backend: pyqt6
- platform: windows-latest
include:
- platform: macos-13
python-version: "3.9"
backend: pyside2
- platform: windows-latest
python-version: "3.9"
backend: pyqt5
exclude:
- python-version: "3.11"
backend: pyside2
- platform: windows-latest
python-version: "3.11"
backend: pyqt5
# - platform: windows-latest
# python-version: "3.13"
# backend: pyqt6

steps:
- uses: actions/checkout@v4
Expand All @@ -63,6 +58,7 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Install dependencies
run: |
Expand Down
7 changes: 3 additions & 4 deletions .github/workflows/cron.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@ name: --pre Test

on:
schedule:
- cron: '0 */12 * * *' # every 12 hours
- cron: "0 */12 * * *" # every 12 hours
workflow_dispatch:

jobs:

test:
name: ${{ matrix.platform }} (${{ matrix.python-version }})
runs-on: ${{ matrix.platform }}
strategy:
fail-fast: false
matrix:
python-version: ['3.8', '3.9', '3.10']
python-version: ["3.11"]
platform: [macos-13, windows-latest]
backend: [pyside2, pyqt5]

Expand Down Expand Up @@ -55,7 +54,7 @@ jobs:
PLATFORM: ${{ matrix.platform }}
PYTHON: ${{ matrix.python }}
RUN_ID: ${{ github.run_id }}
TITLE: '[test-bot] pip install --pre is failing'
TITLE: "[test-bot] pip install --pre is failing"
with:
filename: .github/TEST_FAIL_TEMPLATE.md
update_existing: true
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ It forms the basis of [`napari-micromanager`](https://github.com/pymmcore-plus/n

See complete list of available widgets in the [documentation](https://pymmcore-plus.github.io/pymmcore-widgets/#widgets)


## Installation

```sh
Expand All @@ -28,5 +27,5 @@ pip install pymmcore-widgets
# you must install one yourself, for example:
pip install PyQt5

# package is tested against PyQt5, PyQt6, PySide2, and PySide6
# package is tested against PyQt5, PyQt6, PySide2, and PySide6(==6.7)
```
20 changes: 15 additions & 5 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,18 @@ pip install pymmcore-widgets

### Installing PyQt or PySide

Since [pymmcore-widgets](./index.md) relies on either the [PyQt](https://riverbankcomputing.com/software/pyqt/) or [PySide](https://www.qt.io/qt-for-python) libraries, you also **need** to install one of these packages. You can use any of the available versions of these libraries: [PyQt5](https://pypi.org/project/PyQt5/), [PyQt6](https://pypi.org/project/PyQt6/), [PySide2](https://pypi.org/project/PySide2/) or [PySide6](https://pypi.org/project/PySide6/). For example, to install [PyQt6](https://riverbankcomputing.com/software/pyqt/download), you can use:
Since [pymmcore-widgets](./index.md) relies on either the
[PyQt](https://riverbankcomputing.com/software/pyqt/) or
[PySide](https://www.qt.io/qt-for-python) libraries, you also **need** to
install one of these packages. You can use any of the available versions of
these libraries: [PyQt5](https://pypi.org/project/PyQt5/),
[PyQt6](https://pypi.org/project/PyQt6/),
[PySide2](https://pypi.org/project/PySide2/) or
[PySide6](https://pypi.org/project/PySide6/). We strongly recommend using PyQt6
if possible. If you must use a specific backend version and run into problems,
please open an issue

For example, to install [PyQt6](https://riverbankcomputing.com/software/pyqt/download), you can use:

```sh
pip install PyQt6
Expand All @@ -21,10 +32,9 @@ pip install PyQt6
!!! Note
Widgets are tested on:

* `macOS & Windows`
* `Python 3.8, 3.9 3.10 & 3.11`
* `PyQt5 & PyQt6`
* `PySide2 & PySide6`
* macOS & Windows
* Python 3.9 and above
* PyQt5, PyQt6, PySide2 & PySide6(==6.7)

### Installing Micro-Manager

Expand Down
23 changes: 16 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ sources = ["src"]
name = "pymmcore-widgets"
description = "A set of Qt-based widgets onto the pymmcore-plus model"
readme = "README.md"
requires-python = ">=3.8"
requires-python = ">=3.9"
license = { text = "BSD 3-Clause License" }
authors = [
{ email = "[email protected]", name = "Federico Gasparoli" },
Expand All @@ -34,10 +34,11 @@ classifiers = [
"Intended Audience :: Science/Research",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python",
"Topic :: Software Development :: Widget Sets",
"Topic :: System :: Hardware :: Hardware Drivers",
Expand All @@ -60,11 +61,19 @@ allow-direct-references = true
# extras
# https://peps.python.org/pep-0621/#dependencies-optional-dependencies
[project.optional-dependencies]
test = ["pytest>=6.0", "pytest-cov", "pytest-qt", "PyYAML", "vispy", "cmap", "zarr"]
test = [
"pytest>=6.0",
"pytest-cov",
"pytest-qt",
"PyYAML",
"vispy",
"cmap",
"zarr",
]
pyqt5 = ["PyQt5"]
pyside2 = ["PySide2"]
pyqt6 = ["PyQt6"]
pyside6 = ["PySide6<6.5"]
pyside6 = ["PySide6==6.7.3"] # pretty hard to find a good match here...
image = ["vispy"]

dev = [
Expand Down Expand Up @@ -97,8 +106,9 @@ Documentation = "https://pymmcore-plus.github.io/pymmcore-widgets"
# https://beta.ruff.rs/docs/rules/
[tool.ruff]
line-length = 88
target-version = "py38"
target-version = "py39"
src = ["src", "tests"]

[tool.ruff.lint]
pydocstyle = { convention = "numpy" }
select = [
Expand All @@ -115,7 +125,6 @@ select = [
"RUF", # ruff-specific rules
"TID", # tidy
"TCH", # typecheck
# "SLF", # private-access
]
ignore = [
"D100", # Missing docstring in public module
Expand All @@ -135,6 +144,7 @@ testpaths = ["tests"]
filterwarnings = [
"error",
"ignore:distutils Version classes are deprecated",
"ignore:Failed to disconnect:RuntimeWarning:",
# warning, but not error, that will show up on useq<0.3.3
]

Expand Down Expand Up @@ -178,4 +188,3 @@ ignore = [

[tool.typos.default]
extend-ignore-identifiers-re = ["(?i)nd2?.*", "(?i)ome", "FO(Vs?)?"]

8 changes: 6 additions & 2 deletions src/pymmcore_widgets/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import re
from pathlib import Path
from typing import Any, ContextManager, Sequence
from typing import TYPE_CHECKING, Any

import useq
from psygnal import SignalInstance
Expand All @@ -21,6 +21,10 @@
)
from superqt.utils import signals_blocked

if TYPE_CHECKING:
from collections.abc import Sequence
from contextlib import AbstractContextManager


class ComboMessageBox(QDialog):
"""Dialog that presents a combo box of `items`."""
Expand Down Expand Up @@ -91,7 +95,7 @@ def guess_objective_or_prompt(
return None


def block_core(obj: Any) -> ContextManager:
def block_core(obj: Any) -> AbstractContextManager:
"""Block core signals."""
if isinstance(obj, QObject):
return signals_blocked(obj) # type: ignore [no-any-return]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from __future__ import annotations

from typing import Any, Sequence, cast
from typing import TYPE_CHECKING, Any, cast

from qtpy.QtCore import Qt
from qtpy.QtWidgets import QTableWidget, QTableWidgetItem

from pymmcore_widgets.device_properties._property_widget import PropertyWidget

if TYPE_CHECKING:
from collections.abc import Sequence

DEV_PROP_ROLE = Qt.ItemDataRole.UserRole + 1


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import itertools
import warnings
from collections import Counter
from typing import Any, Sequence, cast
from typing import TYPE_CHECKING, Any, cast

from pymmcore_plus import CMMCorePlus, DeviceProperty
from pymmcore_plus.model import PixelSizeGroup, PixelSizePreset, Setting
Expand Down Expand Up @@ -35,6 +35,9 @@
from pymmcore_widgets.useq_widgets import DataTable, DataTableWidget
from pymmcore_widgets.useq_widgets._column_info import FloatColumn, TextColumn

if TYPE_CHECKING:
from collections.abc import Sequence

FIXED = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
PX = "px"
ID = "id"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from logging import getLogger
from typing import Iterable, cast
from typing import TYPE_CHECKING, cast

from pymmcore_plus import CMMCorePlus, DeviceProperty, DeviceType
from qtpy.QtCore import Qt
Expand All @@ -13,6 +13,9 @@

from ._property_widget import PropertyWidget

if TYPE_CHECKING:
from collections.abc import Iterable

logger = getLogger(__name__)


Expand Down
3 changes: 2 additions & 1 deletion src/pymmcore_widgets/device_properties/_properties_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from __future__ import annotations

from typing import TYPE_CHECKING, Iterable, cast
from typing import TYPE_CHECKING, cast

from pymmcore_plus import CMMCorePlus
from qtpy.QtWidgets import QGridLayout, QLabel, QWidget
Expand All @@ -14,6 +14,7 @@

if TYPE_CHECKING:
import re
from collections.abc import Iterable


class PropertiesWidget(QWidget):
Expand Down
5 changes: 4 additions & 1 deletion src/pymmcore_widgets/hcs/_plate_calibration_widget.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from contextlib import suppress
from typing import Mapping
from typing import TYPE_CHECKING

import numpy as np
import useq
Expand All @@ -28,6 +28,9 @@
)
from pymmcore_widgets.useq_widgets._well_plate_widget import WellPlateView

if TYPE_CHECKING:
from collections.abc import Mapping


class PlateCalibrationWidget(QWidget):
"""Widget to calibrate a well plate.
Expand Down
5 changes: 4 additions & 1 deletion src/pymmcore_widgets/hcs/_util.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from __future__ import annotations

from typing import Iterable
from typing import TYPE_CHECKING

import numpy as np

if TYPE_CHECKING:
from collections.abc import Iterable


def find_circle_center(
coords: Iterable[tuple[float, float]],
Expand Down
5 changes: 4 additions & 1 deletion src/pymmcore_widgets/hcs/_well_calibration_widget.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from pathlib import Path
from typing import Iterator, NamedTuple, cast
from typing import TYPE_CHECKING, NamedTuple, cast

from fonticon_mdi6 import MDI6
from pymmcore_plus import CMMCorePlus
Expand All @@ -23,6 +23,9 @@

from ._util import find_circle_center, find_rectangle_center

if TYPE_CHECKING:
from collections.abc import Iterator

COMBO_ROLE = Qt.ItemDataRole.UserRole + 1
ICON_PATH = Path(__file__).parent / "icons"
ONE_CIRCLE = QIcon(str(ICON_PATH / "circle-center.svg"))
Expand Down
4 changes: 3 additions & 1 deletion src/pymmcore_widgets/hcwizard/_dev_setup_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@

import logging
from contextlib import suppress
from typing import TYPE_CHECKING, Sequence
from typing import TYPE_CHECKING

from pymmcore_plus import CMMCorePlus, Keyword
from qtpy.QtCore import Qt
Expand All @@ -104,6 +104,8 @@
from ._simple_prop_table import PropTable

if TYPE_CHECKING:
from collections.abc import Sequence

from qtpy.QtGui import QFocusEvent

logger = logging.getLogger(__name__)
Expand Down
4 changes: 3 additions & 1 deletion src/pymmcore_widgets/hcwizard/_peripheral_setup_dialog.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Iterable, cast
from typing import TYPE_CHECKING, cast

from pymmcore_plus.model import Device, Microscope
from qtpy.QtCore import QSize, Qt
Expand All @@ -20,6 +20,8 @@
from ._dev_setup_dialog import DeviceSetupDialog

if TYPE_CHECKING:
from collections.abc import Iterable

from pymmcore_plus import CMMCorePlus

FLAGS = Qt.WindowType.MSWindowsFixedSizeDialogHint | Qt.WindowType.Sheet
Expand Down
Loading

0 comments on commit d58003b

Please sign in to comment.