diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2244163..d7c78f7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,14 +9,17 @@ jobs: unit-test-and-typecheck: runs-on: "ubuntu-latest" strategy: + fail-fast: false matrix: python-version: + - "3.13" + - "3.12" - "3.11" - "3.10" - "3.9" pyqt-dependency: - - "PyQt6" - - "PySide6" + - "PyQt" + - "PySide" steps: - uses: "actions/checkout@v3" @@ -30,10 +33,10 @@ jobs: run: | # Project dependencies from pyproject.toml # NOTE: Also builds viscm. How do we avoid this? - pip install . + pip install .[${{ matrix.pyqt-dependency }}] # Test dependencies - pip install pytest pytest-cov pytest-qt pytest-xvfb ${{ matrix.pyqt-dependency }} + pip install pytest pytest-cov pytest-qt pytest-xvfb # pytest-qt CI dependencies: https://pytest-qt.readthedocs.io/en/latest/troubleshooting.html#github-actions sudo apt update sudo apt install -y \ @@ -41,6 +44,8 @@ jobs: libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 x11-utils \ libxcb-cursor0 + - run: pip list + - name: "Run tests" run: "make test" env: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b7cc1e3..32cee2f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,13 +1,13 @@ repos: - repo: "https://github.com/pre-commit/pre-commit-hooks" - rev: "v4.4.0" + rev: "v5.0.0" hooks: - id: "check-added-large-files" - id: "check-vcs-permalinks" - id: "end-of-file-fixer" - - repo: "https://github.com/charliermarsh/ruff-pre-commit" - rev: "v0.0.269" + - repo: "https://github.com/astral-sh/ruff-pre-commit" + rev: "v0.7.1" hooks: - id: "ruff" # NOTE: "--exit-non-zero-on-fix" is important for CI to function @@ -15,6 +15,6 @@ repos: args: ["--fix", "--exit-non-zero-on-fix"] - repo: "https://github.com/psf/black" - rev: "23.3.0" + rev: "24.10.0" hooks: - id: "black" diff --git a/pyproject.toml b/pyproject.toml index f5cb284..c291cb3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,12 +15,12 @@ classifiers = [ "Programming Language :: Python :: 3", ] -requires-python = "~=3.9" +requires-python = ">=3.9" dependencies = [ - "numpy ~=1.22", - "matplotlib ~=3.5", - "colorspacious ~=1.1", - "scipy ~=1.8", + "numpy >=1.22", + "matplotlib >=3.5", + "colorspacious >=1.1", + "scipy >=1.8", ] [project.optional-dependencies] @@ -64,13 +64,7 @@ module = [ ] ignore_missing_imports = true - - -[tool.black] -target-version = ["py39", "py310", "py311"] - -[tool.ruff] -target-version = "py39" +[tool.ruff.lint] select = [ "F", "E", @@ -87,8 +81,8 @@ select = [ "RUF", ] -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "viscm/gui.py" = ["N8"] -[tool.ruff.mccabe] +[tool.ruff.lint.mccabe] max-complexity = 11 diff --git a/test/data/option_d.py b/test/data/option_d.py index f2868b9..fd53f44 100644 --- a/test/data/option_d.py +++ b/test/data/option_d.py @@ -11,6 +11,7 @@ You should have received a copy of the CC0 legalcode along with this work. If not, see . """ + from matplotlib.colors import LinearSegmentedColormap # Used to reconstruct the colormap in viscm diff --git a/viscm/bezierbuilder/__init__.py b/viscm/bezierbuilder/__init__.py index cce4e21..d245047 100644 --- a/viscm/bezierbuilder/__init__.py +++ b/viscm/bezierbuilder/__init__.py @@ -26,7 +26,7 @@ """ import numpy as np -from matplotlib.backends.qt_compat import QtCore +from matplotlib.backends.qt_compat import QtCore # type: ignore [attr-defined] from matplotlib.lines import Line2D from viscm.bezierbuilder.curve import curve_method diff --git a/viscm/gui.py b/viscm/gui.py index e527ae3..1f32ec4 100644 --- a/viscm/gui.py +++ b/viscm/gui.py @@ -26,7 +26,11 @@ # matplotlib.rcParams['backend'] = "QtAgg" # Do this first before any other matplotlib imports, to force matplotlib to # use a Qt backend -from matplotlib.backends.qt_compat import QtCore, QtGui, QtWidgets +from matplotlib.backends.qt_compat import ( # type: ignore [attr-defined] + QtCore, + QtGui, + QtWidgets, +) from matplotlib.colors import ListedColormap from matplotlib.gridspec import GridSpec @@ -280,9 +284,8 @@ def delta_ymax(values): title(ax, "Perceptual derivative") label( ax, - "Length: {:0.1f}\nRMS deviation from flat: {:0.1f} ({:0.1f}%)".format( - arclength, rmse, 100 * rmse / arclength - ), + f"Length: {arclength:0.1f}\nRMS deviation from flat: " + f"{rmse:0.1f} ({100 * rmse / arclength:0.1f}%)", ) ax.set_ylim(-delta_ymax(-local_derivs), delta_ymax(local_derivs)) ax.get_xaxis().set_visible(False) @@ -304,11 +307,9 @@ def delta_ymax(values): lightness_rmse = np.std(lightness_derivs) label( ax, - "Length: {:0.1f}\nRMS deviation from flat: {:0.1f} ({:0.1f}%)".format( - lightness_arclength, - lightness_rmse, - 100 * lightness_rmse / lightness_arclength, - ), + f"Length: {lightness_arclength:0.1f}\nRMS deviation from flat: " + f"{lightness_rmse:0.1f} " + f"({100 * lightness_rmse / lightness_arclength:0.1f}%)", ) ax.set_ylim(-delta_ymax(-lightness_derivs), delta_ymax(lightness_derivs)) @@ -666,7 +667,7 @@ def save_colormap(self, filepath): hex_blob = "" for color in rgb: for component in color: - hex_blob += "%02x" % (int(round(component * 255))) + hex_blob += f"{int(round(component * 255)):02x}" usage_hints = ["red-green-colorblind-safe", "greyscale-safe"] if self.cmtype == "diverging": usage_hints.append("diverging")