diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 1336e17..cf0b6fc 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -10,7 +10,7 @@ jobs: runs-on: "ubuntu-latest" strategy: matrix: - python-version: ["3.11"] + python-version: ["3.14"] steps: - uses: "actions/checkout@v3" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8e13e01..a96e85a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: - name: "Set up Python" uses: "actions/setup-python@v4" with: - python-version: "3.9" + python-version: "3.12" - name: "Install build tool" run: "pip install --user build" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 86e82de..a4291c3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,9 +11,9 @@ jobs: strategy: matrix: python-version: - - "3.11" - - "3.10" - - "3.9" + - "3.14" + - "3.13" + - "3.12" pyqt-dependency: - "PyQt6" - "PySide6" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b7cc1e3..a3de1ea 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,14 +7,14 @@ repos: - id: "end-of-file-fixer" - repo: "https://github.com/charliermarsh/ruff-pre-commit" - rev: "v0.0.269" + rev: "v0.15.14" hooks: - - id: "ruff" + - id: "ruff-check" # NOTE: "--exit-non-zero-on-fix" is important for CI to function # correctly! args: ["--fix", "--exit-non-zero-on-fix"] - repo: "https://github.com/psf/black" - rev: "23.3.0" + rev: "26.5.1" hooks: - id: "black" diff --git a/README.rst b/README.rst index 90e5d3e..963d70e 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,7 @@ Contact: Nathaniel J. Smith and Stéfan van der Walt Dependencies: - * Python 3.9+ + * Python 3.12+ * `colorspacious `_ 1.1+ * Matplotlib 3.5+ * NumPy 1.22+ diff --git a/environment.yml b/environment.yml index bf96902..772d85a 100644 --- a/environment.yml +++ b/environment.yml @@ -4,7 +4,7 @@ channels: - "nodefaults" dependencies: # Runtime - - "python ~=3.11" + - "python ~=3.12" - "numpy ~=1.24" - "matplotlib ~=3.7" - "colorspacious ~=1.1" diff --git a/pyproject.toml b/pyproject.toml index 3ded452..6f7a2a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,12 +15,12 @@ classifiers = [ "Programming Language :: Python :: 3", ] -requires-python = "~=3.9" +requires-python = ">=3.12" 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] @@ -60,7 +60,7 @@ package-data = {viscm = ["examples/*"]} [tool.mypy] -python_version = "3.9" +python_version = "3.12" # These libraries don't have type stubs. Mypy will see them as `Any` and not # throw an [import] error. @@ -73,11 +73,7 @@ module = [ ignore_missing_imports = true -[tool.black] -target-version = ["py39", "py310", "py311"] - -[tool.ruff] -target-version = "py39" +[tool.ruff.lint] select = [ "F", "E", @@ -93,9 +89,16 @@ select = [ "T10", "RUF", ] +ignore = [ + "B905", + "UP031", + "RUF005", + "RUF046", + "RUF059", +] -[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/cli.py b/viscm/cli.py index af1cd47..40b848e 100644 --- a/viscm/cli.py +++ b/viscm/cli.py @@ -1,6 +1,5 @@ import sys from pathlib import Path -from typing import Union import matplotlib.pyplot as plt @@ -117,13 +116,13 @@ def cli(): def _make_window( *, action: str, - cmap: Union[str, None], + cmap: str | None, cmap_type: str, cmap_spline_method: str, cmap_uniform_space: str, - save: Union[Path, None], + save: Path | None, quit_immediately: bool, -) -> Union[gui.ViewerWindow, gui.EditorWindow]: +) -> gui.ViewerWindow | gui.EditorWindow: # Hold a reference so it doesn't get GC'ed fig = plt.figure() figure_canvas = gui.FigureCanvas(fig) @@ -132,7 +131,7 @@ def _make_window( if cmap: cm.load(cmap) - v: Union[gui.viscm, gui.viscm_editor] + v: gui.viscm | gui.viscm_editor # Easter egg! I keep typing 'show' instead of 'view' so accept both if action in ("view", "show"): if cm is None: diff --git a/viscm/gui.py b/viscm/gui.py index 01a33d7..eb74c43 100644 --- a/viscm/gui.py +++ b/viscm/gui.py @@ -284,9 +284,9 @@ 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}" + f"\nRMS deviation from flat: {rmse:0.1f}" + f" ({100 * rmse / arclength:0.1f}%)", ) ax.set_ylim(-delta_ymax(-local_derivs), delta_ymax(local_derivs)) ax.get_xaxis().set_visible(False) @@ -308,11 +308,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}" + f"\nRMS deviation from flat: {lightness_rmse:0.1f}" + f" ({100 * lightness_rmse / lightness_arclength:0.1f}%)", ) ax.set_ylim(-delta_ymax(-lightness_derivs), delta_ymax(lightness_derivs)) @@ -707,16 +705,14 @@ def save_colormap(self, filepath): def export_py(self, filepath): import textwrap - template = textwrap.dedent( - """ + template = textwrap.dedent(""" from matplotlib.colors import ListedColormap cm_type = "{type}" cm_data = {array_list} test_cm = ListedColormap(cm_data, name="{name}") - """ - ) + """) rgb, _ = self.cmap_model.get_sRGB(num=256) array_list = np.array2string( rgb, max_line_width=78, prefix="cm_data = ", separator=","