##// 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 14 from IPython.core.getipython import get_ipython
15 15 from IPython.html.widgets import (Widget, Text,
16 16 FloatSlider, IntSlider, Checkbox, Dropdown,
17 Box, Button, DOMWidget)
17 Box, Button, DOMWidget, Output)
18 18 from IPython.display import display, clear_output
19 19 from IPython.utils.py3compat import string_types, unicode_type
20 20 from IPython.utils.traitlets import HasTraits, Any, Unicode
@@ -204,29 +204,34 b' def interactive(__interact_f, **kwargs):'
204 204 if manual:
205 205 manual_button = Button(description="Run %s" % f.__name__)
206 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 211 container.children = c
208 212
209 213 # Build the callback
210 214 def call_f(name=None, old=None, new=None):
211 container.kwargs = {}
212 for widget in kwargs_widgets:
213 value = widget.value
214 container.kwargs[widget._kwarg] = value
215 if co:
216 clear_output(wait=True)
217 if manual:
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:
215 with output:
216 container.kwargs = {}
217 for widget in kwargs_widgets:
218 value = widget.value
219 container.kwargs[widget._kwarg] = value
220 if co:
221 clear_output(wait=True)
228 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 236 # Wire up the widgets
232 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 80 # build a widget dictionary, so it matches
81 81 widgets = {}
82 82 for w in container.children:
83 widgets[w.description] = w
83 if hasattr(w, 'description'):
84 widgets[w.description] = w
84 85
85 86 for key, d in to_check.items():
86 87 nt.assert_in(key, widgets)
@@ -138,7 +139,7 b' def test_single_value_float():'
138 139 def test_single_value_int():
139 140 for a in (1, 5, -3):
140 141 c = interactive(f, a=a)
141 nt.assert_equal(len(c.children), 1)
142 nt.assert_equal(len(c.children), 2)
142 143 w = c.children[0]
143 144 check_widget(w,
144 145 cls=widgets.IntSlider,
@@ -157,7 +158,7 b' def test_list_tuple_2_int():'
157 158 c = interactive(f, tup=(1,-1))
158 159 for min, max in [ (0,1), (1,10), (1,2), (-5,5), (-20,-19) ]:
159 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 162 d = dict(
162 163 cls=widgets.IntSlider,
163 164 min=min,
@@ -174,7 +175,7 b' def test_list_tuple_3_int():'
174 175 c = interactive(f, tup=(1,2,-1))
175 176 for min, max, step in [ (0,2,1), (1,10,2), (1,100,2), (-5,5,4), (-100,-20,4) ]:
176 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 179 d = dict(
179 180 cls=widgets.IntSlider,
180 181 min=min,
@@ -191,7 +192,7 b' def test_list_tuple_2_float():'
191 192 c = interactive(f, tup=(0.5,-0.5))
192 193 for min, max in [ (0.5, 1.5), (1.1,10.2), (1,2.2), (-5.,5), (-20,-19.) ]:
193 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 196 d = dict(
196 197 cls=widgets.FloatSlider,
197 198 min=min,
@@ -210,7 +211,7 b' def test_list_tuple_3_float():'
210 211 c = interactive(f, tup=(1,2.,-1.))
211 212 for min, max, step in [ (0.,2,1), (1,10.,2), (1,100,2.), (-5.,5.,4), (-100,-20.,4.) ]:
212 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 215 d = dict(
215 216 cls=widgets.FloatSlider,
216 217 min=min,
@@ -224,7 +225,7 b' def test_list_tuple_str():'
224 225 values = ['hello', 'there', 'guy']
225 226 first = values[0]
226 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 229 d = dict(
229 230 cls=widgets.Dropdown,
230 231 value=first,
@@ -471,7 +472,7 b' def test_call_decorated_kwargs_on_trait_change():'
471 472
472 473 def test_fixed():
473 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 476 w = c.children[0]
476 477 check_widget(w,
477 478 cls=widgets.Text,
@@ -34,43 +34,53 b' class Output(DOMWidget):'
34 34 print('prints to output widget')"""
35 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 46 def clear_output(self, *pargs, **kwargs):
38 47 with self:
39 48 clear_output(*pargs, **kwargs)
40 49
41 50 def __enter__(self):
42 51 """Called upon entering output widget context manager."""
43 self._flush()
44 kernel = get_ipython().kernel
45 session = kernel.session
46 send = session.send
47 self._original_send = send
48 self._session = session
49
50 def send_hook(stream, msg_or_type, content=None, parent=None, ident=None,
51 buffers=None, track=False, header=None, metadata=None):
52
53 # Handle both prebuild messages and unbuilt messages.
54 if isinstance(msg_or_type, (Message, dict)):
55 msg_type = msg_or_type['msg_type']
56 msg = dict(msg_or_type)
57 else:
58 msg_type = msg_or_type
59 msg = session.msg(msg_type, content=content, parent=parent,
60 header=header, metadata=metadata)
61
62 # 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']:
64 self.send(msg)
65 else:
66 send(stream, msg, ident=ident, buffers=buffers, track=track)
67
68 session.send = send_hook
52 if self._kernel is not None:
53 self._flush()
54 session = self._kernel.session
55 send = session.send
56 self._original_send = send
57 self._session = session
58
59 def send_hook(stream, msg_or_type, content=None, parent=None, ident=None,
60 buffers=None, track=False, header=None, metadata=None):
61
62 # Handle both prebuild messages and unbuilt messages.
63 if isinstance(msg_or_type, (Message, dict)):
64 msg_type = msg_or_type['msg_type']
65 msg = dict(msg_or_type)
66 else:
67 msg_type = msg_or_type
68 msg = session.msg(msg_type, content=content, parent=parent,
69 header=header, metadata=metadata)
70
71 # If this is a message type that we want to forward, forward it.
72 if stream is self._kernel.iopub_socket and msg_type in ['clear_output', 'stream', 'display_data']:
73 self.send(msg)
74 else:
75 send(stream, msg, ident=ident, buffers=buffers, track=track)
76
77 session.send = send_hook
69 78
70 79 def __exit__(self, exception_type, exception_value, traceback):
71 80 """Called upon exiting output widget context manager."""
72 self._flush()
73 self._session.send = self._original_send
81 if self._kernel is not None:
82 self._flush()
83 self._session.send = self._original_send
74 84
75 85 def _flush(self):
76 86 """Flush stdout and stderr buffers."""
General Comments 0
You need to be logged in to leave comments. Login now