Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 26 additions & 33 deletions .github/workflows/base_test_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ jobs:
test:
name: ${{ inputs.os }} py ${{ inputs.python_version }} ${{ inputs.napari }} ${{ inputs.qt_backend }} ${{ inputs.pydantic }}
runs-on: ${{ inputs.os }}
env:
NAPARI: ${{ inputs.napari }}
BACKEND: ${{ inputs.qt_backend }}
PYVISTA_OFF_SCREEN: True # required for opengl on windows
TOX_ARGS: ${{ inputs.tox_args }}
PYTEST_ARGS: ${{ inputs.pytest_args }}
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
Expand All @@ -61,20 +67,11 @@ jobs:
cache: 'pip'
cache-dependency-path: 'pyproject.toml'

# - name: Install ubuntu libraries
# if: runner.os == 'Linux'
# run: |
# sudo apt update
# sudo apt-get install -y libegl1 libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 x11-utils libxcb-cursor0

- uses: awalsh128/cache-apt-pkgs-action@latest
if: runner.os == 'Linux'
- name: Setup headless display
uses: pyvista/setup-headless-display-action@7d84ae825e6d9297a8e99bdbbae20d1b919a0b19 # v4.2
with:
packages: libegl1 libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 x11-utils libxcb-cursor0 libhdf5-dev
version: 1.0

- name: Install Windows OpenGL
uses: pyvista/setup-headless-display-action@v4
qt: true
wm: herbstluftwm

- name: Download test data
if: ${{ inputs.test_data }}
Expand All @@ -90,47 +87,43 @@ jobs:

- name: Test with tox PartSegImage
if: ${{ inputs.napari == 'latest' }}
run: python -m tox ${{ inputs.tox_args }} -- package/tests/test_PartSegImage ${{ inputs.pytest_args }}
shell: bash
run: |
# shellcheck disable=SC2086
python -m tox $TOX_ARGS -- package/tests/test_PartSegImage $PYTEST_ARGS
env:
PYVISTA_OFF_SCREEN: True # required for opengl on windows
NAPARI: ${{ inputs.napari }}
BACKEND: ${{ inputs.qt_backend }}
PIP_CONSTRAINT: ${{ inputs.napari == 'latest' && format('requirements/constraints_py{0}{1}.txt', inputs.python_version, inputs.pydantic ) || 'requirements/version_denylist.txt' }}
UV_CONSTRAINT: ${{ inputs.napari == 'latest' && format('requirements/constraints_py{0}{1}.txt', inputs.python_version, inputs.pydantic ) || 'requirements/version_denylist.txt' }}

- name: Test with tox PartSegCore
if: ${{ inputs.napari == 'latest' }}
run: python -m tox ${{ inputs.tox_args }} -- package/tests/test_PartSegCore ${{ inputs.pytest_args }}
shell: bash
run: |
# shellcheck disable=SC2086
python -m tox $TOX_ARGS -- package/tests/test_PartSegCore $PYTEST_ARGS
env:
PYVISTA_OFF_SCREEN: True # required for opengl on windows
NAPARI: ${{ inputs.napari }}
BACKEND: ${{ inputs.qt_backend }}
PIP_CONSTRAINT: ${{ inputs.napari == 'latest' && format('requirements/constraints_py{0}{1}.txt', inputs.python_version, inputs.pydantic ) || 'requirements/version_denylist.txt' }}
UV_CONSTRAINT: ${{ inputs.napari == 'latest' && format('requirements/constraints_py{0}{1}.txt', inputs.python_version, inputs.pydantic ) || 'requirements/version_denylist.txt' }}

- name: Test with tox PartSeg
if: ${{ inputs.napari == 'latest' }}
uses: aganders3/headless-gui@v2
timeout-minutes: ${{ inputs.timeout }}
with:
run: python -m tox ${{ inputs.tox_args }} -- package/tests/test_PartSeg ${{ inputs.pytest_args }}
shell: bash
run: |
# shellcheck disable=SC2086
python -m tox $TOX_ARGS -- package/tests/test_PartSeg $PYTEST_ARGS
env:
PYVISTA_OFF_SCREEN: True # required for opengl on windows
NAPARI: ${{ inputs.napari }}
BACKEND: ${{ inputs.qt_backend }}
PIP_CONSTRAINT: ${{ inputs.napari == 'latest' && format('requirements/constraints_py{0}{1}.txt', inputs.python_version, inputs.pydantic ) || 'requirements/version_denylist.txt' }}
UV_CONSTRAINT: ${{ inputs.napari == 'latest' && format('requirements/constraints_py{0}{1}.txt', inputs.python_version, inputs.pydantic ) || 'requirements/version_denylist.txt' }}

- name: Test with tox all
if: ${{ inputs.napari != 'latest' }}
uses: aganders3/headless-gui@v2
timeout-minutes: ${{ inputs.timeout }}
with:
run: python -m tox ${{ inputs.tox_args }} -- ${{ inputs.pytest_args }}
shell: bash
run: |
# shellcheck disable=SC2086
python -m tox $TOX_ARGS ${PYTEST_ARGS:+-- $PYTEST_ARGS}
env:
PYVISTA_OFF_SCREEN: True # required for opengl on windows
NAPARI: ${{ inputs.napari }}
BACKEND: ${{ inputs.qt_backend }}
PIP_CONSTRAINT: ${{ inputs.napari == 'latest' && format('requirements/constraints_py{0}{1}.txt', inputs.python_version, inputs.pydantic ) || 'requirements/version_denylist.txt' }}
UV_CONSTRAINT: ${{ inputs.napari == 'latest' && format('requirements/constraints_py{0}{1}.txt', inputs.python_version, inputs.pydantic ) || 'requirements/version_denylist.txt' }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_napari_repo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
fail-fast: false
matrix:
platform: [ ubuntu-24.04 ]
python: ['3.10', '3.11', '3.12']
python: ['3.10', '3.11', '3.12', '3.13']
napari_version: ['repo']
steps:
- uses: actions/checkout@v6
Expand Down
10 changes: 8 additions & 2 deletions package/PartSeg/common_gui/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,20 +227,26 @@ def get_colormaps(self) -> list[Optional[colormap.Colormap]]:
return [self.settings.colormap_dict[name][0] for name in colormaps_name]

def napari_viewer_show(self):
viewer = Viewer(title="Additional output", settings=self.settings, partseg_viewer_name=self.channel_info)
viewer = Viewer(
title="Additional output", settings=self.settings, partseg_viewer_name=self.channel_info, show=False
)
viewer.scale_bar.unit = "nm"
viewer.theme = self.settings.theme_name
viewer.create_initial_layers(image=True, roi=True, additional_layers=False, points=True)
viewer.show()
self.viewer_list.append(viewer)
viewer.window.qt_viewer.destroyed.connect(lambda _x: self.close_viewer(viewer))

def additional_layers_show(self, with_channels=False):
if not self.settings.additional_layers:
QMessageBox().information(self, "No data", "Last executed algorithm does not provide additional data")
return
viewer = Viewer(title="Additional output", settings=self.settings, partseg_viewer_name=self.channel_info)
viewer = Viewer(
title="Additional output", settings=self.settings, partseg_viewer_name=self.channel_info, show=False
)
viewer.theme = self.settings.theme_name
viewer.create_initial_layers(image=with_channels, roi=False, additional_layers=True, points=False)
viewer.show()
self.viewer_list.append(viewer)
viewer.window.qt_viewer.destroyed.connect(lambda _x: self.close_viewer(viewer))

Expand Down
13 changes: 7 additions & 6 deletions package/tests/test_PartSeg/test_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class TestNapariViewer:
def test_base(self, image, analysis_segmentation2, tmp_path):
settings = BaseSettings(tmp_path)
settings.image = image
viewer = Viewer(settings, "")
viewer = Viewer(settings, "", show=False)
viewer.create_initial_layers(True, True, True, True)
assert len(viewer.layers) == 2
viewer.create_initial_layers(True, True, True, True)
Expand All @@ -92,7 +92,7 @@ def test_base(self, image, analysis_segmentation2, tmp_path):
def test_points(self, image, tmp_path, qtbot):
settings = BaseSettings(tmp_path)
settings.image = image
viewer = Viewer(settings, "")
viewer = Viewer(settings, "", show=False)
viewer.create_initial_layers(True, True, True, True)
assert len(viewer.layers) == 2
points = np.array([[0, 1, 1, 1], [0, 7, 10, 10]])
Expand All @@ -113,7 +113,7 @@ def test_points(self, image, tmp_path, qtbot):
def test_image(self, image, image2, tmp_path, qtbot):
settings = BaseSettings(tmp_path)
settings.image = image
viewer = Viewer(settings, "test")
viewer = Viewer(settings, "test", show=False)
with qtbot.waitSignal(viewer._sync_widget.sync_image_chk.stateChanged):
viewer._sync_widget.sync_image_chk.setChecked(True)
assert len(viewer.layers) == 2
Expand All @@ -125,7 +125,7 @@ def test_image(self, image, image2, tmp_path, qtbot):
def test_roi(self, image, tmp_path, qtbot):
settings = BaseSettings(tmp_path)
settings.image = image
viewer = Viewer(settings, "test")
viewer = Viewer(settings, "test", show=False)
viewer._sync_widget.sync_image()
assert len(viewer.layers) == 2
viewer._sync_widget.sync_ROI_chk.setChecked(True)
Expand All @@ -135,10 +135,11 @@ def test_roi(self, image, tmp_path, qtbot):
assert len(viewer.layers) == 4
viewer.close()

def test_additional(self, image, tmp_path, qtbot):
@pytest.mark.usefixtures("qtbot")
def test_additional(self, image, tmp_path):
settings = BaseSettings(tmp_path)
settings.image = image
viewer = Viewer(settings, "test")
viewer = Viewer(settings, "test", show=False)
viewer._sync_widget.sync_image()
assert len(viewer.layers) == 2
settings._additional_layers = {
Expand Down
18 changes: 13 additions & 5 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# and then run "tox" from this directory.

[tox]
envlist = py{39,310,311,312,313}-{PyQt5,PySide2,PyQt6,PySide6}-all, py{39,310,311,312,313}-{PyQt5,PyQt6}-napari_{419,54,repo}, py{39,310}-PySide2-napari_{419,54,repo}
envlist = py{39,310,311,312,313}-{PyQt5,PySide2,PyQt6,PySide6}-all, py{310,311,312,313}-{PyQt5,PyQt6}-napari_repo,py{39,310,311,312,313}-{PyQt5,PyQt6,PySide2}-napari_{419,54}, py{312,313}-PySide6-napari_{419,54,repo}
toxworkdir=/tmp/tox

[gh-actions]
Expand Down Expand Up @@ -71,15 +71,23 @@ deps=
pytest-json-report
lxml_html_clean

[testenv:py{39,310,311,312,313}-{PyQt5,PySide2,PyQt6,PySide6}-napari_{419,54,repo}]

[testenv:py{39,310,311,312,313}-{PyQt5,PySide2,PyQt6,PySide6}-napari_{419,54}]
deps =
{[testenv]deps}
napari_419: napari==0.4.19.post1
napari_54: napari==0.5.4
napari_repo: git+https://github.com/napari/napari.git
commands =
!napari_repo: python -m pytest -v package/tests/test_PartSeg/test_napari_widgets.py --json-report --json-report-file={toxinidir}/report-{envname}-{sys_platform}.json {posargs}
napari_repo: python -m pytest package/tests --json-report --json-report-file={toxinidir}/report-{envname}-{sys_platform}.json {posargs}
python -m pytest -v --json-report --json-report-file={toxinidir}/report-{envname}-{sys_platform}.json {posargs:package/tests/test_PartSeg/test_napari_widgets.py}


[testenv:py{310,311,312,313}-{PyQt5,PyQt6,PySide6}-napari_repo]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question (testing): The napari_repo env drops PySide2 and py39; confirm this reduction in matrix is intentional.

Previously, napari_repo ran on py{39,310,311,312,313}-{PyQt5,PySide2,PyQt6,PySide6}; now it’s only py{310,311,312,313}-{PyQt5,PyQt6,PySide6}. Unless this is due to an intentional upstream drop of py39/PySide2 support, consider keeping those combos so we don’t silently lose coverage for configurations users may still depend on.

deps =
{[testenv]deps}
git+https://github.com/napari/napari.git
commands =
python -m pytest --json-report --json-report-file={toxinidir}/report-{envname}-{sys_platform}.json {posargs:package/tests}


[testenv:py{39,310,311,312,313}-PyQt5-coverage]
deps =
Expand Down
Loading