Skip to content

Commit

Permalink
Close #79: ipywidgets' Widget.comm field now uses Any() instead of In…
Browse files Browse the repository at this point in the history
…stance()
  • Loading branch information
cpsievert committed Mar 23, 2023
1 parent 1be8f20 commit 0721da7
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions shinywidgets/_shinywidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
from ipywidgets._version import (
__protocol_version__, # pyright: ignore[reportUnknownVariableType]
)

from ipywidgets.widgets.widget import (
Widget,
_remove_buffers, # pyright: ignore[reportUnknownVariableType, reportGeneralTypeIssues]
)
from shiny import Session, event, reactive
import traitlets

from shiny import Session, reactive
from shiny._utils import run_coro_sync, wrap_async
from shiny.http_staticfiles import StaticFiles
from shiny.render import RenderFunction, RenderFunctionAsync
Expand Down Expand Up @@ -67,13 +68,16 @@ def init_shiny_widget(w: Widget):
while hasattr(session, "_parent"):
session = session._parent

# `Widget` has `comm = Instance('ipykernel.comm.Comm')` which means we'd get a
# runtime error if we try to set this attribute to a different class, but
# fortunately this hack provides a workaround.
# TODO: find a better way to do this (maybe send a PR to ipywidgets?) or at least clean up after ourselves
# https://github.com/jupyter-widgets/ipywidgets/blob/88cec8b/python/ipywidgets/ipywidgets/widgets/widget.py#L424
old_comm_klass = copy.copy(Widget.comm.klass) # type: ignore
Widget.comm.klass = object # type: ignore
# Previous versions of ipywidgets (< 8.0.5) had
# `Widget.comm = Instance('ipykernel.comm.Comm')`
# which meant we'd get a runtime error when setting `Widget.comm = ShinyComm()`.
# In more recent versions, this is no longer necessary since they've (correctly)
# changed comm from an Instance() to Any().
# https://github.com/jupyter-widgets/ipywidgets/pull/3533/files#diff-522bb5e7695975cba0199c6a3d6df5be827035f4dc18ed6da22ac216b5615c77R482
old_comm_klass = None
if isinstance(Widget.comm, traitlets.traitlets.Instance): # type: ignore
old_comm_klass = copy.copy(Widget.comm.klass) # type: ignore
Widget.comm.klass = object # type: ignore

# Get the initial state of the widget
state, buffer_paths, buffers = _remove_buffers(w.get_state()) # type: ignore
Expand Down Expand Up @@ -137,7 +141,8 @@ def _():
comm.handle_msg(msg)

def _restore_state():
Widget.comm.klass = old_comm_klass # type: ignore
if old_comm_klass is not None:
Widget.comm.klass = old_comm_klass # type: ignore
SESSIONS.remove(session) # type: ignore

session.on_ended(_restore_state)
Expand Down

0 comments on commit 0721da7

Please sign in to comment.