Skip to content

Commit aea7d55

Browse files
Merge pull request #55 from widgetti/ci/ipyvue3-compat
Support ipyvue 3 and test it in CI on one Python version
2 parents f92d470 + 18abcd2 commit aea7d55

2 files changed

Lines changed: 35 additions & 4 deletions

File tree

.github/workflows/unittest.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,19 @@ jobs:
2525
# run the suite against both the default renderer and the opt-in fast
2626
# one (REACTON_FAST=1), so both stay green
2727
reacton-fast: ["0", "1"]
28+
# ipyvue/ipyvuetify 3 are the Vue 3 port. Pin the 1.x line by default and
29+
# add one python version that runs against the 3.x line, so reacton keeps
30+
# working with both.
31+
ipyvue: ["<3"]
32+
include:
33+
- python-version: "3.12"
34+
reacton-fast: "0"
35+
ipyvue: ">=3"
36+
- python-version: "3.12"
37+
reacton-fast: "1"
38+
ipyvue: ">=3"
2839

29-
name: unit-test (py${{ matrix.python-version }}, REACTON_FAST=${{ matrix.reacton-fast }})
40+
name: unit-test${{ matrix.ipyvue == '>=3' && '-vue3' || '' }} (py${{ matrix.python-version }}, REACTON_FAST=${{ matrix.reacton-fast }})
3041
steps:
3142
- uses: actions/checkout@v4
3243
- name: Set up Python ${{ matrix.python-version }}
@@ -39,7 +50,7 @@ jobs:
3950
path: ./dist
4051
- name: Install
4152
run: |
42-
pip install `echo dist/*.whl`[dev] "bqplot<0.13" "pandas<3" "ruff==0.8.3"
53+
pip install `echo dist/*.whl`[dev] "bqplot<0.13" "pandas<3" "ruff==0.8.3" "ipyvue${{ matrix.ipyvue }}" "ipyvuetify${{ matrix.ipyvue }}"
4354
- name: test
4455
env:
4556
REACTON_FAST: ${{ matrix.reacton-fast }}

reacton/core.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
173193
def _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

Comments
 (0)