Skip to content

chore: Drop napari<0.6 and pydantic<2#1406

Merged
Czaki merged 11 commits into
developfrom
drop_old_napari_and_pydantic
Jun 9, 2026
Merged

chore: Drop napari<0.6 and pydantic<2#1406
Czaki merged 11 commits into
developfrom
drop_old_napari_and_pydantic

Conversation

@Czaki

@Czaki Czaki commented Jun 6, 2026

Copy link
Copy Markdown
Collaborator

Summary by Sourcery

Raise the supported napari and pydantic baselines, removing compatibility paths for older napari versions and simplifying configuration and tests accordingly.

Enhancements:

  • Streamline runtime and GUI code to rely on the newer napari API for colormaps, layer selection, cursor coordinates, theming, and settings paths.
  • Adjust configuration import and backup handling to use updated napari settings behavior without legacy load hooks.
  • Introduce a pydantic v2-compatible config model_copy implementation while keeping the existing copy interface.

Build:

  • Update core dependency versions in pyproject, including napari, pydantic, QtPy, numpy, scipy, psygnal, superqt, tifffile, and vispy.

CI:

  • Simplify GitHub Actions test matrix and constraints handling by dropping pydantic v1-specific variants and pydantic-dependent constraint files.
  • Update base test workflow and napari widget workflow to stop passing a pydantic selector and to test only against newer napari versions using unified constraints files.

Tests:

  • Simplify napari-related tests by removing conditionals for old napari versions and expecting the new colormap and viewer behaviors.
  • Update tox environments to target napari 0.6.2 and 0.7.0 instead of older 0.4.x/0.5.x series and align napari widget test workflow with these versions.

Chores:

  • Remove obsolete constraints files for pydantic 1.x and clean up legacy napari compatibility helpers and constants across the codebase.

Summary by CodeRabbit

  • Chores

    • Simplified CI and test workflows, removed legacy constraint artifacts, and raised several runtime dependency minimums.
  • Bug Fixes

    • Removed many napari-version conditionals; unified viewer theming, colormap handling, and settings save/load behavior.
    • Updated code to align with Pydantic v2 model-copy/validation patterns.
  • Tests

    • Updated tests to reflect unified napari behavior and new Pydantic model-copy semantics.

@Czaki Czaki added this to the 0.17.0 milestone Jun 6, 2026
@sourcery-ai

sourcery-ai Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Drops support for older napari (<0.6.x-ish) and pydantic 1.x, simplifying napari-version conditionals, updating runtime/test dependencies and CI/tox matrices to target newer napari/Qt/Pydantic stacks, and aligning internal utilities and settings handling with the new APIs.

Flow diagram for updated napari plugin settings path resolution

flowchart TD
    A["get_settings called"] --> B{"_SETTINGS is None?"}
    B -- No --> G["Return existing _SETTINGS"]
    B -- Yes --> C["napari_settings = napari_get_settings"]
    C --> D{"napari_settings.config_path is not None?"}
    D -- Yes --> E["save_path = dirname(napari_settings.config_path)"]
    D -- No --> F["save_path = user_config_dir(napari, False)"]
    E --> H["_SETTINGS = PartSegNapariSettings(join(save_path, PartSeg_napari_plugins))"]
    F --> H
    H --> I["_SETTINGS.load"]
    I --> G["Return _SETTINGS"]
Loading

File-Level Changes

Change Details Files
Simplify napari-dependent widget/image tests to assume modern napari APIs and behaviors.
  • Remove version checks for napari 0.4.x/0.5.x in napari widget tests.
  • Always assert colormap types using CyclicLabelColormap and DirectLabelColormap.
  • Fix EXPECTED_RANGE and get_color_dict to single modern behavior and always clear QtViewer._instances in teardown.
package/tests/test_PartSeg/test_napari_widgets.py
package/tests/test_PartSeg/test_napari_image_view.py
package/tests/test_PartSeg/test_viewer.py
Update napari-based GUI code to rely on current napari/Qt APIs and simplify compatibility branches.
  • Always set canvas.background_color_override without hasattr checks and remove scale bar color customization.
  • Assume viewer.layers.selection/ cursor.position / world_to_data exist and return coordinates directly with type hints.
  • Simplify error-report theming to always use get_theme(get_settings().appearance.theme).
  • Align napari plugin settings path resolution with new napari settings API and use user_config_dir fallback.
  • Remove unused napari version gating in labels_control.
