@@ -485,14 +485,28 @@ def add(self, name: str, obj: DataObject, overwrite: bool = False) -> None:
485485 # Set the title on the object
486486 obj .title = name
487487
488- # add_object auto-detects panel based on object type
488+ # Determine which panel the object will be added to
489+ from sigima import SignalObj # pylint: disable=import-outside-toplevel
490+
491+ panel = "signal" if isinstance (obj , SignalObj ) else "image"
492+
493+ # add_object uses cross-thread Qt signals - it returns before the signal
494+ # is processed by the main thread. We must poll until the object appears.
489495 self .proxy .add_object (obj )
490496
491- # Force synchronization: add_object uses Qt signals without @remote_call
492- # decorator, so it returns before the object is actually added.
493- # Calling get_current_panel() (which has @remote_call) forces the Qt event
494- # loop to process pending signals including SIG_ADD_OBJECT.
495- self .proxy .get_current_panel ()
497+ # Wait for object to appear (cross-thread signal processing)
498+ # On slow CI (Python 3.9), the signal may take time to be processed
499+ for _ in range (100 ): # 10 seconds total timeout
500+ try :
501+ titles = self .proxy .get_object_titles (panel = panel )
502+ if name in titles :
503+ return # Object successfully added
504+ except Exception : # pylint: disable=broad-exception-caught
505+ pass
506+ time .sleep (0.1 )
507+
508+ # If we get here, the add failed (shouldn't happen normally)
509+ raise RuntimeError (f"Timeout waiting for object '{ name } ' to appear in DataLab" )
496510
497511 def remove (self , name : str ) -> None :
498512 """Remove an object from the workspace.
@@ -821,14 +835,7 @@ def add(self, name: str, obj: DataObject, overwrite: bool = False) -> DataObject
821835 ValueError: If object exists and overwrite=False
822836 """
823837 self ._backend .add (name , obj , overwrite = overwrite )
824- # For live backend, allow retry window for object to appear
825- # This handles race conditions with XML-RPC (especially on Python 3.9)
826- if isinstance (self ._backend , LiveBackend ):
827- for _ in range (50 ): # 5 seconds total timeout
828- try :
829- return self ._backend .get (name )
830- except KeyError :
831- time .sleep (0.1 )
838+ # LiveBackend.add() waits for the object to appear, so get() should work
832839 return self ._backend .get (name )
833840
834841 def remove (self , name : str ) -> None :
0 commit comments