From 9a49914032dfaa07dfc5369be6a94637633602eb Mon Sep 17 00:00:00 2001 From: Luca Marconato Date: Tue, 27 Jan 2026 16:41:53 +0100 Subject: [PATCH 1/7] fix scanpy set_default_colors_for_categorical_obs --- src/napari_spatialdata/_widgets.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/napari_spatialdata/_widgets.py b/src/napari_spatialdata/_widgets.py index 5431036f..95839054 100644 --- a/src/napari_spatialdata/_widgets.py +++ b/src/napari_spatialdata/_widgets.py @@ -18,13 +18,19 @@ from napari.viewer import Viewer from qtpy import QtCore, QtWidgets from qtpy.QtCore import Qt, Signal -from scanpy.plotting._utils import _set_colors_for_categorical_obs from sklearn.preprocessing import MinMaxScaler from spatialdata._types import ArrayLike from superqt import QRangeSlider from vispy import scene from vispy.color.colormap import Colormap, MatplotlibColormap from vispy.scene.widgets import ColorBarWidget +# See https://github.com/scverse/squidpy/issues/1061 for more details. +# Scanpy 0.11.x-0.12.x renamed set_default_colors_for_categorical_obs to _set_default_colors_for_categorical_obs +# and then changed it back. Try underscore version first, fall back to non-underscore. +try: + from scanpy.plotting._utils import _set_default_colors_for_categorical_obs as set_default_colors_for_categorical_obs +except ImportError: + from scanpy.plotting._utils import set_default_colors_for_categorical_obs from napari_spatialdata._model import DataModel from napari_spatialdata.utils._utils import _min_max_norm, get_napari_version From 0fbbed58cfcb010edad86d5fd5e05bd87f2af533 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 15:42:59 +0000 Subject: [PATCH 2/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/napari_spatialdata/_widgets.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/napari_spatialdata/_widgets.py b/src/napari_spatialdata/_widgets.py index 95839054..b94a1763 100644 --- a/src/napari_spatialdata/_widgets.py +++ b/src/napari_spatialdata/_widgets.py @@ -24,13 +24,14 @@ from vispy import scene from vispy.color.colormap import Colormap, MatplotlibColormap from vispy.scene.widgets import ColorBarWidget + # See https://github.com/scverse/squidpy/issues/1061 for more details. # Scanpy 0.11.x-0.12.x renamed set_default_colors_for_categorical_obs to _set_default_colors_for_categorical_obs # and then changed it back. Try underscore version first, fall back to non-underscore. try: from scanpy.plotting._utils import _set_default_colors_for_categorical_obs as set_default_colors_for_categorical_obs except ImportError: - from scanpy.plotting._utils import set_default_colors_for_categorical_obs + pass from napari_spatialdata._model import DataModel from napari_spatialdata.utils._utils import _min_max_norm, get_napari_version From fca677fa466cc26746c31a07a728406985b54f2f Mon Sep 17 00:00:00 2001 From: Luca Marconato Date: Tue, 27 Jan 2026 16:44:42 +0100 Subject: [PATCH 3/7] fix --- src/napari_spatialdata/_widgets.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/napari_spatialdata/_widgets.py b/src/napari_spatialdata/_widgets.py index 95839054..a3959813 100644 --- a/src/napari_spatialdata/_widgets.py +++ b/src/napari_spatialdata/_widgets.py @@ -24,6 +24,7 @@ from vispy import scene from vispy.color.colormap import Colormap, MatplotlibColormap from vispy.scene.widgets import ColorBarWidget + # See https://github.com/scverse/squidpy/issues/1061 for more details. # Scanpy 0.11.x-0.12.x renamed set_default_colors_for_categorical_obs to _set_default_colors_for_categorical_obs # and then changed it back. Try underscore version first, fall back to non-underscore. @@ -219,7 +220,7 @@ def _(self, vec: pd.Series, **kwargs: Any) -> dict[str, Any]: if self._attr != "columns_df": if vec_color_name not in self.model.adata.uns: colorer = AnnData(shape=(len(vec), 0), obs=pd.DataFrame(index=vec.index, data={"vec": vec})) - _set_colors_for_categorical_obs(colorer, "vec", palette="tab20") + set_default_colors_for_categorical_obs(colorer, "vec", palette="tab20") colors = colorer.uns["vec_colors"] color_dict = dict(zip(vec.cat.categories, colors, strict=False)) color_dict.update({np.nan: "#808080ff"}) @@ -230,7 +231,7 @@ def _(self, vec: pd.Series, **kwargs: Any) -> dict[str, Any]: df = layer.metadata["_columns_df"] if vec_color_name not in df.columns: colorer = AnnData(shape=(len(vec), 0), obs=pd.DataFrame(index=vec.index, data={"vec": vec})) - _set_colors_for_categorical_obs(colorer, "vec", palette="tab20") + set_default_colors_for_categorical_obs(colorer, "vec", palette="tab20") colors = colorer.uns["vec_colors"] color_dict = dict(zip(vec.cat.categories, colors, strict=False)) color_dict.update({np.nan: "#808080ff"}) From dd323f4766a4d4ab95d79ff43ad88b2eee4eee1b Mon Sep 17 00:00:00 2001 From: Luca Marconato Date: Tue, 27 Jan 2026 16:45:57 +0100 Subject: [PATCH 4/7] fix --- src/napari_spatialdata/_widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/napari_spatialdata/_widgets.py b/src/napari_spatialdata/_widgets.py index a50be34e..3c57a4d6 100644 --- a/src/napari_spatialdata/_widgets.py +++ b/src/napari_spatialdata/_widgets.py @@ -31,7 +31,7 @@ try: from scanpy.plotting._utils import _set_default_colors_for_categorical_obs as set_default_colors_for_categorical_obs except ImportError: - pass + from scanpy.plotting._utils import _set_default_colors_for_categorical_obs as set_default_colors_for_categorical_obs from napari_spatialdata._model import DataModel from napari_spatialdata.utils._utils import _min_max_norm, get_napari_version From 17a265616fb309e0a0918f19a8192d9333ebc6d0 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 27 Jan 2026 15:48:41 +0000 Subject: [PATCH 5/7] fix --- src/napari_spatialdata/_widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/napari_spatialdata/_widgets.py b/src/napari_spatialdata/_widgets.py index 3c57a4d6..a3959813 100644 --- a/src/napari_spatialdata/_widgets.py +++ b/src/napari_spatialdata/_widgets.py @@ -31,7 +31,7 @@ try: from scanpy.plotting._utils import _set_default_colors_for_categorical_obs as set_default_colors_for_categorical_obs except ImportError: - from scanpy.plotting._utils import _set_default_colors_for_categorical_obs as set_default_colors_for_categorical_obs + from scanpy.plotting._utils import set_default_colors_for_categorical_obs from napari_spatialdata._model import DataModel from napari_spatialdata.utils._utils import _min_max_norm, get_napari_version From d08d8fb4d8c3f5df6a3c21b4f2125cde6c570867 Mon Sep 17 00:00:00 2001 From: Luca Marconato Date: Tue, 27 Jan 2026 17:08:10 +0100 Subject: [PATCH 6/7] fix tests --- src/napari_spatialdata/_widgets.py | 8 ++++---- tests/conftest.py | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/napari_spatialdata/_widgets.py b/src/napari_spatialdata/_widgets.py index 3c57a4d6..7cab1d64 100644 --- a/src/napari_spatialdata/_widgets.py +++ b/src/napari_spatialdata/_widgets.py @@ -29,9 +29,9 @@ # Scanpy 0.11.x-0.12.x renamed set_default_colors_for_categorical_obs to _set_default_colors_for_categorical_obs # and then changed it back. Try underscore version first, fall back to non-underscore. try: - from scanpy.plotting._utils import _set_default_colors_for_categorical_obs as set_default_colors_for_categorical_obs + from scanpy.plotting._utils import _set_colors_for_categorical_obs as set_colors_for_categorical_obs except ImportError: - from scanpy.plotting._utils import _set_default_colors_for_categorical_obs as set_default_colors_for_categorical_obs + from scanpy.plotting._utils import set_colors_for_categorical_obs from napari_spatialdata._model import DataModel from napari_spatialdata.utils._utils import _min_max_norm, get_napari_version @@ -220,7 +220,7 @@ def _(self, vec: pd.Series, **kwargs: Any) -> dict[str, Any]: if self._attr != "columns_df": if vec_color_name not in self.model.adata.uns: colorer = AnnData(shape=(len(vec), 0), obs=pd.DataFrame(index=vec.index, data={"vec": vec})) - set_default_colors_for_categorical_obs(colorer, "vec", palette="tab20") + set_colors_for_categorical_obs(colorer, "vec", palette="tab20") colors = colorer.uns["vec_colors"] color_dict = dict(zip(vec.cat.categories, colors, strict=False)) color_dict.update({np.nan: "#808080ff"}) @@ -231,7 +231,7 @@ def _(self, vec: pd.Series, **kwargs: Any) -> dict[str, Any]: df = layer.metadata["_columns_df"] if vec_color_name not in df.columns: colorer = AnnData(shape=(len(vec), 0), obs=pd.DataFrame(index=vec.index, data={"vec": vec})) - set_default_colors_for_categorical_obs(colorer, "vec", palette="tab20") + set_colors_for_categorical_obs(colorer, "vec", palette="tab20") colors = colorer.uns["vec_colors"] color_dict = dict(zip(vec.cat.categories, colors, strict=False)) color_dict.update({np.nan: "#808080ff"}) diff --git a/tests/conftest.py b/tests/conftest.py index e4f46808..981d2fa6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,11 @@ from __future__ import annotations +# MUST set environment variables BEFORE any Qt/napari/vispy imports +# to enable headless mode in CI environments (Ubuntu/Linux without display) import os + +# os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") +# os.environ.setdefault("NAPARI_HEADLESS", "1") import random import string from abc import ABC, ABCMeta From 3eea7e06c8a9c8b399bf80bc50835f9144be61c0 Mon Sep 17 00:00:00 2001 From: Luca Marconato Date: Tue, 27 Jan 2026 17:52:22 +0100 Subject: [PATCH 7/7] fix tests macos/linux --- tests/conftest.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 981d2fa6..9329ad51 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,9 +3,13 @@ # MUST set environment variables BEFORE any Qt/napari/vispy imports # to enable headless mode in CI environments (Ubuntu/Linux without display) import os +import sys -# os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") -# os.environ.setdefault("NAPARI_HEADLESS", "1") +# Only use offscreen on Linux - macOS doesn't support the offscreen Qt platform plugin +if sys.platform == "linux": + os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") + +os.environ.setdefault("NAPARI_HEADLESS", "1") import random import string from abc import ABC, ABCMeta