package/PartSeg/common_gui/napari_image_view.py
package/PartSeg/common_gui/error_report.py
package/PartSeg/plugins/napari_widgets/_settings.py
package/PartSeg/plugins/napari_widgets/lables_control.py
Raise core dependency versions and drop pydantic<2 support.
  • Bump QtPy, numpy, psygnal, scipy, superqt, tifffile, vispy minimum versions.
  • Split napari dependency into version ranges for <3.14 and >=3.14 Python, targeting 0.6.2 and 0.7.0 respectively.
  • Require pydantic>=2.2.0 and adjust base Config class to use model_fields and add a pydantic-v2-compatible model_copy wrapper with validation semantics aligned to the existing copy method.
pyproject.toml
package/PartSegCore/utils.py
Simplify napari IO and backup handling to target only modern napari behavior.
  • Make add_color always return a colormap using adjust_color(image.get_colors()[idx]).
  • Remove legacy napari settings load/_load calls in backup import; simply obtain settings via napari_get_settings.
  • Update QMessageBox usage to use StandardButton enums consistently and annotate base_folder type.
package/PartSeg/plugins/napari_io/loader.py
package/PartSeg/common_backend/load_backup.py
Update tox, constraints, and GitHub Actions workflows to remove pydantic-1 tracks and target newer napari versions.
  • Change tox envs from napari_419/54 to napari_62 and adjust corresponding deps; update GH matrix NAPARI mapping.
  • Run napari widget workflow only against napari 0.6.2 and simplify qt_backend matrix values.
  • Remove pydantic-related workflow inputs, matrix entries, and constraints for pydantic_1; stop generating *_pydantic_1 constraint files.
  • Update workflow constraint file selection to drop pydantic suffix and always use constraints_py{python_version}.txt.
tox.ini
.github/workflows/base_test_workflow.yml
.github/workflows/test_napari_widgets.yml
.github/workflows/tests.yml
.github/workflows/upgrade-dependencies.yml
requirements/constraints_py3.10_pydantic_1.txt
requirements/constraints_py3.11_pydantic_1.txt
requirements/constraints_py3.12_pydantic_1.txt
requirements/constraints_py3.13_pydantic_1.txt
package/tests/test_PartSeg/test_napari_io.py

Possibly linked issues

  • #test-bot napari repos test fail: The PR modernizes napari integration and CI workflows, likely addressing the failing napari repo workflow tests described.
  • #test-bot: PR adjusts napari versions, tox envs, and CI workflows likely fixing the failing napari repo workflow mentioned.
  • #test-bot: PR updates napari versions, tox envs, and workflows, likely fixing the reported napari repo workflow failure.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c91f4e88-5408-4b84-be80-e43ad98c1933

📥 Commits

Reviewing files that changed from the base of the PR and between fa11239 and d4d9132.

📒 Files selected for processing (3)
  • package/PartSeg/plugins/napari_widgets/_settings.py
  • package/PartSegImage/channel_class.py
  • package/tests/test_PartSegImage/test_channel_class.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • package/PartSeg/plugins/napari_widgets/_settings.py
  • package/PartSegImage/channel_class.py
  • package/tests/test_PartSegImage/test_channel_class.py

📝 Walkthrough

Walkthrough

Removes Pydantic-v1 CI variants and napari-version branches, updates dependency pins and CI/tox matrices, migrates model-copy and Pydantic hooks to v2, simplifies napari runtime code (themes, colormaps, active layer/coordinates), and updates tests to match new APIs.

Changes

Drop Pydantic v1 variants and older napari version support

