@@ -170,6 +170,26 @@ def close_widget(widget: widgets.Widget):
170170 logger .warning ("Widget %r does not have a close method, possibly a close trait was added" , widget )
171171
172172
173+ def _is_shared_ipyvue_template (widget : widgets .Widget ) -> bool :
174+ """Is this widget an ipyvue Template that is shared between VueTemplate instances?
175+
176+ ipyvue keeps a per-file registry of Template widgets (ipyvue/Template.py), so several
177+ VueTemplate widgets can point at the same Template. Such a Template outlives the
178+ VueTemplate that created it, and we must not close it as an orphan.
179+ ipyvue 3 only puts a Template in that registry when there is a real comm, so an
180+ unregistered Template belongs to a single VueTemplate and is a normal orphan.
181+ """
182+ cls = widget .__class__
183+ if cls .__name__ != "Template" or cls .__module__ != "ipyvue.Template" :
184+ return False
185+ module = sys .modules .get (cls .__module__ )
186+ registry = getattr (module , "template_registry" , None )
187+ if registry is None :
188+ # unknown ipyvue version: keep the old, conservative behaviour
189+ return True
190+ return any (template is widget for template in registry .values ())
191+
192+
173193def _event_handler_exception_wrapper (f ):
174194 """Wrap an event handler to catch exceptions and put them in a reacton context.
175195
@@ -2166,7 +2186,7 @@ def reconsolidate_children():
21662186 if orphan_ids :
21672187 for orphan_widget in orphan_widgets :
21682188 # these are shared widgets
2169- if orphan_widget . __class__ . __name__ == "Template" and orphan_widget . __class__ . __module__ == "ipyvue.Template" :
2189+ if _is_shared_ipyvue_template ( orphan_widget ) :
21702190 orphan_ids -= {orphan_widget .model_id }
21712191 if el .is_shared :
21722192 widget = self ._shared_widgets [el ]
@@ -2750,7 +2770,7 @@ def _reconsolidate(self, el: Element, default_key: str, parent_key: str):
27502770 orphan_widgets = set ([_get_widgets_dict ()[k ] for k in orphan_ids ])
27512771 for orphan_widget in orphan_widgets :
27522772 # these are shared between widgets
2753- if orphan_widget . __class__ . __name__ == "Template" and orphan_widget . __class__ . __module__ == "ipyvue.Template" :
2773+ if _is_shared_ipyvue_template ( orphan_widget ) :
27542774 orphan_ids -= {orphan_widget .model_id }
27552775 widget = self ._shared_widgets [el ] if el .is_shared else context .widgets [key ]
27562776 if widget .model_id not in self ._orphans :
0 commit comments