Skip to content

Commit bbd67df

Browse files
committed
Fix crash when adding object via RemoteProxy
Closes #279
1 parent 396e816 commit bbd67df

File tree

4 files changed

+106
-4
lines changed

4 files changed

+106
-4
lines changed

datalab/gui/objectview.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,26 @@ def populate_tree(self) -> None:
222222
self.set_current_item_id(uuid)
223223

224224
def update_tree(self) -> None:
225-
"""Update tree"""
225+
"""Update tree
226+
227+
Note: If an item is not found in the tree, the tree is repopulated to ensure
228+
consistency between the tree and the model. This can happen in rare cases when
229+
objects are added to the model but the tree was not properly updated.
230+
"""
226231
for group in self.objmodel.get_groups():
227-
self.__update_item(self.get_item_from_id(get_uuid(group)), group)
232+
group_item = self.get_item_from_id(get_uuid(group))
233+
if group_item is None:
234+
# Group item not found, repopulate tree to fix inconsistency
235+
self.populate_tree()
236+
return
237+
self.__update_item(group_item, group)
228238
for obj in group:
229-
self.__update_item(self.get_item_from_id(get_uuid(obj)), obj)
239+
obj_item = self.get_item_from_id(get_uuid(obj))
240+
if obj_item is None:
241+
# Object item not found, repopulate tree to fix inconsistency
242+
self.populate_tree()
243+
return
244+
self.__update_item(obj_item, obj)
230245

231246
def __add_to_group_item(
232247
self, obj: SignalObj | ImageObj, group_item: QW.QTreeWidgetItem
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2+
3+
"""
4+
Update tree robustness test
5+
---------------------------
6+
7+
This test verifies that the object tree view handles edge cases gracefully,
8+
specifically when the tree becomes out of sync with the model.
9+
10+
This is a regression test for a bug where update_tree() crashed with
11+
AttributeError: 'NoneType' object has no attribute 'setText' when an
12+
object existed in the model but had no corresponding tree item.
13+
14+
The fix makes update_tree() defensive by calling populate_tree() if
15+
an item is not found.
16+
"""
17+
18+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
19+
# guitest: show
20+
21+
import numpy as np
22+
import sigima.objects
23+
24+
from datalab.tests import datalab_test_app_context
25+
26+
27+
def test_update_tree_with_model_tree_desync():
28+
"""Test that update_tree handles model/tree desynchronization gracefully.
29+
30+
This test simulates a scenario where an object exists in the model
31+
but doesn't have a corresponding tree item, which previously caused
32+
an AttributeError in update_tree().
33+
34+
The fix ensures update_tree() detects this and calls populate_tree()
35+
to restore consistency.
36+
"""
37+
with datalab_test_app_context(console=False) as win:
38+
win.set_current_panel("image")
39+
40+
# Create and add a base image
41+
data = np.random.rand(100, 100).astype(np.float64)
42+
img1 = sigima.objects.create_image("Base Image", data)
43+
win.imagepanel.add_object(img1)
44+
45+
# Create a second image and add it to the MODEL only (not to the tree)
46+
# This simulates a desync between model and tree
47+
data2 = np.random.rand(100, 100).astype(np.float64)
48+
img2 = sigima.objects.create_image("Second Image", data2)
49+
50+
# Get current group ID
51+
group_id = win.imagepanel.objview.get_current_group_id()
52+
53+
# Add to model ONLY (bypassing add_object_item which adds to tree)
54+
win.imagepanel.objmodel.add_object(img2, group_id)
55+
56+
# Now the model has 2 objects but the tree only shows 1
57+
# Calling update_tree() should NOT crash
58+
# With the fix, it should call populate_tree() to resync
59+
60+
# This is the call that previously caused:
61+
# AttributeError: 'NoneType' object has no attribute 'setText'
62+
win.imagepanel.objview.update_tree()
63+
64+
# Verify objects are now in sync
65+
assert len(win.imagepanel) == 2

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

Lines changed: 16 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-13 11:43+0100\n"
10+
"POT-Creation-Date: 2025-12-13 12:31+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,21 @@ msgstr ""
2727
msgid "🛠️ Bug Fixes since version 1.0.2"
2828
msgstr "🛠️ Correctifs depuis la version 1.0.2"
2929

30+
msgid "**Remote control - Crash when adding object via proxy:**"
31+
msgstr "**Contrôle distant - Plantage lors de l'ajout d'un objet via le proxy :**"
32+
33+
msgid "Fixed `AttributeError: 'NoneType' object has no attribute 'setText'` crash when adding objects via `RemoteProxy.add_object()` in macros"
34+
msgstr "Correction du plantage `AttributeError: 'NoneType' object has no attribute 'setText'` lors de l'ajout d'objets via `RemoteProxy.add_object()` dans les macros"
35+
36+
msgid "The crash occurred in `update_tree()` when the tree view became temporarily out of sync with the object model (e.g., when adding objects with specific metadata configurations or ROIs via remote proxy)"
37+
msgstr "Le plantage se produisait dans `update_tree()` lorsque la vue arborescente se désynchronisait temporairement avec le modèle d'objets (par exemple, lors de l'ajout d'objets avec des configurations de métadonnées spécifiques ou des ROIs via le proxy distant)"
38+
39+
msgid "The tree view now rebuilds automatically if inconsistencies are detected, ensuring robust object addition in all scenarios"
40+
msgstr "La vue arborescente se reconstruit désormais automatiquement si des incohérences sont détectées, assurant un ajout d'objets robuste dans tous les scénarios"
41+
42+
msgid "This closes [Issue #279](https://github.com/datalab-platform/datalab/issues/279) - AttributeError in update_tree() when adding object via RemoteProxy"
43+
msgstr "Ceci clôture [Issue #279](https://github.com/datalab-platform/datalab/issues/279) - AttributeError dans update_tree() lors de l'ajout d'un objet via RemoteProxy"
44+
3045
msgid "**Icons - Qt SVG warnings on Linux:**"
3146
msgstr "**Icônes - Avertissements Qt SVG sous Linux :**"
3247

doc/release_notes/release_1.00.md

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

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

7+
**Remote control - Crash when adding object via proxy:**
8+
9+
* Fixed `AttributeError: 'NoneType' object has no attribute 'setText'` crash when adding objects via `RemoteProxy.add_object()` in macros
10+
* The crash occurred in `update_tree()` when the tree view became temporarily out of sync with the object model (e.g., when adding objects with specific metadata configurations or ROIs via remote proxy)
11+
* The tree view now rebuilds automatically if inconsistencies are detected, ensuring robust object addition in all scenarios
12+
* This closes [Issue #279](https://github.com/datalab-platform/datalab/issues/279) - AttributeError in update_tree() when adding object via RemoteProxy
13+
714
**Icons - Qt SVG warnings on Linux:**
815

916
* Fixed "qt.svg: Invalid path data; path truncated" warnings appearing 4 times at startup on Linux/Ubuntu

0 commit comments

Comments
 (0)