Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-ipyvue for openSUSE:Factory checked in at 2024-04-02 16:40:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-ipyvue (Old) and /work/SRC/openSUSE:Factory/.python-ipyvue.new.1905 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-ipyvue" Tue Apr 2 16:40:27 2024 rev:9 rq:1163564 version:1.10.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-ipyvue/python-ipyvue.changes 2024-03-07 18:32:17.227369663 +0100 +++ /work/SRC/openSUSE:Factory/.python-ipyvue.new.1905/python-ipyvue.changes 2024-04-02 16:40:45.929589447 +0200 @@ -1,0 +2,6 @@ +Fri Mar 29 17:21:59 UTC 2024 - Ben Greiner <c...@bnavigator.de> + +- Update to 1.10.2 + * fix: watch didn't work for Vue-only vars + +------------------------------------------------------------------- Old: ---- ipyvue-1.10.1-gh.tar.gz ipyvue-1.10.1.tar.gz New: ---- ipyvue-1.10.2-gh.tar.gz ipyvue-1.10.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-ipyvue.spec ++++++ --- /var/tmp/diff_new_pack.Pen4MC/_old 2024-04-02 16:40:46.593613918 +0200 +++ /var/tmp/diff_new_pack.Pen4MC/_new 2024-04-02 16:40:46.593613918 +0200 @@ -17,10 +17,10 @@ # This is important for versions ending in .0 -%define python3dist_version 1.10.1 +%define python3dist_version 1.10.2 %define skip_python39 1 Name: python-ipyvue -Version: 1.10.1 +Version: 1.10.2 Release: 0 Summary: Jupyter widgets base for Vue libraries License: MIT ++++++ ipyvue-1.10.1-gh.tar.gz -> ipyvue-1.10.2-gh.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipyvue-1.10.1/.bumpversion.cfg new/ipyvue-1.10.2/.bumpversion.cfg --- old/ipyvue-1.10.1/.bumpversion.cfg 2023-09-07 16:55:32.000000000 +0200 +++ new/ipyvue-1.10.2/.bumpversion.cfg 2024-02-27 15:23:12.000000000 +0100 @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.10.1 +current_version = 1.10.2 commit = True message = chore: bump version: {current_version} â {new_version} tag = True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipyvue-1.10.1/.github/workflows/unit.yml new/ipyvue-1.10.2/.github/workflows/unit.yml --- old/ipyvue-1.10.1/.github/workflows/unit.yml 2023-09-07 16:55:32.000000000 +0200 +++ new/ipyvue-1.10.2/.github/workflows/unit.yml 2024-02-27 15:23:12.000000000 +0100 @@ -13,7 +13,7 @@ - name: Install Python uses: actions/setup-python@v2 with: - python-version: "3.x" + python-version: "3.11" - name: Install dependencies run: pip install -r .github/requirements.txt - name: Run black @@ -35,7 +35,7 @@ - name: Install Python uses: actions/setup-python@v2 with: - python-version: "3.x" + python-version: "3.11" - name: Install dependencies run: | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipyvue-1.10.1/README.md new/ipyvue-1.10.2/README.md --- old/ipyvue-1.10.1/README.md 2023-09-07 16:55:32.000000000 +0200 +++ new/ipyvue-1.10.2/README.md 2024-02-27 15:23:12.000000000 +0100 @@ -25,3 +25,10 @@ $ jupyter nbextension install --py --symlink --sys-prefix ipyvue $ jupyter nbextension enable --py --sys-prefix ipyvue $ jupyter labextension develop . --overwrite + +Sponsors +-------- + +Project ipyvue receives direct funding from the following sources: + +[![MSD](resources/msd-logo.svg)](https://msd.com) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipyvue-1.10.1/ipyvue/_version.py new/ipyvue-1.10.2/ipyvue/_version.py --- old/ipyvue-1.10.1/ipyvue/_version.py 2023-09-07 16:55:32.000000000 +0200 +++ new/ipyvue-1.10.2/ipyvue/_version.py 2024-02-27 15:23:12.000000000 +0100 @@ -1,2 +1,2 @@ -__version__ = "1.10.1" +__version__ = "1.10.2" semver = "^" + __version__ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipyvue-1.10.1/js/package.json new/ipyvue-1.10.2/js/package.json --- old/ipyvue-1.10.1/js/package.json 2023-09-07 16:55:32.000000000 +0200 +++ new/ipyvue-1.10.2/js/package.json 2024-02-27 15:23:12.000000000 +0100 @@ -1,6 +1,6 @@ { "name": "jupyter-vue", - "version": "1.10.1", + "version": "1.10.2", "description": "Jupyter widgets base for Vue libraries", "license": "MIT", "author": "Mario Buikhuizen, Maarten Breddels", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipyvue-1.10.1/js/src/VueTemplateRenderer.js new/ipyvue-1.10.2/js/src/VueTemplateRenderer.js --- old/ipyvue-1.10.1/js/src/VueTemplateRenderer.js 2023-09-07 16:55:32.000000000 +0200 +++ new/ipyvue-1.10.2/js/src/VueTemplateRenderer.js 2024-02-27 15:23:12.000000000 +0100 @@ -163,27 +163,30 @@ } function createWatches(model, parentView, templateWatchers) { - return model.keys() - .filter(prop => !prop.startsWith('_') - && !['events', 'template', 'components', 'layout', 'css', 'data', 'methods'].includes(prop)) - .reduce((result, prop) => ({ - ...result, - [prop]: { - handler(value) { - if (templateWatchers && templateWatchers[prop]) { - templateWatchers[prop].bind(this)(value); - } - /* Don't send changes received from backend back */ - if (_.isEqual(value, model.get(prop))) { - return; - } + const modelWatchers = model.keys().filter(prop => !prop.startsWith('_') + && !['events', 'template', 'components', 'layout', 'css', 'data', 'methods'].includes(prop)) + .reduce((result, prop) => ({ + ...result, + [prop]: { + handler(value) { + if (templateWatchers && templateWatchers[prop]) { + templateWatchers[prop].bind(this)(value); + } + /* Don't send changes received from backend back */ + if (_.isEqual(value, model.get(prop))) { + return; + } - model.set(prop, value === undefined ? null : _.cloneDeep(value)); - model.save_changes(model.callbacks(parentView)); - }, - deep: true, + model.set(prop, value === undefined ? null : _.cloneDeep(value)); + model.save_changes(model.callbacks(parentView)); }, - }), {}); + deep: true, + }, + }), {}) + /* Overwritten keys from templateWatchers are handled in modelWatchers + so that we eventually call all handlers from templateWatchers. + */ + return {...templateWatchers, ...modelWatchers}; } function createMethods(model, parentView) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipyvue-1.10.1/release.sh new/ipyvue-1.10.2/release.sh --- old/ipyvue-1.10.1/release.sh 2023-09-07 16:55:32.000000000 +0200 +++ new/ipyvue-1.10.2/release.sh 2024-02-27 15:23:12.000000000 +0100 @@ -3,4 +3,7 @@ # usage: ./release minor -n version=$(bump2version --dry-run --list $* | grep new_version= | sed -r s,"^.*=",,) echo Version tag v$version -bumpversion $* --verbose && git push upstream master v$version +bumpversion $* --verbose +(cd js && npm install) +git add js/package-lock.json && git commit --amend --no-edit +git push upstream master v$version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipyvue-1.10.1/resources/msd-logo.svg new/ipyvue-1.10.2/resources/msd-logo.svg --- old/ipyvue-1.10.1/resources/msd-logo.svg 1970-01-01 01:00:00.000000000 +0100 +++ new/ipyvue-1.10.2/resources/msd-logo.svg 2024-02-27 15:23:12.000000000 +0100 @@ -0,0 +1 @@ +<svg width="266" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 442.89 165.48"><defs><style>.cls-1{fill:#009484;}.cls-2{fill:#243444;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Graphics"><path class="cls-1" d="M41.37,41.37a41.37,41.37,0,0,1,82.74,0Zm0,82.74A41.37,41.37,0,0,1,82.74,82.74,41.37,41.37,0,0,1,41.37,41.37a41.37,41.37,0,0,0,0,82.74Zm0,0a41.37,41.37,0,0,0,82.74,0ZM82.74,82.74a41.37,41.37,0,0,1,41.37,41.37,41.37,41.37,0,1,0,0-82.74A41.37,41.37,0,0,1,82.74,82.74Z"/><path class="cls-2" d="M269.76,41.37h25.63V124.1h-19V68.46L252.09,124.1,226.51,68.39V124.1H208.79V41.37h25.33l18.27,42.82ZM363,65.81C363,49.46,350.43,40,335.41,40s-31.13,8.72-31.13,25.66c0,14.69,16.17,22.24,25.4,24.62,5.07,1.34,17.86,2.77,17.86,11.91,0,8.69-8.94,11.06-15.63,11.06-8.62,0-13.68-6-12.94-15.17H302c-.59,20.58,13.4,28.25,29.74,28.63,18.89.43,33.31-7.64,33.31-25.83s-16.36-21.17-29.15-25.32C331,73.91,321.8,72.48,321.8,64c0-7.07,6.1-10.45,12.34-10.45,8,0,12.19,4,12.79,12.22H363m35.75-24.53H3 72.38v82.65h26.36c21.91,0,44.15-12.66,44.15-41.25S420.65,41.28,398.74,41.28Zm-1.19,67.61-7.3,0V56.47h7.3c20.09,0,27.34,13.1,27.34,26.21S417.64,108.89,397.55,108.89Z"/></g></g></svg> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipyvue-1.10.1/setup.py new/ipyvue-1.10.2/setup.py --- old/ipyvue-1.10.1/setup.py 2023-09-07 16:55:32.000000000 +0200 +++ new/ipyvue-1.10.2/setup.py 2024-02-27 15:23:12.000000000 +0100 @@ -195,9 +195,10 @@ "jsdeps": NPM, "develop": DevelopCmd, }, + license="MIT", author="Mario Buikhuizen, Maarten Breddels", author_email="mbuikhui...@gmail.com, maartenbredd...@gmail.com", - url="https://github.com/widgetto/ipyvue", + url="https://github.com/widgetti/ipyvue", keywords=[ "ipython", "jupyter", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipyvue-1.10.1/tests/ui/test_nested.py new/ipyvue-1.10.2/tests/ui/test_nested.py --- old/ipyvue-1.10.1/tests/ui/test_nested.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ipyvue-1.10.2/tests/ui/test_nested.py 2024-02-27 15:23:12.000000000 +0100 @@ -0,0 +1,155 @@ +import pytest +import sys +import re + +if sys.version_info < (3, 7): + pytest.skip("requires python3.7 or higher", allow_module_level=True) + +import ipyvue as vue +import playwright.sync_api +from playwright.sync_api import expect + +from IPython.display import display +from traitlets import default, Unicode, Instance +import ipywidgets as widgets + + +class MyTemplate(vue.VueTemplate): + class_ = Unicode("template-parent").tag(sync=True) + child = Instance(widgets.Widget, allow_none=True).tag( + sync=True, **widgets.widget_serialization + ) + text = Unicode(None, allow_none=True).tag(sync=True) + + @default("template") + def _default_vue_template(self): + return """ + <template> + <div :class="class_"> + <span v-if="text">{{text}}</span> + <jupyter-widget v-if="child" :widget="child"></jupyter-widget> + </div> + </template> + """ + + +@pytest.mark.parametrize("parent_is_template", [True, False]) +def test_vue_with_vue_widget_child( + ipywidgets_runner, page_session: playwright.sync_api.Page, parent_is_template +): + def kernel_code(): + from test_nested import MyTemplate + import ipyvue as vue + + child = vue.Html(tag="div", children=["I am a widget sibling"]) + + if parent_is_template: + widget = MyTemplate(child=child, class_="test-parent") + else: + widget = vue.Html( + tag="div", + children=[child], + class_="test-parent", + ) + display(widget) + + ipywidgets_runner(kernel_code, {"parent_is_template": parent_is_template}) + parent = page_session.locator(".test-parent") + parent.wait_for() + expect(parent.locator(":nth-child(1)")).to_contain_text("I am a widget sibling") + + +@pytest.mark.parametrize("parent_is_template", [True, False]) +def test_vue_with_vue_template_child( + ipywidgets_runner, page_session: playwright.sync_api.Page, parent_is_template +): + def kernel_code(): + # this import is need so when this code executes in the kernel, + # the class is imported + from test_nested import MyTemplate + import ipyvue as vue + + child = MyTemplate(class_="test-child", text="I am a child") + + if parent_is_template: + widget = MyTemplate( + child=child, + class_="test-parent", + ) + else: + widget = vue.Html( + tag="div", + children=[child], + class_="test-parent", + ) + display(widget) + + ipywidgets_runner(kernel_code, {"parent_is_template": parent_is_template}) + parent = page_session.locator(".test-parent") + parent.wait_for() + expect(parent.locator(":nth-child(1) >> nth=0")).to_have_class("test-child") + expect(parent.locator(".test-child >> :nth-child(1)")).to_contain_text( + "I am a child" + ) + + +@pytest.mark.parametrize("parent_is_template", [True, False]) +def test_vue_with_ipywidgets_child( + ipywidgets_runner, page_session: playwright.sync_api.Page, parent_is_template +): + def kernel_code(): + from test_nested import MyTemplate + import ipyvue as vue + import ipywidgets as widgets + + child = widgets.Label(value="I am a child") + child.add_class("widget-child") + + if parent_is_template: + widget = MyTemplate( + child=child, + class_="test-parent", + ) + else: + widget = vue.Html( + tag="div", + children=[child], + class_="test-parent", + ) + display(widget) + + ipywidgets_runner(kernel_code, {"parent_is_template": parent_is_template}) + parent = page_session.locator(".test-parent") + parent.wait_for() + # extra div is created by ipyvue + expect(parent.locator(":nth-child(1) >> :nth-child(1)")).to_have_class( + re.compile(".*widget-child.*") + ) + expect(parent.locator(".widget-child")).to_contain_text("I am a child") + + +@pytest.mark.parametrize("parent_is_template", [True, False]) +def test_vue_ipywidgets_vue( + ipywidgets_runner, page_session: playwright.sync_api.Page, parent_is_template +): + # tests an interrupted vue hierarchy + def kernel_code(): + import ipywidgets as widgets + import ipyvue as vue + + child = vue.Html( + tag="div", children=["I am a widget sibling"], class_="test-child" + ) + parent = widgets.VBox(children=[child]) + parent.add_class("ipywidgets-parent") + grant_parent = vue.Html( + tag="div", + children=[child], + class_="test-grandparent", + ) + display(grant_parent) + + ipywidgets_runner(kernel_code, {"parent_is_template": parent_is_template}) + grand_parent = page_session.locator(".test-grandparent") + grand_parent.wait_for() + expect(grand_parent.locator(".test-child")).to_contain_text("I am a widget sibling") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipyvue-1.10.1/tests/ui/test_watchers.py new/ipyvue-1.10.2/tests/ui/test_watchers.py --- old/ipyvue-1.10.1/tests/ui/test_watchers.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ipyvue-1.10.2/tests/ui/test_watchers.py 2024-02-27 15:23:12.000000000 +0100 @@ -0,0 +1,94 @@ +import pytest +import sys +from playwright.sync_api import Page +from traitlets import Callable, Int, Unicode, default +from IPython.display import display + +if sys.version_info < (3, 7): + pytest.skip("requires python3.7 or higher", allow_module_level=True) + +import ipyvue as vue + + +class WatcherTemplateTraitlet(vue.VueTemplate): + number = Int(0).tag(sync=True) + callback = Callable() + text = Unicode("Click Me ").tag(sync=True) + + @default("template") + def _default_vue_template(self): + return """ + <template> + <div @click="number += 1">{{text + number}}</div> + </template> + <script> + export default { + watch: { + number: function(value) { + callback(); + } + } + } + </script> + """ + + def vue_callback(self): + self.callback() + + +# We test that the watcher is activated when a var from python is changed +def test_watcher_traitlet(solara_test, page_session: Page): + def callback(): + widget.text = "Clicked " + + widget = WatcherTemplateTraitlet(callback=callback) + + display(widget) + + widget = page_session.locator("text=Click Me 0") + widget.click() + widget = page_session.locator("text=Clicked 1") + + +class WatcherTemplateVue(vue.VueTemplate): + callback = Callable() + text = Unicode("Click Me ").tag(sync=True) + + @default("template") + def _default_vue_template(self): + return """ + <template> + <div @click="number += 1">{{text + number}}</div> + </template> + <script> + export default { + watch: { + number: function(value) { + callback(); + } + }, + data(){ + return { + number: 0 + } + } + } + </script> + """ + + def vue_callback(self): + self.callback() + + +# We test that watch works for a purely Vue variable +def test_watcher_vue(solara_test, page_session: Page): + def callback(): + widget.text = "Clicked " + + widget = WatcherTemplateVue(callback=callback) + + display(widget) + + widget = page_session.locator("text=Click Me 0") + widget.click() + widget = page_session.locator("text=Clicked 1") ++++++ ipyvue-1.10.1-gh.tar.gz -> ipyvue-1.10.2.tar.gz ++++++ ++++ 21453 lines of diff (skipped)