ipywidgets: Error with 8.0.5 when selecting ipytree node

Description

I have an ipytree widget in Jupyterlab, and on clicking a node of it getting errors:

Error serializing widget state attribute: selected_nodes serialize @ 595.7f2125f3d2c7376588c2.js?v=7f2125f3d2c7376588c2:1 sync @ 595.7f2125f3d2c7376588c2.js?v=7f2125f3d2c7376588c2:1 save @ 644.7d1bff49f8e38fac4070.js?v=7d1bff49f8e38fac4070:1 save_changes @ 595.7f2125f3d2c7376588c2.js?v=7f2125f3d2c7376588c2:1 (anonymous) @ 568.c44c0ae4f70f7df0fe86.js?v=c44c0ae4f70f7df0fe86:1 dispatch @ 755.71bcc770291b01d6ebaa.js?v=71bcc770291b01d6ebaa:2 v.handle @ 755.71bcc770291b01d6ebaa.js?v=71bcc770291b01d6ebaa:2 trigger @ 755.71bcc770291b01d6ebaa.js?v=71bcc770291b01d6ebaa:2 triggerHandler @ 755.71bcc770291b01d6ebaa.js?v=71bcc770291b01d6ebaa:2 trigger @ 287.fd063a1253f3266560f7.js?v=fd063a1253f3266560f7:2 select_node @ 287.fd063a1253f3266560f7.js?v=fd063a1253f3266560f7:2 activate_node @ 287.fd063a1253f3266560f7.js?v=fd063a1253f3266560f7:2 (anonymous) @ 287.fd063a1253f3266560f7.js?v=fd063a1253f3266560f7:2 dispatch @ 755.71bcc770291b01d6ebaa.js?v=71bcc770291b01d6ebaa:2 v.handle @ 755.71bcc770291b01d6ebaa.js?v=71bcc770291b01d6ebaa:2 Uncaught DOMException: Failed to execute ‘structuredClone’ on ‘Window’: #<Promise> could not be cloned.

Reproduce

In Jupyterlab (3.4.5):

from ipytree import Node, Tree

tree = Tree() subtree = Node() tree.add_node(subtree) subtree.add_node(Node()) tree

Expected behavior

Context

When downgrading to ipywidgets==8.0.4 and jupyterlab_widgets==3.0.5 versions the widget works as expected without errors.

Troubleshoot Output
Paste the output from running `jupyter troubleshoot` from the command line here.
You may want to sanitize the paths in the output.
Command Line Output
Paste the output from your command line running `jupyter lab` (or `jupyter notebook` if you use notebook) here, use `--debug` if possible.
Browser Output
Paste the output from your browser Javascript console here.

If using JupyterLab

  • JupyterLab version:
Installed Labextensions
JupyterLab v3.4.5
/opt/conda/share/jupyter/labextensions
        jupyterlab_pygments v0.2.2 enabled OK (python, jupyterlab_pygments)
        jupyter-offlinenotebook v0.2.2 enabled OK
        ipytree v0.2.2 enabled OK
        ipylab v0.6.0 enabled OK (python, ipylab)
        @jupyterlab/plugin-playground v0.3.0 enabled OK (python, jupyterlab-plugin-playground)
        @jupyter-widgets/jupyterlab-manager v5.0.6 enabled OK (python, jupyterlab_widgets)

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Comments: 20 (20 by maintainers)

Most upvoted comments

Can we please revert out of using structuredClone? Then we can subsequently look at different alternatives for adding support for dataviews in a backwards compatible manner?

The following is broken since https://github.com/jupyter-widgets/ipywidgets/pull/3689:

  • box widget in core ipywidgets
  • draw control in ipyleaflet
  • the renderer of pythreejs
  • ipytree

As a result, I also would be in favor of reverting the PR in a patch release of ipywidgets.

Does that sound good to everyone? Also pinging @ibdafna @mwcraig for opinions

Note that this also broke pythreejs, as it uses its own deserializer like this:

https://github.com/jupyter-widgets/pythreejs/blob/584fe393ff593319ce33cd53dd94c8625aa01c88/js/src/_base/serializers.js#L6-L59

Since the fix in #3738 checks equality directly against unpack_models, that fix doesn’t work for pythreejs, meaning that many calls to serialize it fails, since it was also relying on the toJSON behavior of widgets. I’m also not confident in the ability of pack_models to work reliably, since it is non-trivial to traverse contained references in its serialized state. Can we please revert out of using structuredClone? Then we can subsequently look at different alternatives for adding support for dataviews in a backwards compatible manner?

JS never sets the value on the model

Counterpoint: any library (or user) use of jslink or jsdlink, frequently used to improve responsiveness. This fails with the same error:

from ipywidgets import *
slider = FloatSlider()
box1 = HBox([slider])
box2 = VBox([])
jslink((box1, "children"), (box2, "children"))

The strawman is looking fine, for something i wrote through the github code editing ui:

I don’t think it’s safe to assume that toJSON will work for all the cases, hence the complexity of mirroring the structure of unpack_models.

Here’s a strawman PR: might not be able to bring it home, but do intend to check on binder/lite…

Making every downstream package update on a point release because “our old implementation was suspect,” seems like… an unfriendly move.

Can we restore the appearance of the old behavior, and get the new benefits? Basically, if deserialize === unpack_models is defined, and serialize == null, then use something like the above (except, perhaps, in a dump for loop that doesn’t create excessive anonymous functions).