From 7ae97acc96ce9f78bd43dbd0778cd7db36804966 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Tue, 27 Mar 2018 14:10:28 -0700 Subject: [PATCH 1/3] Use _repr_mimebundle_ instead of _ipython_display Fixes #1811 --- ipywidgets/widgets/interaction.py | 3 +-- ipywidgets/widgets/widget.py | 33 ++++--------------------------- ipywidgets/widgets/widget_box.py | 6 ------ 3 files changed, 5 insertions(+), 37 deletions(-) diff --git a/ipywidgets/widgets/interaction.py b/ipywidgets/widgets/interaction.py index 3dd7272047..209b715a72 100644 --- a/ipywidgets/widgets/interaction.py +++ b/ipywidgets/widgets/interaction.py @@ -214,8 +214,7 @@ def __init__(self, __interact_f, __options={}, **kwargs): else: for widget in self.kwargs_widgets: widget.observe(self.update, names='value') - - self.on_displayed(self.update) + self.update() # Callback function def update(self, *args): diff --git a/ipywidgets/widgets/widget.py b/ipywidgets/widgets/widget.py index 1a3d9357aa..d26f38b5a3 100644 --- a/ipywidgets/widgets/widget.py +++ b/ipywidgets/widgets/widget.py @@ -13,7 +13,6 @@ from traitlets import ( HasTraits, Unicode, Dict, Instance, List, Int, Set, Bytes, observe, default, Container, Undefined) -from IPython.display import display from json import loads as jsonloads, dumps as jsondumps from base64 import standard_b64encode @@ -381,7 +380,6 @@ def _default_keys(self): _property_lock = Dict() _holding_sync = False _states_to_send = Set() - _display_callbacks = Instance(CallbackDispatcher, ()) _msg_callbacks = Instance(CallbackDispatcher, ()) #------------------------------------------------------------------------- @@ -449,7 +447,7 @@ def close(self): Widget.widgets.pop(self.model_id, None) self.comm.close() self.comm = None - self._ipython_display_ = None + self._repr_mimebundle_ = None def send_state(self, key=None): """Sends the widget state, or a piece of it, to the front-end, if it exists. @@ -549,21 +547,6 @@ def on_msg(self, callback, remove=False): True if the callback should be unregistered.""" self._msg_callbacks.register_callback(callback, remove=remove) - def on_displayed(self, callback, remove=False): - """(Un)Register a widget displayed callback. - - Parameters - ---------- - callback: method handler - Must have a signature of:: - - callback(widget, **kwargs) - - kwargs from display are passed through without modification. - remove: bool - True if the callback should be unregistered.""" - self._display_callbacks.register_callback(callback, remove=remove) - def add_traits(self, **traits): """Dynamically add trait attributes to the Widget.""" super().add_traits(**traits) @@ -671,10 +654,6 @@ def _handle_custom_msg(self, content, buffers): """Called when a custom msg is received.""" self._msg_callbacks(self, content, buffers) - def _handle_displayed(self, **kwargs): - """Called when a view has been displayed for this widget instance""" - self._display_callbacks(self, **kwargs) - @staticmethod def _trait_to_json(x, self): """Convert a trait value to json.""" @@ -685,9 +664,8 @@ def _trait_from_json(x, self): """Convert json values to objects.""" return x - def _ipython_display_(self, **kwargs): - """Called when `IPython.display.display` is called on the widget.""" - + def _repr_mimebundle_(self, **kwargs): + """Called when `IPython.display.display` is called.""" plaintext = repr(self) if len(plaintext) > 110: plaintext = plaintext[:110] + '…' @@ -705,10 +683,7 @@ def _ipython_display_(self, **kwargs): 'version_minor': 0, 'model_id': self._model_id } - display(data, raw=True) - - if self._view_name is not None: - self._handle_displayed(**kwargs) + return data def _send(self, msg, buffers=None): """Sends a message to the model in the front-end.""" diff --git a/ipywidgets/widgets/widget_box.py b/ipywidgets/widgets/widget_box.py index 28a9d71f42..740e54cb1a 100644 --- a/ipywidgets/widgets/widget_box.py +++ b/ipywidgets/widgets/widget_box.py @@ -62,12 +62,6 @@ class Box(DOMWidget, CoreWidget): def __init__(self, children=(), **kwargs): kwargs['children'] = children super().__init__(**kwargs) - self.on_displayed(Box._fire_children_displayed) - - def _fire_children_displayed(self): - for child in self.children: - child._handle_displayed() - @register @doc_subst(_doc_snippets) From 7dd601bad68a2f219e9531caa7eaa09e15b1b9c4 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Tue, 31 Dec 2019 10:09:16 -0800 Subject: [PATCH 2/3] require at least ipython 6.1 so we can use _repr_mimebundle --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d90cf50ef7..c1ee5b6273 100644 --- a/setup.py +++ b/setup.py @@ -108,6 +108,7 @@ setuptools_args = {} install_requires = setuptools_args['install_requires'] = [ 'ipykernel>=4.5.1', + 'ipython>=6.1.0', # to use _repr_mimebundle 'traitlets>=4.3.1', # Requiring nbformat to specify bugfix version which is not required by # notebook. @@ -120,7 +121,6 @@ ] extras_require = setuptools_args['extras_require'] = { - '': ['ipython>=4.0.0'], 'test': ['pytest>=3.6.0', 'pytest-cov'], } From 1fb8776e02e5a4929d398f3ed75ec32859b3aeca Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Tue, 31 Dec 2019 12:04:56 -0800 Subject: [PATCH 3/3] Fix test failures --- ipywidgets/widgets/tests/test_interaction.py | 12 ++++++------ ipywidgets/widgets/tests/utils.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ipywidgets/widgets/tests/test_interaction.py b/ipywidgets/widgets/tests/test_interaction.py index 1ee946744e..6e0f61c35d 100644 --- a/ipywidgets/widgets/tests/test_interaction.py +++ b/ipywidgets/widgets/tests/test_interaction.py @@ -472,8 +472,8 @@ def test_call_decorated_on_trait_change(clear_display): def foo(a='default'): d['a'] = a return a - assert len(displayed) == 1 - w = displayed[0].children[0] + assert len(displayed) == 2 # display the result and the interact + w = displayed[1].children[0] check_widget(w, cls=widgets.Text, value='default', @@ -487,7 +487,7 @@ def foo(a='default'): with patch.object(interaction, 'display', record_display): w.value = 'called' assert d['a'] == 'called' - assert len(displayed) == 2 + assert len(displayed) == 3 assert w.value == displayed[-1] def test_call_decorated_kwargs_on_trait_change(clear_display): @@ -498,8 +498,8 @@ def test_call_decorated_kwargs_on_trait_change(clear_display): def foo(a='default'): d['a'] = a return a - assert len(displayed) == 1 - w = displayed[0].children[0] + assert len(displayed) == 2 # display the result and the interact + w = displayed[1].children[0] check_widget(w, cls=widgets.Text, value='kwarg', @@ -513,7 +513,7 @@ def foo(a='default'): with patch.object(interaction, 'display', record_display): w.value = 'called' assert d['a'] == 'called' - assert len(displayed) == 2 + assert len(displayed) == 3 assert w.value == displayed[-1] diff --git a/ipywidgets/widgets/tests/utils.py b/ipywidgets/widgets/tests/utils.py index 8553852f16..11a971de8a 100644 --- a/ipywidgets/widgets/tests/utils.py +++ b/ipywidgets/widgets/tests/utils.py @@ -27,10 +27,10 @@ def close(self, *args, **kwargs): def setup_test_comm(): _widget_attrs['_comm_default'] = getattr(Widget, '_comm_default', undefined) Widget._comm_default = lambda self: DummyComm() - _widget_attrs['_ipython_display_'] = Widget._ipython_display_ + _widget_attrs['_repr_mimebundle_'] = Widget._repr_mimebundle_ def raise_not_implemented(*args, **kwargs): raise NotImplementedError() - Widget._ipython_display_ = raise_not_implemented + Widget._repr_mimebundle_ = raise_not_implemented def teardown_test_comm(): for attr, value in _widget_attrs.items():