Skip to content

Commit 59d299e

Browse files
committed
Fix "Remove all results" AttributeError when ROI was removed
Closes #286
1 parent 1645046 commit 59d299e

File tree

4 files changed

+92
-2
lines changed

4 files changed

+92
-2
lines changed

datalab/adapters_metadata/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def append(self, adapter: BaseResultAdapter, obj: SignalObj | ImageObj) -> None:
8888
if "roi_index" in df.columns:
8989
i_roi = int(df.iloc[i_row_res]["roi_index"])
9090
roititle = ""
91-
if i_roi >= 0:
91+
if i_roi >= 0 and obj.roi is not None:
9292
roititle = obj.roi.get_single_roi_title(i_roi)
9393
ylabel += f"|{roititle}"
9494
self.ylabels.append(ylabel)

datalab/tests/features/common/result_deletion_unit_test.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,63 @@ def test_delete_results_clears_analysis_parameters():
154154
execenv.print("\n✓ All tests passed!")
155155

156156

157+
def test_delete_results_after_roi_removed():
158+
"""Test that deleting results works when ROI was removed from object.
159+
160+
This tests the fix for the bug where deleting results fails with
161+
AttributeError when results contain ROI information but the ROI
162+
was subsequently removed from the object.
163+
"""
164+
with datalab_test_app_context(console=False) as win:
165+
execenv.print("Test delete_results after ROI removed:")
166+
panel = win.imagepanel
167+
168+
# Create a test image with ROI
169+
param = Gauss2DParam.create(height=200, width=200, sigma=20)
170+
img = create_image_from_param(param)
171+
roi = create_image_roi("rectangle", [25, 25, 100, 100])
172+
img.roi = roi
173+
panel.add_object(img)
174+
execenv.print(" ✓ Created image with ROI")
175+
176+
# Run centroid analysis - this stores ROI index in results
177+
execenv.print(" Running centroid analysis with ROI...")
178+
with Conf.proc.show_result_dialog.temp(False):
179+
panel.processor.run_feature("centroid")
180+
181+
# Verify that results exist and contain ROI information
182+
img_refreshed = panel.objmodel[get_uuid(img)]
183+
adapter_before = GeometryAdapter.from_obj(img_refreshed, "centroid")
184+
assert adapter_before is not None, "Centroid result should exist"
185+
df = adapter_before.to_dataframe()
186+
assert "roi_index" in df.columns, "Results should contain roi_index"
187+
execenv.print(" ✓ Centroid result created with ROI information")
188+
189+
# Now remove the ROI from the object (simulating user action)
190+
img_refreshed.roi = None
191+
execenv.print(" ✓ Removed ROI from object")
192+
193+
# Try to delete all results - this should NOT raise an error
194+
execenv.print(" Deleting all results (with ROI removed)...")
195+
panel.objview.select_objects([get_uuid(img)])
196+
try:
197+
panel.delete_results()
198+
execenv.print(" ✓ Delete results succeeded (no AttributeError)")
199+
except AttributeError as e:
200+
raise AssertionError(
201+
f"delete_results should not raise AttributeError when ROI is None: {e}"
202+
) from e
203+
204+
# Verify that results were deleted
205+
img_after = panel.objmodel[get_uuid(img)]
206+
adapter_after = GeometryAdapter.from_obj(img_after, "centroid")
207+
assert adapter_after is None, "Centroid result should be deleted"
208+
execenv.print(" ✓ Centroid result deleted successfully")
209+
execenv.print("\n✓ Test passed!")
210+
211+
157212
if __name__ == "__main__":
158213
test_delete_results_image()
159214
test_delete_results_signal()
160215
test_delete_results_clears_analysis_parameters()
216+
test_delete_results_after_roi_removed()

doc/locale/fr/LC_MESSAGES/release_notes/release_1.00.po

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ msgid ""
77
msgstr ""
88
"Project-Id-Version: DataLab \n"
99
"Report-Msgid-Bugs-To: \n"
10-
"POT-Creation-Date: 2025-12-16 10:56+0100\n"
10+
"POT-Creation-Date: 2025-12-16 12:43+0100\n"
1111
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1212
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313
"Language: fr\n"
@@ -27,6 +27,30 @@ msgstr ""
2727
msgid "🛠️ Bug Fixes since version 1.0.2"
2828
msgstr "🛠️ Correctifs depuis la version 1.0.2"
2929

30+
msgid "**Remove all results - AttributeError when ROI was removed:**"
31+
msgstr "**Supprimer tous les résultats - AttributeError lorsque la ROI a été supprimée :**"
32+
33+
msgid "Fixed \"Remove all results\" action failing with `AttributeError: 'NoneType' object has no attribute 'get_single_roi_title'` when results contain ROI information but the ROI was subsequently removed from the object"
34+
msgstr "Correction de l'action « Supprimer tous les résultats » qui échouait avec `AttributeError: 'NoneType' object has no attribute 'get_single_roi_title'` lorsque les résultats contiennent des informations de ROI mais que la ROI a été ensuite supprimée de l'objet"
35+
36+
msgid "The issue occurred when:"
37+
msgstr "Le problème se produisait lorsque :"
38+
39+
msgid "Running an analysis with a ROI (e.g., Centroid on an image with rectangular ROI)"
40+
msgstr "Exécution d'une analyse avec une ROI (par ex. Centroïde sur une image avec ROI rectangulaire)"
41+
42+
msgid "Removing the ROI from the object"
43+
msgstr "Suppression de la ROI de l'objet"
44+
45+
msgid "Trying to delete all results via \"Analysis > Remove results > Remove all results\""
46+
msgstr "Tentative de suppression de tous les résultats via « Analyse > Supprimer les résultats > Supprimer tous les résultats »"
47+
48+
msgid "The fix adds a proper None check before accessing the ROI's title"
49+
msgstr "Le correctif ajoute une vérification de valeur None appropriée avant d'accéder au titre de la ROI"
50+
51+
msgid "This closes [Issue #286](https://github.com/DataLab-Platform/DataLab/issues/286) - 'Remove all results' fails with AttributeError when ROI was removed"
52+
msgstr "Ceci clôture [Issue #286](https://github.com/datalab-platform/datalab/issues/286) - 'Remove all results' fails with AttributeError when ROI was removed"
53+
3054
msgid "**Analysis auto-recompute - Stale parameters after deleting results:**"
3155
msgstr "**Recalcul automatique de l'analyse - Paramètres obsolètes après suppression des résultats :**"
3256

doc/release_notes/release_1.00.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@
44

55
### 🛠️ Bug Fixes since version 1.0.2 ###
66

7+
**Remove all results - AttributeError when ROI was removed:**
8+
9+
* Fixed "Remove all results" action failing with `AttributeError: 'NoneType' object has no attribute 'get_single_roi_title'` when results contain ROI information but the ROI was subsequently removed from the object
10+
* The issue occurred when:
11+
1. Running an analysis with a ROI (e.g., Centroid on an image with rectangular ROI)
12+
2. Removing the ROI from the object
13+
3. Trying to delete all results via "Analysis > Remove results > Remove all results"
14+
* The fix adds a proper None check before accessing the ROI's title
15+
* This closes [Issue #286](https://github.com/DataLab-Platform/DataLab/issues/286) - "Remove all results" fails with AttributeError when ROI was removed
16+
717
**Analysis auto-recompute - Stale parameters after deleting results:**
818

919
* Fixed analysis parameters not being cleared when deleting analysis results, which could cause unexpected auto-recompute behavior when modifying ROIs

0 commit comments

Comments
 (0)