##// END OF EJS Templates
Merge pull request #7554 from jdfreder/interact-fix...
Min RK -
r20261:6bf6e5ac merge
parent child Browse files
Show More
@@ -14,7 +14,7 b' from inspect import getcallargs'
14 from IPython.core.getipython import get_ipython
14 from IPython.core.getipython import get_ipython
15 from IPython.html.widgets import (Widget, Text,
15 from IPython.html.widgets import (Widget, Text,
16 FloatSlider, IntSlider, Checkbox, Dropdown,
16 FloatSlider, IntSlider, Checkbox, Dropdown,
17 Box, Button, DOMWidget)
17 Box, Button, DOMWidget, Output)
18 from IPython.display import display, clear_output
18 from IPython.display import display, clear_output
19 from IPython.utils.py3compat import string_types, unicode_type
19 from IPython.utils.py3compat import string_types, unicode_type
20 from IPython.utils.traitlets import HasTraits, Any, Unicode
20 from IPython.utils.traitlets import HasTraits, Any, Unicode
@@ -204,29 +204,34 b' def interactive(__interact_f, **kwargs):'
204 if manual:
204 if manual:
205 manual_button = Button(description="Run %s" % f.__name__)
205 manual_button = Button(description="Run %s" % f.__name__)
206 c.append(manual_button)
206 c.append(manual_button)
207
208 # Use an output widget to capture the output of interact.
209 output = Output()
210 c.append(output)
207 container.children = c
211 container.children = c
208
212
209 # Build the callback
213 # Build the callback
210 def call_f(name=None, old=None, new=None):
214 def call_f(name=None, old=None, new=None):
211 container.kwargs = {}
215 with output:
212 for widget in kwargs_widgets:
216 container.kwargs = {}
213 value = widget.value
217 for widget in kwargs_widgets:
214 container.kwargs[widget._kwarg] = value
218 value = widget.value
215 if co:
219 container.kwargs[widget._kwarg] = value
216 clear_output(wait=True)
220 if co:
217 if manual:
221 clear_output(wait=True)
218 manual_button.disabled = True
219 try:
220 container.result = f(**container.kwargs)
221 except Exception as e:
222 ip = get_ipython()
223 if ip is None:
224 container.log.warn("Exception in interact callback: %s", e, exc_info=True)
225 else:
226 ip.showtraceback()
227 finally:
228 if manual:
222 if manual:
229 manual_button.disabled = False
223 manual_button.disabled = True
224 try:
225 container.result = f(**container.kwargs)
226 except Exception as e:
227 ip = get_ipython()
228 if ip is None:
229 container.log.warn("Exception in interact callback: %s", e, exc_info=True)
230 else:
231 ip.showtraceback()
232 finally:
233 if manual:
234 manual_button.disabled = False
230
235
231 # Wire up the widgets
236 # Wire up the widgets
232 # If we are doing manual running, the callback is only triggered by the button
237 # If we are doing manual running, the callback is only triggered by the button
@@ -80,7 +80,8 b' def check_widgets(container, **to_check):'
80 # build a widget dictionary, so it matches
80 # build a widget dictionary, so it matches
81 widgets = {}
81 widgets = {}
82 for w in container.children:
82 for w in container.children:
83 widgets[w.description] = w
83 if hasattr(w, 'description'):
84 widgets[w.description] = w
84
85
85 for key, d in to_check.items():
86 for key, d in to_check.items():
86 nt.assert_in(key, widgets)
87 nt.assert_in(key, widgets)
@@ -138,7 +139,7 b' def test_single_value_float():'
138 def test_single_value_int():
139 def test_single_value_int():
139 for a in (1, 5, -3):
140 for a in (1, 5, -3):
140 c = interactive(f, a=a)
141 c = interactive(f, a=a)
141 nt.assert_equal(len(c.children), 1)
142 nt.assert_equal(len(c.children), 2)
142 w = c.children[0]
143 w = c.children[0]
143 check_widget(w,
144 check_widget(w,
144 cls=widgets.IntSlider,
145 cls=widgets.IntSlider,
@@ -157,7 +158,7 b' def test_list_tuple_2_int():'
157 c = interactive(f, tup=(1,-1))
158 c = interactive(f, tup=(1,-1))
158 for min, max in [ (0,1), (1,10), (1,2), (-5,5), (-20,-19) ]:
159 for min, max in [ (0,1), (1,10), (1,2), (-5,5), (-20,-19) ]:
159 c = interactive(f, tup=(min, max), lis=[min, max])
160 c = interactive(f, tup=(min, max), lis=[min, max])
160 nt.assert_equal(len(c.children), 2)
161 nt.assert_equal(len(c.children), 3)
161 d = dict(
162 d = dict(
162 cls=widgets.IntSlider,
163 cls=widgets.IntSlider,
163 min=min,
164 min=min,
@@ -174,7 +175,7 b' def test_list_tuple_3_int():'
174 c = interactive(f, tup=(1,2,-1))
175 c = interactive(f, tup=(1,2,-1))
175 for min, max, step in [ (0,2,1), (1,10,2), (1,100,2), (-5,5,4), (-100,-20,4) ]:
176 for min, max, step in [ (0,2,1), (1,10,2), (1,100,2), (-5,5,4), (-100,-20,4) ]:
176 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
177 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
177 nt.assert_equal(len(c.children), 2)
178 nt.assert_equal(len(c.children), 3)
178 d = dict(
179 d = dict(
179 cls=widgets.IntSlider,
180 cls=widgets.IntSlider,
180 min=min,
181 min=min,
@@ -191,7 +192,7 b' def test_list_tuple_2_float():'
191 c = interactive(f, tup=(0.5,-0.5))
192 c = interactive(f, tup=(0.5,-0.5))
192 for min, max in [ (0.5, 1.5), (1.1,10.2), (1,2.2), (-5.,5), (-20,-19.) ]:
193 for min, max in [ (0.5, 1.5), (1.1,10.2), (1,2.2), (-5.,5), (-20,-19.) ]:
193 c = interactive(f, tup=(min, max), lis=[min, max])
194 c = interactive(f, tup=(min, max), lis=[min, max])
194 nt.assert_equal(len(c.children), 2)
195 nt.assert_equal(len(c.children), 3)
195 d = dict(
196 d = dict(
196 cls=widgets.FloatSlider,
197 cls=widgets.FloatSlider,
197 min=min,
198 min=min,
@@ -210,7 +211,7 b' def test_list_tuple_3_float():'
210 c = interactive(f, tup=(1,2.,-1.))
211 c = interactive(f, tup=(1,2.,-1.))
211 for min, max, step in [ (0.,2,1), (1,10.,2), (1,100,2.), (-5.,5.,4), (-100,-20.,4.) ]:
212 for min, max, step in [ (0.,2,1), (1,10.,2), (1,100,2.), (-5.,5.,4), (-100,-20.,4.) ]:
212 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
213 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
213 nt.assert_equal(len(c.children), 2)
214 nt.assert_equal(len(c.children), 3)
214 d = dict(
215 d = dict(
215 cls=widgets.FloatSlider,
216 cls=widgets.FloatSlider,
216 min=min,
217 min=min,
@@ -224,7 +225,7 b' def test_list_tuple_str():'
224 values = ['hello', 'there', 'guy']
225 values = ['hello', 'there', 'guy']
225 first = values[0]
226 first = values[0]
226 c = interactive(f, tup=tuple(values), lis=list(values))
227 c = interactive(f, tup=tuple(values), lis=list(values))
227 nt.assert_equal(len(c.children), 2)
228 nt.assert_equal(len(c.children), 3)
228 d = dict(
229 d = dict(
229 cls=widgets.Dropdown,
230 cls=widgets.Dropdown,
230 value=first,
231 value=first,
@@ -471,7 +472,7 b' def test_call_decorated_kwargs_on_trait_change():'
471
472
472 def test_fixed():
473 def test_fixed():
473 c = interactive(f, a=widgets.fixed(5), b='text')
474 c = interactive(f, a=widgets.fixed(5), b='text')
474 nt.assert_equal(len(c.children), 1)
475 nt.assert_equal(len(c.children), 2)
475 w = c.children[0]
476 w = c.children[0]
476 check_widget(w,
477 check_widget(w,
477 cls=widgets.Text,
478 cls=widgets.Text,
@@ -34,43 +34,53 b' class Output(DOMWidget):'
34 print('prints to output widget')"""
34 print('prints to output widget')"""
35 _view_name = Unicode('OutputView', sync=True)
35 _view_name = Unicode('OutputView', sync=True)
36
36
37 def __init__(self, *args, **kwargs):
38 super(Output, self).__init__(*args, **kwargs)
39 from IPython import get_ipython
40 ip = get_ipython()
41 if ip is not None and hasattr(ip, 'kernel'):
42 self._kernel = ip.kernel
43 else:
44 self._kernel = None
45
37 def clear_output(self, *pargs, **kwargs):
46 def clear_output(self, *pargs, **kwargs):
38 with self:
47 with self:
39 clear_output(*pargs, **kwargs)
48 clear_output(*pargs, **kwargs)
40
49
41 def __enter__(self):
50 def __enter__(self):
42 """Called upon entering output widget context manager."""
51 """Called upon entering output widget context manager."""
43 self._flush()
52 if self._kernel is not None:
44 kernel = get_ipython().kernel
53 self._flush()
45 session = kernel.session
54 session = self._kernel.session
46 send = session.send
55 send = session.send
47 self._original_send = send
56 self._original_send = send
48 self._session = session
57 self._session = session
49
58
50 def send_hook(stream, msg_or_type, content=None, parent=None, ident=None,
59 def send_hook(stream, msg_or_type, content=None, parent=None, ident=None,
51 buffers=None, track=False, header=None, metadata=None):
60 buffers=None, track=False, header=None, metadata=None):
52
61
53 # Handle both prebuild messages and unbuilt messages.
62 # Handle both prebuild messages and unbuilt messages.
54 if isinstance(msg_or_type, (Message, dict)):
63 if isinstance(msg_or_type, (Message, dict)):
55 msg_type = msg_or_type['msg_type']
64 msg_type = msg_or_type['msg_type']
56 msg = dict(msg_or_type)
65 msg = dict(msg_or_type)
57 else:
66 else:
58 msg_type = msg_or_type
67 msg_type = msg_or_type
59 msg = session.msg(msg_type, content=content, parent=parent,
68 msg = session.msg(msg_type, content=content, parent=parent,
60 header=header, metadata=metadata)
69 header=header, metadata=metadata)
61
70
62 # If this is a message type that we want to forward, forward it.
71 # If this is a message type that we want to forward, forward it.
63 if stream is kernel.iopub_socket and msg_type in ['clear_output', 'stream', 'display_data']:
72 if stream is self._kernel.iopub_socket and msg_type in ['clear_output', 'stream', 'display_data']:
64 self.send(msg)
73 self.send(msg)
65 else:
74 else:
66 send(stream, msg, ident=ident, buffers=buffers, track=track)
75 send(stream, msg, ident=ident, buffers=buffers, track=track)
67
76
68 session.send = send_hook
77 session.send = send_hook
69
78
70 def __exit__(self, exception_type, exception_value, traceback):
79 def __exit__(self, exception_type, exception_value, traceback):
71 """Called upon exiting output widget context manager."""
80 """Called upon exiting output widget context manager."""
72 self._flush()
81 if self._kernel is not None:
73 self._session.send = self._original_send
82 self._flush()
83 self._session.send = self._original_send
74
84
75 def _flush(self):
85 def _flush(self):
76 """Flush stdout and stderr buffers."""
86 """Flush stdout and stderr buffers."""
General Comments 0
You need to be logged in to leave comments. Login now