chore: Add Python 3.13 to supported versions#1327
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideThis PR adds support for Python 3.13 by updating the CI test matrices in GitHub Actions and updating project metadata to reflect the new version and classifier. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
WalkthroughAdds Python 3.13 across CI, tox, dependency compilation, and packaging; introduces ErrorInfo and error-preparation helpers in PartSegCore.utils, updates batch-processing to use the shared error representation, and adjusts tests to exercise the new error serialization and timeout behavior. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🧬 Code graph analysis (1)package/tests/test_PartSeg/test_sentry.py (1)
🪛 GitHub Check: Codacy Static Code Analysispackage/tests/test_PartSeg/test_sentry.py[notice] 51-51: package/tests/test_PartSeg/test_sentry.py#L51 ⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
🔇 Additional comments (2)
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. Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #1327 +/- ##
===========================================
- Coverage 93.17% 93.15% -0.02%
===========================================
Files 210 210
Lines 33232 33251 +19
===========================================
+ Hits 30964 30976 +12
- Misses 2268 2275 +7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
tox.ini (1)
105-105: Minor: Fix inconsistent spacing in testenv key.Line 105 has inconsistent spacing between key components:
PyQt5, PySide2(space after PyQt5 comma) vs.PySide2,PyQt6(no space).Apply this formatting fix:
-[testenv:py{39,310,311,312,313}-{PyQt5, PySide2,PyQt6,PySide6}-azure] +[testenv:py{39,310,311,312,313}-{PyQt5,PySide2,PyQt6,PySide6}-azure]
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.github/workflows/tests.yml(2 hunks).github/workflows/upgrade-dependencies.yml(1 hunks)pyproject.toml(3 hunks)requirements/constraints_py3.13.txt(1 hunks)tox.ini(5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-08T20:57:48.839Z
Learnt from: Czaki
PR: 4DNucleome/PartSeg#1117
File: .github/workflows/make_release.yml:46-47
Timestamp: 2024-10-08T20:57:48.839Z
Learning: The `requirements/constraints_py3.10.txt` file is used to pin the versions of dependencies in the `pip install` command for the PartSeg project.
Applied to files:
requirements/constraints_py3.13.txt
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
- GitHub Check: Base py3.11 / windows-latest py 3.11 latest PyQt5
- GitHub Check: 4DNucleome.PartSeg (Tests_other test windows)
- GitHub Check: 4DNucleome.PartSeg (Tests_other test macos)
- GitHub Check: 4DNucleome.PartSeg (Tests_linux test_linux)
- GitHub Check: repo py3.12
- GitHub Check: repo py3.10
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller windows)
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller macos_arm)
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller macos)
- GitHub Check: 4DNucleome.PartSeg (Builds sdist)
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller_linux)
- GitHub Check: 4DNucleome.PartSeg (Documentation_check help)
- GitHub Check: 4DNucleome.PartSeg (GetTestData linux)
- GitHub Check: 4DNucleome.PartSeg (manifest_check manifest_check)
- GitHub Check: 4DNucleome.PartSeg (Documentation_check Notebook_check)
- GitHub Check: 4DNucleome.PartSeg (formatting_check check_formating)
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: Sourcery review
🔇 Additional comments (7)
.github/workflows/upgrade-dependencies.yml (1)
38-41: Python 3.13 addition looks good.The loop correctly iterates over Python 3.13 alongside existing versions, and the uv pip compile commands will generate the corresponding constraints file.
.github/workflows/tests.yml (1)
57-57: Python 3.13 test matrix expansion is consistent.Both test job matrices (base-test and base-test-main) correctly include Python 3.13, aligned with the PR objective.
Also applies to: 100-100
tox.ini (1)
7-7: Python 3.13 tox environment setup is consistent and complete.The envlist, gh-actions mapping, and testenv definitions properly extend support to Python 3.13 across all variations (PyQt5, PySide2, PyQt6, PySide6, napari versions, and coverage/azure/minimal configurations).
Also applies to: 16-16, 74-74, 84-84
requirements/constraints_py3.13.txt (1)
1-5: Autogenerated constraints file is properly formatted.The constraints file follows the standard format with proper dependency tracking via comments. Generated command and metadata are clearly documented at the top.
pyproject.toml (3)
8-8: Version bump discrepancy between PR objective and code.The PR objective states the fallback_version should be bumped to
0.16.4dev0, but the code shows0.16.5dev0. Please confirm which value is correct.
26-26: Python 3.13 classifier is correctly added.The classifier follows the established pattern for other Python versions.
139-139: Verify napari dependency change rationale.Line 139 changes
napari[pyside6_experimental]>=0.5.0tonapari[pyside6]>=0.5.0. This change is not mentioned in the PR objective for Python 3.13 support. Please confirm whether this is:
- Required for Python 3.13 compatibility, or
- A separate dependency update that should be documented
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (5)
package/tests/test_PartSegCore/test_utils.py (1)
374-384: Consider adding assertions on the error data structure.The test verifies that
prepare_error_dataoutput can be queued, but only assertsitem[0] == 1. Consider adding assertions to verify the structure ofprepped_excmatches the expectedErrorInfoformat (a tuple containing the exception and serialized data).The broad
except Exception(BLE001) is appropriate here since the test intentionally catches any exception type to validateprepare_error_datahandling.item = q.get(timeout=1) assert item[0] == 1 + prepped = item[1][0] + assert isinstance(prepped, tuple) + assert len(prepped) == 2 + assert isinstance(prepped[0], ValueError)package/PartSegCore/analysis/batch_processing/parallel_backend.py (1)
280-281: Inconsistent error handling inspawn_worker.The exception handler in
spawn_worker(line 281) still uses the oldtraceback.extract_tbapproach, whileBatchWorker.calculate_task(line 235) now usesprepare_error_data. For consistency, consider updating this handler as well.except Exception as e: # pragma: no cover # pylint: disable=broad-except - result_queue.put(("-1", (-1, [(e, traceback.extract_tb(e.__traceback__))]))) + result_queue.put(("-1", (-1, [prepare_error_data(e)])))This would also allow removing the
import tracebackat line 22 if it's no longer needed elsewhere.package/PartSegCore/utils.py (3)
63-132: Callback helpers: behavior unchanged; consider minor type-hint polishThe updated
int | Nonelogic in_inspect_signatureand the use ofMethodTypeinget_callbacklook consistent with how callbacks are sliced and dispatched. For extra clarity and type-checker friendliness, you could also:
- Annotate
max_argsinget_callbackasint | None.- Annotate
methodinCallbackMethod.__init__asMethodType.This is purely cosmetic and doesn’t affect runtime behavior.
-class CallbackMethod(CallbackBase): - def __init__(self, method, max_args: int | None = None): +class CallbackMethod(CallbackBase): + def __init__(self, method: MethodType, max_args: int | None = None): @@ -def get_callback(callback: typing.Callable | MethodType, max_args=None) -> CallbackBase: +def get_callback(callback: typing.Callable | MethodType, max_args: int | None = None) -> CallbackBase:
293-405: ProfileDict: new union annotations align with usage; unifykey_pathtypes for consistencyThe updated annotations for
my_dict,update,connect,set, and_call_callbackall match the existing runtime behavior and are more expressive.getstill useskey_path: list | strwhileset/connectaccepttyping.Sequence[str] | str; functionally this already works with any iterable, but for symmetry and cleaner typing you might want to declareget’skey_pathasSequence[str] | stras well.- def get(self, key_path: list | str, default=None): + def get(self, key_path: typing.Sequence[str] | str, default=None):
466-482:napari_image_reprimplementation is fine but now duplicated across modulesThe new
napari_image_repr(image: Image) -> strmatches the implementation shown inpackage/PartSegImage/image.py(per provided snippet), which introduces duplication and a risk of future divergence. If import topology allows, consider centralizing this helper in a single place (e.g., keep it here inPartSegCore.utilsand havePartSegImage.imageimport and re-export it, or move both to a small shared napari-utility module).
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
.github/workflows/tests.yml(2 hunks).github/workflows/upgrade-dependencies.yml(1 hunks)package/PartSegCore/analysis/batch_processing/batch_backend.py(2 hunks)package/PartSegCore/analysis/batch_processing/parallel_backend.py(2 hunks)package/PartSegCore/utils.py(14 hunks)package/tests/test_PartSeg/test_sentry.py(1 hunks)package/tests/test_PartSegCore/test_analysis_batch.py(2 hunks)package/tests/test_PartSegCore/test_utils.py(3 hunks)tox.ini(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- .github/workflows/upgrade-dependencies.yml
- .github/workflows/tests.yml
- tox.ini
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: Czaki
Repo: 4DNucleome/PartSeg PR: 1307
File: examples/dilate_segmentation_mask.py:0-0
Timestamp: 2025-10-15T11:26:16.151Z
Learning: In the PartSeg project, the minimum supported numpy version is 1.22.2, with a restriction to numpy<2 for Python versions below 3.10. Features from newer numpy versions (e.g., numpy 2.3) should be avoided to maintain backward compatibility.
🧬 Code graph analysis (5)
package/tests/test_PartSegCore/test_utils.py (1)
package/PartSegCore/utils.py (1)
prepare_error_data(509-518)
package/PartSegCore/analysis/batch_processing/batch_backend.py (1)
package/PartSegCore/utils.py (1)
prepare_error_data(509-518)
package/tests/test_PartSeg/test_sentry.py (1)
package/PartSegCore/utils.py (2)
prepare_error_data(509-518)safe_repr(485-492)
package/PartSegCore/utils.py (1)
package/PartSegImage/image.py (1)
Image(198-1034)
package/tests/test_PartSegCore/test_analysis_batch.py (1)
package/PartSegCore/analysis/batch_processing/batch_backend.py (5)
CalculationManager(444-544)dump_data(764-773)kill_jobs(501-502)has_work(495-499)writing_finished(942-944)
🪛 Ruff (0.14.8)
package/tests/test_PartSegCore/test_utils.py
370-370: Avoid specifying long messages outside the exception class
(TRY003)
379-379: Do not catch blind exception: Exception
(BLE001)
package/PartSegCore/utils.py
511-511: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
512-512: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
- GitHub Check: 4DNucleome.PartSeg (Tests_other test windows)
- GitHub Check: 4DNucleome.PartSeg (Tests_other test macos)
- GitHub Check: 4DNucleome.PartSeg (Tests_linux test_linux)
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller windows)
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller macos_arm)
- GitHub Check: 4DNucleome.PartSeg (Builds sdist)
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller macos)
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller_linux)
- GitHub Check: Base py3.12 / ubuntu-24.04 py 3.12 latest PyQt5
- GitHub Check: Base py3.10 / ubuntu-24.04 py 3.10 latest PyQt5
- GitHub Check: 4DNucleome.PartSeg (Documentation_check Notebook_check)
- GitHub Check: 4DNucleome.PartSeg (manifest_check manifest_check)
- GitHub Check: 4DNucleome.PartSeg (GetTestData linux)
- GitHub Check: 4DNucleome.PartSeg (Documentation_check help)
- GitHub Check: 4DNucleome.PartSeg (formatting_check check_formating)
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: Sourcery review
🔇 Additional comments (9)
package/tests/test_PartSeg/test_sentry.py (1)
13-13: LGTM!The import relocation aligns with the refactor that moves
prepare_error_dataandsafe_reprto the centralPartSegCore.utilsmodule.package/tests/test_PartSegCore/test_utils.py (2)
3-3: LGTM!The new imports are correctly added to support the
prepare_error_datatest functionality.Also applies to: 17-17
368-371: LGTM!The helper function correctly creates a deep exception stack for testing
prepare_error_data. The static analysis hint about the long exception message (TRY003) is acceptable for test code.package/PartSegCore/analysis/batch_processing/parallel_backend.py (2)
33-33: LGTM!The import of
prepare_error_datafromPartSegCore.utilsaligns with the centralization of error handling utilities.
235-235: LGTM!The error handling now uses the centralized
prepare_error_datafunction for consistent error serialization.package/tests/test_PartSegCore/test_analysis_batch.py (2)
456-456: LGTM!Adding type hints to
wait_for_calculationimproves code clarity and IDE support.
466-474: LGTM! Improved hang detection and debugging.The enhanced error handling provides valuable diagnostic information when calculations hang:
- Dumping file writer data preserves partial results for analysis
kill_jobs()ensures proper cleanup- The detailed failure message includes work status, task count, queue state, and writing status
This will significantly aid debugging CI hang issues.
package/PartSegCore/analysis/batch_processing/batch_backend.py (2)
72-72: LGTM!The import correctly sources
ErrorInfoandprepare_error_datafrom the centralizedPartSegCore.utilsmodule, eliminating code duplication.
94-95: LGTM!The type aliases correctly use the imported
ErrorInfotype, maintaining type safety while leveraging the centralized definition.
| def pre_prepare_traceback_for_queue(exc: BaseException) -> StackSummary: | ||
| """ | ||
| Prepare exception for sending it through the multiprocessing queue. | ||
|
|
||
| :param exc: exception to prepare | ||
| :return: prepared exception | ||
| """ | ||
| traceback_list = traceback.extract_tb(exc.__traceback__) | ||
| for el in traceback_list: | ||
| if hasattr(el, "_code"): | ||
| del el._code | ||
| return traceback_list | ||
|
|
||
|
|
||
| def prepare_error_data(exception: Exception) -> ErrorInfo: | ||
| try: | ||
| from sentry_sdk.serializer import serialize # noqa: PLC0415 | ||
| from sentry_sdk.utils import event_from_exception # noqa: PLC0415 | ||
|
|
||
| event = event_from_exception(exception)[0] | ||
| event = serialize(event) | ||
| return exception, (event, pre_prepare_traceback_for_queue(exception)) | ||
| except ImportError: # pragma: no cover |
There was a problem hiding this comment.
Error serialization helpers look solid; drop or adjust unused noqa directives
The ErrorInfo alias plus pre_prepare_traceback_for_queue and prepare_error_data give a clear, queue‑friendly error payload, and the StackSummary usage looks correct. One small issue: Ruff flags the # noqa: PLC0415 comments on the inner imports as unused (RUF100, non-enabled code PLC0415).
To keep linters happy, either remove these noqa markers or convert them to tool-specific directives (e.g. # pylint: disable=import-outside-toplevel) if you still need to silence Pylint.
- from sentry_sdk.serializer import serialize # noqa: PLC0415
- from sentry_sdk.utils import event_from_exception # noqa: PLC0415
+ from sentry_sdk.serializer import serialize
+ from sentry_sdk.utils import event_from_exceptionAs per static analysis hints (Ruff RUF100).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def pre_prepare_traceback_for_queue(exc: BaseException) -> StackSummary: | |
| """ | |
| Prepare exception for sending it through the multiprocessing queue. | |
| :param exc: exception to prepare | |
| :return: prepared exception | |
| """ | |
| traceback_list = traceback.extract_tb(exc.__traceback__) | |
| for el in traceback_list: | |
| if hasattr(el, "_code"): | |
| del el._code | |
| return traceback_list | |
| def prepare_error_data(exception: Exception) -> ErrorInfo: | |
| try: | |
| from sentry_sdk.serializer import serialize # noqa: PLC0415 | |
| from sentry_sdk.utils import event_from_exception # noqa: PLC0415 | |
| event = event_from_exception(exception)[0] | |
| event = serialize(event) | |
| return exception, (event, pre_prepare_traceback_for_queue(exception)) | |
| except ImportError: # pragma: no cover | |
| def pre_prepare_traceback_for_queue(exc: BaseException) -> StackSummary: | |
| """ | |
| Prepare exception for sending it through the multiprocessing queue. | |
| :param exc: exception to prepare | |
| :return: prepared exception | |
| """ | |
| traceback_list = traceback.extract_tb(exc.__traceback__) | |
| for el in traceback_list: | |
| if hasattr(el, "_code"): | |
| del el._code | |
| return traceback_list | |
| def prepare_error_data(exception: Exception) -> ErrorInfo: | |
| try: | |
| from sentry_sdk.serializer import serialize | |
| from sentry_sdk.utils import event_from_exception | |
| event = event_from_exception(exception)[0] | |
| event = serialize(event) | |
| return exception, (event, pre_prepare_traceback_for_queue(exception)) | |
| except ImportError: # pragma: no cover |
🧰 Tools
🪛 Ruff (0.14.8)
511-511: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
512-512: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
🤖 Prompt for AI Agents
In package/PartSegCore/utils.py around lines 495 to 517, the inner imports use
unused `# noqa: PLC0415` markers which Ruff flags (RUF100); either remove those
`noqa` markers entirely (preferred) or replace them with the explicit pylint
directive `# pylint: disable=import-outside-toplevel` if you must silence an
import-outside-toplevel warning, ensuring no unused lint codes remain.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
package/PartSegCore/analysis/batch_processing/parallel_backend.py (1)
235-235: Good standardization of error payload format.Using
prepare_error_data(e)standardizes the error payload format in the worker's exception handling, ensuring consistent error serialization with sentry support.Consider updating the spawn_worker exception handler for consistency.
Line 281 in the
spawn_workerfunction still uses the old format(e, traceback.extract_tb(e.__traceback__))instead ofprepare_error_data(e). For consistency, consider updating this as well.except Exception as e: # pragma: no cover # pylint: disable=broad-except - result_queue.put(("-1", (-1, [(e, traceback.extract_tb(e.__traceback__))]))) + result_queue.put(("-1", (-1, [prepare_error_data(e)])))
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
.github/workflows/tests.yml(2 hunks).github/workflows/upgrade-dependencies.yml(1 hunks)package/PartSegCore/analysis/batch_processing/batch_backend.py(2 hunks)package/PartSegCore/analysis/batch_processing/parallel_backend.py(2 hunks)package/PartSegCore/utils.py(14 hunks)package/tests/test_PartSeg/test_sentry.py(1 hunks)package/tests/test_PartSegCore/test_analysis_batch.py(2 hunks)package/tests/test_PartSegCore/test_utils.py(3 hunks)tox.ini(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/workflows/tests.yml
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Czaki
Repo: 4DNucleome/PartSeg PR: 1307
File: examples/dilate_segmentation_mask.py:0-0
Timestamp: 2025-10-15T11:26:16.151Z
Learning: In the PartSeg project, the minimum supported numpy version is 1.22.2, with a restriction to numpy<2 for Python versions below 3.10. Features from newer numpy versions (e.g., numpy 2.3) should be avoided to maintain backward compatibility.
Learnt from: Czaki
Repo: 4DNucleome/PartSeg PR: 1206
File: package/PartSegCore/image_transforming/transform_base.py:2-2
Timestamp: 2024-10-09T13:08:00.401Z
Learning: The project supports Python 3.9+ but not 3.10+, so features introduced in Python 3.10 like the `|` operator for type annotations cannot be used.
📚 Learning: 2024-10-08T20:57:48.839Z
Learnt from: Czaki
Repo: 4DNucleome/PartSeg PR: 1117
File: .github/workflows/make_release.yml:46-47
Timestamp: 2024-10-08T20:57:48.839Z
Learning: The `requirements/constraints_py3.10.txt` file is used to pin the versions of dependencies in the `pip install` command for the PartSeg project.
Applied to files:
.github/workflows/upgrade-dependencies.yml
🧬 Code graph analysis (5)
package/PartSegCore/analysis/batch_processing/parallel_backend.py (1)
package/PartSegCore/utils.py (1)
prepare_error_data(509-518)
package/tests/test_PartSeg/test_sentry.py (1)
package/PartSegCore/utils.py (2)
prepare_error_data(509-518)safe_repr(485-492)
package/PartSegCore/analysis/batch_processing/batch_backend.py (1)
package/PartSegCore/utils.py (2)
iterate_names(466-475)prepare_error_data(509-518)
package/tests/test_PartSegCore/test_analysis_batch.py (1)
package/PartSegCore/analysis/batch_processing/batch_backend.py (4)
dump_data(764-773)kill_jobs(501-502)has_work(495-499)writing_finished(942-944)
package/tests/test_PartSegCore/test_utils.py (1)
package/PartSegCore/utils.py (1)
prepare_error_data(509-518)
🪛 GitHub Actions: Tests
package/tests/test_PartSeg/test_sentry.py
[error] 49-59: Sentry data bag clipping test failed: expected MAX_DATABAG_BREADTH of 10 but got 4 in first clipped vars result.
[error] 64-76: Sentry data bag clipping breadth test failed: after increasing MAX_DATABAG_BREADTH to 100, expected all letters to be present in vars, but some were missing.
🪛 Ruff (0.14.8)
package/tests/test_PartSegCore/test_utils.py
370-370: Avoid specifying long messages outside the exception class
(TRY003)
379-379: Do not catch blind exception: Exception
(BLE001)
package/PartSegCore/utils.py
511-511: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
512-512: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
- GitHub Check: 4DNucleome.PartSeg (Tests_other test windows)
- GitHub Check: 4DNucleome.PartSeg (Tests_other test macos)
- GitHub Check: 4DNucleome.PartSeg (Tests_linux test_linux)
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller windows)
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller macos_arm)
- GitHub Check: 4DNucleome.PartSeg (Builds sdist)
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller macos)
- GitHub Check: 4DNucleome.PartSeg (Builds pyinstaller_linux)
- GitHub Check: 4DNucleome.PartSeg (Documentation_check Notebook_check)
- GitHub Check: 4DNucleome.PartSeg (manifest_check manifest_check)
- GitHub Check: 4DNucleome.PartSeg (GetTestData linux)
- GitHub Check: 4DNucleome.PartSeg (Documentation_check help)
- GitHub Check: 4DNucleome.PartSeg (formatting_check check_formating)
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: Sourcery review
🔇 Additional comments (14)
.github/workflows/upgrade-dependencies.yml (1)
38-38: LGTM! Python 3.13 added to dependency upgrade workflow.The addition of Python 3.13 to the upgrade loop correctly extends dependency compilation coverage and aligns with the broader Python 3.13 support added across CI workflows and test configurations.
tox.ini (2)
7-7: LGTM! Python 3.13 test coverage added consistently.Python 3.13 (py313) has been correctly added to all relevant test environment patterns and GitHub Actions mappings, ensuring comprehensive test coverage for the new Python version.
Also applies to: 16-16, 74-74, 84-84, 105-105
65-65: Good refactor: pytest invocation simplified.Replacing the specific pytest subpath invocation with a more generic form improves maintainability. This change appears independent of Python 3.13 support but is a positive improvement.
package/tests/test_PartSegCore/test_analysis_batch.py (2)
456-456: Good addition: type hints improve clarity.Adding explicit type annotations (
manager: CalculationManager) and return type (-> None) improves code documentation and enables better static analysis.
466-474: Excellent improvement: enhanced timeout diagnostics.The timeout handling now:
- Dumps writer data for all files (preserving partial results for debugging)
- Provides detailed state information in the failure message (work flag, current task, queue status, writer status)
This significantly improves debuggability when tests timeout.
package/PartSegCore/utils.py (3)
1-2: LGTM! Future annotations enable modern type syntax.Adding
from __future__ import annotationsallows the use of|union syntax throughout this file while maintaining compatibility with Python 3.9+. This is the correct approach for type modernization given the project's Python 3.9+ support requirement.Based on learnings, the project supports Python 3.9+ (not 3.10+), and the
|operator for type annotations was introduced in Python 3.10. However, withfrom __future__ import annotations, these annotations are treated as strings and not evaluated at runtime, making them compatible with Python 3.9+.
22-22: Good addition: centralized error type definition.The
ErrorInfotype alias standardizes error representation across batch processing components, improving type safety and maintainability. The union ofStackSummaryortuple[dict, StackSummary]accommodates both sentry-enabled and sentry-free environments.
64-64: LGTM! Type modernization with union syntax.All function signatures have been correctly updated to use the
|union syntax (e.g.,int | None,dict | EventedDict,str | None). This modernizes the codebase while maintaining Python 3.9+ compatibility through thefrom __future__ import annotationsimport.Also applies to: 76-76, 105-105, 127-127, 293-293, 303-303, 324-324, 340-340, 365-365, 383-383, 466-466, 478-478
package/PartSegCore/analysis/batch_processing/parallel_backend.py (1)
33-33: LGTM! Centralized error handling utility imported.The import of
prepare_error_datafromPartSegCore.utilsaligns with the broader refactor to centralize error handling utilities across batch processing components.package/tests/test_PartSegCore/test_utils.py (2)
3-3: LGTM! Test dependencies added.The imports for
multiprocessingandprepare_error_datasupport the new test coverage for error data serialization in multiprocessing contexts.Also applies to: 17-17
368-384: Good test coverage for error serialization.The new tests verify that
prepare_error_datacorrectly:
- Handles deep exception stacks (via
raise_in_depth)- Produces serializable output that can be queued and retrieved
This validates the core functionality needed for error handling in multiprocessing batch operations.
Note: Minor style hints from static analysis.
- Line 370: Ruff suggests avoiding long messages outside exception class (TRY003)
- Line 379: Ruff suggests avoiding blind exception catching (BLE001)
These are stylistic suggestions and don't affect functionality. Given this is test code with clear intent (testing error handling), these can be safely ignored.
package/PartSegCore/analysis/batch_processing/batch_backend.py (2)
72-72: LGTM! Centralized error handling utilities imported.The imports of
ErrorInfo,iterate_names, andprepare_error_datafromPartSegCore.utilscomplete the refactor to centralize error handling utilities. This eliminates local definitions and ensures consistent error handling across batch processing components.
94-95: Good type alias updates using shared ErrorInfo.The type aliases
CalculationResultListandWrappedResultnow correctly reference the sharedErrorInfotype fromPartSegCore.utils, ensuring type consistency across the codebase.package/tests/test_PartSeg/test_sentry.py (1)
13-13: Import refactoring verified: utilities correctly moved to centralized location.The imports for
prepare_error_dataandsafe_reprhave been correctly moved fromPartSegCore.analysis.batch_processing.batch_backendtoPartSegCore.utils. Both functions are properly defined and actively used in the test file.
| def pre_prepare_traceback_for_queue(exc: BaseException) -> StackSummary: | ||
| """ | ||
| Prepare exception for sending it through the multiprocessing queue. | ||
|
|
||
| :param exc: exception to prepare | ||
| :return: prepared exception | ||
| """ | ||
| traceback_list = traceback.extract_tb(exc.__traceback__) | ||
| for el in traceback_list: | ||
| if hasattr(el, "_code"): | ||
| del el._code | ||
| return traceback_list | ||
|
|
||
|
|
||
| def prepare_error_data(exception: Exception) -> ErrorInfo: | ||
| try: | ||
| from sentry_sdk.serializer import serialize # noqa: PLC0415 | ||
| from sentry_sdk.utils import event_from_exception # noqa: PLC0415 | ||
|
|
||
| event = event_from_exception(exception)[0] | ||
| event = serialize(event) | ||
| return exception, (event, pre_prepare_traceback_for_queue(exception)) | ||
| except ImportError: # pragma: no cover |
There was a problem hiding this comment.
Well-designed error serialization utilities.
The new functions provide robust error data preparation for multiprocessing queues:
pre_prepare_traceback_for_queue: Sanitizes traceback by removing unpicklable_codeattributesprepare_error_data: Attempts sentry serialization with graceful fallback to basic traceback
The design correctly handles the ImportError case when sentry-sdk is not available.
However, there's a minor issue flagged by static analysis:
Remove unused noqa directives.
Lines 511-512 have # noqa: PLC0415 directives that are flagged as unused by Ruff. These should be removed for code cleanliness.
Apply this diff:
try:
- from sentry_sdk.serializer import serialize # noqa: PLC0415
- from sentry_sdk.utils import event_from_exception # noqa: PLC0415
+ from sentry_sdk.serializer import serialize
+ from sentry_sdk.utils import event_from_exception
event = event_from_exception(exception)[0]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def pre_prepare_traceback_for_queue(exc: BaseException) -> StackSummary: | |
| """ | |
| Prepare exception for sending it through the multiprocessing queue. | |
| :param exc: exception to prepare | |
| :return: prepared exception | |
| """ | |
| traceback_list = traceback.extract_tb(exc.__traceback__) | |
| for el in traceback_list: | |
| if hasattr(el, "_code"): | |
| del el._code | |
| return traceback_list | |
| def prepare_error_data(exception: Exception) -> ErrorInfo: | |
| try: | |
| from sentry_sdk.serializer import serialize # noqa: PLC0415 | |
| from sentry_sdk.utils import event_from_exception # noqa: PLC0415 | |
| event = event_from_exception(exception)[0] | |
| event = serialize(event) | |
| return exception, (event, pre_prepare_traceback_for_queue(exception)) | |
| except ImportError: # pragma: no cover | |
| def prepare_error_data(exception: Exception) -> ErrorInfo: | |
| try: | |
| from sentry_sdk.serializer import serialize | |
| from sentry_sdk.utils import event_from_exception | |
| event = event_from_exception(exception)[0] | |
| event = serialize(event) | |
| return exception, (event, pre_prepare_traceback_for_queue(exception)) | |
| except ImportError: # pragma: no cover |
🧰 Tools
🪛 Ruff (0.14.8)
511-511: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
512-512: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
🤖 Prompt for AI Agents
In package/PartSegCore/utils.py around lines 495 to 517, the two imports from
sentry_sdk at lines ~511-512 include unnecessary "# noqa: PLC0415" directives
flagged by Ruff; simply remove those "# noqa: PLC0415" comments from the import
lines so the imports remain but the unused noqa directives are eliminated.
|



Summary by Sourcery
Add Python 3.13 support by updating CI workflows and project metadata and bump the development version.
Enhancements:
CI:
Documentation:
Chores:
Summary by CodeRabbit
New Features
Chores
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.