Layer / File(s) Summary
Dependency declarations and CI workflow configuration
pyproject.toml, .github/workflows/base_test_workflow.yml, .github/workflows/test_napari_widgets.yml, .github/workflows/tests.yml, .github/workflows/upgrade-dependencies.yml, tox.ini, .github/project_dict.pws
Updates dependency minimums (e.g., QtPy ≥2.3.1, napari pins by Python version, pydantic ≥2.2.0), removes the pydantic reusable-workflow input and pydantic-specific constraint generation, and retargets GitHub Actions/tox napari matrix to napari62/napari70.
Pydantic v2 compatibility & settings
package/PartSegCore/utils.py, package/PartSegCore/analysis/measurement_base.py, package/PartSegCore/mask_create.py, package/PartSeg/common_gui/algorithms_description.py, package/PartSeg/plugins/napari_widgets/_settings.py, package/PartSeg/common_backend/load_backup.py
Adds BaseModel.model_copy(validate=...), switches copy() → model_copy() in core code/tests, and changes napari settings save-path derivation to prefer config_path dirname with platformdirs fallback.
Napari API simplification and version-check removal
package/PartSeg/common_gui/napari_image_view.py, package/PartSeg/common_gui/error_report.py, package/PartSeg/plugins/napari_io/loader.py, package/PartSeg/plugins/napari_widgets/lables_control.py, package/PartSegImage/channel_class.py
Removes napari-version detection and conditional branches; ImageView now unconditionally sets canvas background and uses selection.active, ErrorDialog calls get_theme(...) unconditionally, loader always exposes colormap data, label widget/version constants removed, Channel updated with Pydantic v2 hooks and updated JSON schema behavior.
Test updates for napari and Pydantic assumptions
package/tests/test_PartSeg/test_napari_image_view.py, package/tests/test_PartSeg/test_napari_io.py, package/tests/test_PartSeg/test_napari_widgets.py, package/tests/test_PartSeg/test_viewer.py, other tests under package/tests/*
Removes napari-version gates and related imports, fixes colormap attribute expectations, updates JSON-schema assertions to use Model.model_json_schema(), replaces copy() with model_copy() in tests, and simplifies fixture teardown.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

skip check PR title

Poem

"A rabbit fluffs its checklist bright,
hopping through CI in the night,
Pydantic v2 and napari new,
tests aligned and workflows too,
carrots for merged PRs — delight!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: Drop napari<0.6 and pydantic<2' is concise, specific, and accurately summarizes the main objective of the PR—raising version baselines for napari and pydantic and removing associated legacy compatibility code.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch drop_old_napari_and_pydantic

Warning

Review ran into problems

🔥 Problems

Stopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a @coderabbit review after the pipeline has finished.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Czaki Czaki changed the title Drop napari<6 and pydantic<2 chore:Drop napari<6 and pydantic<2 Jun 6, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • In .github/workflows/test_napari_widgets.yml the qt_backend matrix is set to a single string "PyQt5, PySide2" instead of two separate entries (e.g. ["PyQt5", "PySide2"]), which will prevent the matrix from expanding as intended.
  • In test_napari_image_view.image_view, QtViewer._instances.clear() is now called unconditionally; consider keeping a defensive check (e.g. hasattr(QtViewer, "_instances")) in case this private attribute changes or is removed in future napari versions.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `.github/workflows/test_napari_widgets.yml` the `qt_backend` matrix is set to a single string `"PyQt5, PySide2"` instead of two separate entries (e.g. `["PyQt5", "PySide2"]`), which will prevent the matrix from expanding as intended.
- In `test_napari_image_view.image_view`, `QtViewer._instances.clear()` is now called unconditionally; consider keeping a defensive check (e.g. `hasattr(QtViewer, "_instances")`) in case this private attribute changes or is removed in future napari versions.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@Czaki Czaki changed the title chore:Drop napari<6 and pydantic<2 chore: Drop napari<6 and pydantic<2 Jun 6, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/base_test_workflow.yml (1)

1-45: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical workflow input contract break.

The pydantic workflow input has been removed from this reusable workflow's inputs declaration, but the caller workflow .github/workflows/tests.yml (line 88) still passes pydantic: ${{ matrix.pydantic }} when invoking this workflow. This will cause a workflow validation error at runtime.

Either:

  1. Add the pydantic input back to this workflow's on.workflow_call.inputs section (even if unused), or
  2. Update all caller workflows to stop passing the pydantic parameter.

Based on context snippet 1 from .github/workflows/tests.yml:83-90.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/base_test_workflow.yml around lines 1 - 45, The workflow's
inputs removed the pydantic parameter but callers still pass pydantic, causing a
validation error; restore a pydantic input in the on.workflow_call.inputs block
by adding an entry named pydantic (e.g., required: false, type: string, default:
""), or if you prefer boolean use type: boolean and default: false — ensure the
input name is exactly "pydantic" so callers (e.g., the invocation in tests.yml
using matrix.pydantic) validate without errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test_napari_widgets.yml:
- Line 40: The qt_backend matrix currently lists a single string "PyQt5,
PySide2" instead of two separate entries; update the workflow matrix entry for
qt_backend to be a proper YAML array of two elements (e.g., ["PyQt5",
"PySide2"]) so the job runs once per backend; locate and edit the qt_backend key
in the matrix section to replace the comma-separated single string with separate
quoted strings.

---

Outside diff comments:
In @.github/workflows/base_test_workflow.yml:
- Around line 1-45: The workflow's inputs removed the pydantic parameter but
callers still pass pydantic, causing a validation error; restore a pydantic
input in the on.workflow_call.inputs block by adding an entry named pydantic
(e.g., required: false, type: string, default: ""), or if you prefer boolean use
type: boolean and default: false — ensure the input name is exactly "pydantic"
so callers (e.g., the invocation in tests.yml using matrix.pydantic) validate
without errors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 43315f17-e549-4568-8ec8-f8f547de9ad1

📥 Commits

Reviewing files that changed from the base of the PR and between acb30dd and 9effe25.

📒 Files selected for processing (22)
  • .github/workflows/base_test_workflow.yml
  • .github/workflows/test_napari_widgets.yml
  • .github/workflows/tests.yml
  • .github/workflows/upgrade-dependencies.yml
  • package/PartSeg/common_backend/load_backup.py
  • package/PartSeg/common_gui/error_report.py
  • package/PartSeg/common_gui/napari_image_view.py
  • package/PartSeg/plugins/napari_io/loader.py
  • package/PartSeg/plugins/napari_widgets/_settings.py
  • package/PartSeg/plugins/napari_widgets/lables_control.py
  • package/PartSegCore/utils.py
  • package/tests/test_PartSeg/test_napari_image_view.py
  • package/tests/test_PartSeg/test_napari_io.py
  • package/tests/test_PartSeg/test_napari_widgets.py
  • package/tests/test_PartSeg/test_viewer.py
  • pyproject.toml
  • requirements/constraints_py3.10_pydantic_1.txt
  • requirements/constraints_py3.11_pydantic_1.txt
  • requirements/constraints_py3.12_pydantic_1.txt
  • requirements/constraints_py3.13_pydantic_1.txt
  • requirements/constraints_py3.14_pydantic_1.txt
  • tox.ini
💤 Files with no reviewable changes (8)
  • requirements/constraints_py3.10_pydantic_1.txt
  • package/PartSeg/plugins/napari_widgets/lables_control.py
  • requirements/constraints_py3.13_pydantic_1.txt
  • requirements/constraints_py3.11_pydantic_1.txt
  • package/tests/test_PartSeg/test_napari_io.py
  • .github/workflows/upgrade-dependencies.yml
  • requirements/constraints_py3.12_pydantic_1.txt
  • .github/workflows/tests.yml

Comment thread .github/workflows/test_napari_widgets.yml Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
package/tests/test_PartSeg/test_napari_image_view.py (1)

67-67: ⚠️ Potential issue | 🟠 Major

Fix napari teardown: QtViewer._instances may not exist in napari 0.6.2
In napari 0.6.2, _instances is not defined on napari.qt.QtViewer (instance tracking is handled by Viewer / _QtMainWindow). QtViewer._instances.clear() can therefore raise AttributeError during fixture teardown and fail all tests using this fixture.

🛡️ Defensive alternative
-    QtViewer._instances.clear()
+    if hasattr(QtViewer, "_instances"):
+        QtViewer._instances.clear()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package/tests/test_PartSeg/test_napari_image_view.py` at line 67, The
teardown calls QtViewer._instances.clear() which raises AttributeError in napari
0.6.2 because QtViewer may not have _instances; update the fixture to
defensively clear instances only if the attribute exists—check hasattr(QtViewer,
"_instances") or wrap the clear call in a try/except AttributeError around
QtViewer._instances.clear() so tests don't fail when napari.qt.QtViewer lacks
_instances.
🧹 Nitpick comments (1)
.github/workflows/test_napari_widgets.yml (1)

34-48: Consider adding an explicit permissions block to the workflow.

The static analysis tool flagged that this workflow uses default permissions because no permissions: block is defined at the workflow level. For security hardening, consider adding an explicit permissions block that grants only the minimum required permissions for the workflow's operations.

Example permissions block

Add at the workflow level (after the concurrency: block):

permissions:
  contents: read
  pull-requests: read

Adjust the specific permissions based on what the workflow actually needs to access.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test_napari_widgets.yml around lines 34 - 48, Add an
explicit top-level permissions block to the workflow to avoid default broad
permissions; in the workflow that defines the "test-qt5" job add a permissions:
stanza (placed after the concurrency: block) and grant only the minimal scopes
needed (for example contents: read and pull-requests: read) and adjust as
required for any additional actions the job uses so the workflow no longer
relies on default permissions.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@package/tests/test_PartSeg/test_napari_image_view.py`:
- Line 67: The teardown calls QtViewer._instances.clear() which raises
AttributeError in napari 0.6.2 because QtViewer may not have _instances; update
the fixture to defensively clear instances only if the attribute exists—check
hasattr(QtViewer, "_instances") or wrap the clear call in a try/except
AttributeError around QtViewer._instances.clear() so tests don't fail when
napari.qt.QtViewer lacks _instances.

---

Nitpick comments:
In @.github/workflows/test_napari_widgets.yml:
- Around line 34-48: Add an explicit top-level permissions block to the workflow
to avoid default broad permissions; in the workflow that defines the "test-qt5"
job add a permissions: stanza (placed after the concurrency: block) and grant
only the minimal scopes needed (for example contents: read and pull-requests:
read) and adjust as required for any additional actions the job uses so the
workflow no longer relies on default permissions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8e5bdb6b-fe70-4dc2-9d44-193ac5b25946

📥 Commits

Reviewing files that changed from the base of the PR and between 9effe25 and 561e528.

📒 Files selected for processing (4)
  • .github/project_dict.pws
  • .github/workflows/test_napari_widgets.yml
  • .github/workflows/tests.yml
  • package/tests/test_PartSeg/test_napari_image_view.py
💤 Files with no reviewable changes (1)
  • .github/workflows/tests.yml
✅ Files skipped from review due to trivial changes (1)
  • .github/project_dict.pws

@Czaki Czaki changed the title chore: Drop napari<6 and pydantic<2 chore: Drop napari<0.6 and pydantic<2 Jun 7, 2026
@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.29630% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.56%. Comparing base (2f9db69) to head (d4d9132).
⚠️ Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
package/PartSegCore/utils.py 85.71% 1 Missing ⚠️
package/PartSegImage/channel_class.py 91.66% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1406      +/-   ##
===========================================
- Coverage    92.72%   92.56%   -0.16%     
===========================================
  Files          211      211              
  Lines        33273    33224      -49     
===========================================
- Hits         30851    30754      -97     
- Misses        2422     2470      +48     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Czaki

Czaki commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@package/PartSegImage/channel_class.py`:
- Around line 11-13: The JSON schema claims Channel accepts a non-empty string
but core validation allows empty strings; update the Channel validation to
enforce the non-empty string contract by modifying the pydantic core schema
returned from Channel.__get_pydantic_core_schema__ to use
core_schema.str_schema(min_length=1) (and mirror this constraint in check_type
so it raises for ""), and ensure Channel(...) construction still raises a
ValueError for empty strings with a clear message; also keep
__get_pydantic_json_schema__ description consistent with the tightened core
schema.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 00a8ff77-35b0-4931-999a-f107b62bfc2a

📥 Commits

Reviewing files that changed from the base of the PR and between fa11239 and fbd12b9.

📒 Files selected for processing (2)
  • package/PartSeg/plugins/napari_widgets/_settings.py
  • package/PartSegImage/channel_class.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • package/PartSeg/plugins/napari_widgets/_settings.py

Comment thread package/PartSegImage/channel_class.py
@sonarqubecloud

sonarqubecloud Bot commented Jun 9, 2026

Copy link
Copy Markdown

@Czaki

Czaki commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/4DNucleome/PartSeg/issues/comments/4640787630","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- review_stack_entry_start -->\n\n[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/4DNucleome/PartSeg/pull/1406?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)\n\n<!-- review_stack_entry_end -->\n<!-- This is an auto-generated comment: review in progress by coderabbit.ai -->\n\n> [!NOTE]\n> Currently processing new changes in this PR. This may take a few minutes, please wait...\n> \n> <details>\n> <summary>⚙️ Run configuration</summary>\n> \n> **Configuration used**: Path: .coderabbit.yaml\n> \n> **Review profile**: CHILL\n> \n> **Plan**: Pro\n> \n> **Run ID**: `c91f4e88-5408-4b84-be80-e43ad98c1933`\n> \n> </details>\n> \n> <details>\n> <summary>📥 Commits</summary>\n> \n> Reviewing files that changed from the base of the PR and between fa1123913415a5ecc151ba3cf68f76b5a5a8db4f and d4d91320c9a16e88cfd9cbba714862c77f764807.\n> \n> </details>\n> \n> <details>\n> <summary>📒 Files selected for processing (3)</summary>\n> \n> * `package/PartSeg/plugins/napari_widgets/_settings.py`\n> * `package/PartSegImage/channel_class.py`\n> * `package/tests/test_PartSegImage/test_channel_class.py`\n> \n> </details>\n> \n> ```ascii\n>  ______________________________________________________________________\n> < Race conditions: you *caught* one. Unfortunately you released three. >\n>  ----------------------------------------------------------------------\n>   \\\n>    \\   (\\__/)\n>        (•ㅅ•)\n>        /   づ\n> ```\n\n<!-- end of auto-generated comment: review in progress by coderabbit.ai -->\n\n<!-- This is an auto-generated comment: review paused by coderabbit.ai -->\n\n> [!NOTE]\n> ## Reviews paused\n> \n> It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the `reviews.auto_review.auto_pause_after_reviewed_commits` setting.\n> \n> Use the following commands to manage reviews:\n> - `@coderabbitai resume` to resume automatic reviews.\n> - `@coderabbitai review` to trigger a single review.\n> \n> Use the checkboxes below for quick actions:\n> - [ ] <!-- {\"checkboxId\": \"7f6cc2e2-2e4e-497a-8c31-c9e4573e93d1\"} --> ▶️ Resume reviews\n> - [ ] <!-- {\"checkboxId\": \"e9bb8d72-00e8-4f67-9cb2-caf3b22574fe\"} --> 🔍 Trigger review\n\n<!-- end of auto-generated comment: review paused by coderabbit.ai -->\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nRemoves Pydantic-v1 CI variants and napari-version branches, raises GUI/runtime dependency minimums, adds Pydantic-v2-compatible BaseModel behavior, updates napari-related runtime code and tests to use newer APIs, and rewires CI/tox workflows and constraint generation.\n\n## Changes\n\n**Drop Pydantic v1 variants and older napari version support**\n\n|Layer / File(s)|Summary|\n|---|---|\n|**Dependency declarations and CI workflow configuration** <br> `pyproject.toml`, `.github/workflows/base_test_workflow.yml`, `.github/workflows/test_napari_widgets.yml`, `.github/workflows/tests.yml`, `.github/workflows/upgrade-dependencies.yml`, `tox.ini`, `.github/project_dict.pws`|Updates dependency minimums (e.g., QtPy ≥2.3.1, napari pins by Python version, pydantic ≥2.2.0), removes the `pydantic` reusable-workflow input and pydantic-specific constraint generation, and retargets GitHub Actions/tox napari matrix to napari62/napari70.|\n|**Pydantic v2 compatibility & settings** <br> `package/PartSegCore/utils.py`, `package/PartSegCore/analysis/measurement_base.py`, `package/PartSegCore/mask_create.py`, `package/PartSeg/common_gui/algorithms_description.py`, `package/PartSeg/plugins/napari_widgets/_settings.py`, `package/PartSeg/common_backend/load_backup.py`|Adds BaseModel.model_copy(validate=...), switches copy() → model_copy() in core code/tests, and changes napari settings save-path derivation to prefer config_path dirname with platformdirs fallback.|\n|**Napari API simplification and version-check removal** <br> `package/PartSeg/common_gui/napari_image_view.py`, `package/PartSeg/common_gui/error_report.py`, `package/PartSeg/plugins/napari_io/loader.py`, `package/PartSeg/plugins/napari_widgets/lables_control.py`, `package/PartSegImage/channel_class.py`|Removes napari-version detection and conditional branches; ImageView now unconditionally sets canvas background and uses selection.active, ErrorDialog calls get_theme(...) unconditionally, loader always exposes colormap data, label widget/version constants removed, Channel updated with Pydantic v2 hooks and updated JSON schema behavior.|\n|**Test updates for napari and Pydantic assumptions** <br> `package/tests/test_PartSeg/test_napari_image_view.py`, `package/tests/test_PartSeg/test_napari_io.py`, `package/tests/test_PartSeg/test_napari_widgets.py`, `package/tests/test_PartSeg/test_viewer.py`, other tests under `package/tests/*`|Removes napari-version gates and related imports, fixes colormap attribute expectations, updates JSON-schema assertions to use Model.model_json_schema(), replaces copy() with model_copy() in tests, and simplifies fixture teardown.|\n\nEstimated code review effort\n\n🎯 4 (Complex) | ⏱️ ~45 minutes\n\nPossibly related PRs\n\n- [4DNucleome/PartSeg#1223](https://github.com/4DNucleome/PartSeg/pull/1223): Overlaps edits to autogenerated constraint files and dependency pins.  \n- [4DNucleome/PartSeg#1228](https://github.com/4DNucleome/PartSeg/pull/1228): Related changes to napari loader/colormap handling.  \n- [4DNucleome/PartSeg#1116](https://github.com/4DNucleome/PartSeg/pull/1116): Prior napari compatibility changes touching the same modules and tests.\n\nSuggested labels\n\n`skip check PR title`\n\nPoem\n\n> \"A rabbit fluffs its checklist bright,  \n> hopping through CI in the night,  \n> Pydantic v2 and napari new,  \n> tests aligned and workflows too,  \n> carrots for merged PRs — delight!\"\n\n</details>\n\n<!-- walkthrough_end -->\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 4 | ❌ 1</summary>\n\n### ❌ Failed checks (1 warning)\n\n|     Check name     | Status     | Explanation                                                                          | Resolution                                                                         |\n| :----------------: | :--------- | :----------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------- |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 5.41% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |\n\n<details>\n<summary>✅ Passed checks (4 passed)</summary>\n\n|         Check name         | Status   | Explanation                                                                                                                                                                     |\n| :------------------------: | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n|      Description Check     | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled.                                                                                                                     |\n|         Title check        | ✅ Passed | The title clearly and concisely summarizes the main objectives: dropping support for older napari (<0.6) and pydantic (<2) versions and removing associated compatibility code. |\n|     Linked Issues check    | ✅ Passed | Check skipped because no linked issues were found for this pull request.                                                                                                        |\n| Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request.                                                                                                        |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n<details>\n<summary>📝 Generate docstrings</summary>\n\n- [ ] <!-- {\"checkboxId\": \"7962f53c-55bc-4827-bfbf-6a18da830691\"} --> Create stacked PR\n- [ ] <!-- {\"checkboxId\": \"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98\"} --> Commit on current branch\n\n</details>\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-4657704875\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-4657704875\"} -->   Commit unit tests in branch `drop_old_napari_and_pydantic`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=4DNucleome/PartSeg&utm_content=1406)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n<!-- internal state start -->\n\n\n<!-- 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 -->\n\n<!-- internal state end -->"},"request":{"retryCount":3,"signal":{},"retries":3,"retryAfter":16}}}

@Czaki Czaki merged commit 8c1e0f0 into develop Jun 9, 2026
65 of 67 checks passed
@Czaki Czaki deleted the drop_old_napari_and_pydantic branch June 9, 2026 08:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant