Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Traitlet problem (fails to synchronize) on certain combination of modules #3655

Open
audunsh opened this issue Dec 20, 2022 · 2 comments
Open
Labels
Custom Widget Issues related to using ipywidgets as a framework for custom widgets

Comments

@audunsh
Copy link

audunsh commented Dec 20, 2022

Description

The boilerplate example in documentation fails to synchronize traitlets on the most recent install of IPywidgets in the Classic Notebook.

It is unclear to me wether or not this is caused by external dependencies, but the following downgrade of several modules (unsure wether or not they are relevant) fixes the problem:

!pip3 install flatbuffers==22.10.26 google-auth==2.13.0 imageio==2.22.2 importlib-metadata==5.1.0 ipykernel==6.17.1 ipywidgets==8.0.2 jupyter-server==1.23.3 nbformat==5.7.0 prompt-toolkit==3.0.32 protobuf==4.21.9 SQLAlchemy==1.4.44 traitlets==5.6.0 widgetsnbextension==4.0.3

I first encountered this problem on December 19th 2022, and managed to narrow it down to the above modules by comparing to a working installation.

Reproduce

On a recent install of IPywidgets in a classic Notebook, run:

from ipywidgets import DOMWidget
from traitlets import Unicode, Int

class MyWidget(DOMWidget):
    _view_module = Unicode('mywidget').tag(sync=True)
    _view_module_version = Unicode('0.1.0').tag(sync=True)
    _view_name = Unicode('MyWidgetView').tag(sync=True)
    count = Int().tag(sync=True)

In the next cell:

%%javascript

define('mywidget', ['@jupyter-widgets/base'], function(widgets) {
    var MyWidgetView = widgets.DOMWidgetView.extend({
        render: function() {
            console.log("render");
            MyWidgetView.__super__.render.apply(this, arguments);
            this._count_changed();
            this.listenTo(this.model, 'change:count', this._count_changed, this);
            
        },

        _count_changed: function() {
            var old_value = this.model.previous('count');
            var new_value = this.model.get('count');
            this.el.textContent = String(old_value) + ' -> ' + String(new_value);
        }
    });

    return {
        MyWidgetView: MyWidgetView
    }
});

Finally:

m = MyWidget()
m.count = 2
m

Expected behaviour

Javascript console should print "render" and cell output area should show "0 -> 2".

Context

  • OSX
  • Chrome (Version 108.0.5359.124 )
  • Jupyter Notebook Version: 6.4.12
@audunsh audunsh added the Custom Widget Issues related to using ipywidgets as a framework for custom widgets label Dec 20, 2022
@maartenbreddels
Copy link
Member

Hi,

make sure to use ES6 classes. I'm surprised your code actually runs, I had to do this:

%%javascript
require.undef('mywidget') // force reloading when executing cell twice
define('mywidget', ['@jupyter-widgets/base'], function(widgets) {
    class MyWidgetView extends widgets.DOMWidgetView {
        render() {
            console.log("render");
            super.render();
            this._count_changed();
            this.listenTo(this.model, 'change:count', this._count_changed, this);
            
        }

        _count_changed() {
            var old_value = this.model.previous('count');
            var new_value = this.model.get('count');
            this.el.textContent = String(old_value) + ' -> ' + String(new_value);
        }
    };

    return {
        MyWidgetView: MyWidgetView
    }
});

Also, please downgrade ipykernel to < 6.18, or wait for ipython/ipykernel#1061 to be released.

Let me know if that helps!

@dealmeida-h
Copy link

Hi,

I'm having a similar problem, I had a code that used to run fine using ipywidgets 7.7, but now it won't work with ipywidgets 8. I see that the code was using the same structure as OP's code (using var MyWidgetView = widgets.DOMWidgetView.extend instead of class). However, even if I try to make the changes proposed by @maartenbreddels, I'm still unable to create a view (console error is: TypeError: Class constructor O cannot be invoked without 'new'). Any insights on this error? Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Custom Widget Issues related to using ipywidgets as a framework for custom widgets
Projects
None yet
Development

No branches or pull requests

3 participants