##// END OF EJS Templates
set default value from signature defaults in interact...
MinRK -
Show More
@@ -26,7 +26,9 b' from IPython.html.widgets import (Widget, TextWidget,'
26 ContainerWidget, DOMWidget)
26 ContainerWidget, DOMWidget)
27 from IPython.display import display, clear_output
27 from IPython.display import display, clear_output
28 from IPython.utils.py3compat import string_types, unicode_type
28 from IPython.utils.py3compat import string_types, unicode_type
29 from IPython.utils.traitlets import HasTraits, Any, Unicode
29 from IPython.utils.traitlets import HasTraits, TraitError, Any, Unicode
30
31 empty = Parameter.empty
30
32
31 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
32 # Classes and Functions
34 # Classes and Functions
@@ -108,12 +110,20 b' def _widget_abbrev(o):'
108 else:
110 else:
109 return _widget_abbrev_single_value(o)
111 return _widget_abbrev_single_value(o)
110
112
111 def _widget_from_abbrev(abbrev):
113 def _widget_from_abbrev(abbrev, default=empty):
112 """Build a Widget intstance given an abbreviation or Widget."""
114 """Build a Widget instance given an abbreviation or Widget."""
113 if isinstance(abbrev, Widget) or isinstance(abbrev, fixed):
115 if isinstance(abbrev, Widget) or isinstance(abbrev, fixed):
114 return abbrev
116 return abbrev
115
117
116 widget = _widget_abbrev(abbrev)
118 widget = _widget_abbrev(abbrev)
119 if default is not empty and isinstance(abbrev, (list, tuple)):
120 # if it's not a single-value abbreviation,
121 # set the initial value from the default
122 try:
123 widget.value = default
124 except TraitError:
125 # warn?
126 pass
117 if widget is None:
127 if widget is None:
118 raise ValueError("%r cannot be transformed to a Widget" % (abbrev,))
128 raise ValueError("%r cannot be transformed to a Widget" % (abbrev,))
119 return widget
129 return widget
@@ -124,50 +134,38 b' def _yield_abbreviations_for_parameter(param, kwargs):'
124 kind = param.kind
134 kind = param.kind
125 ann = param.annotation
135 ann = param.annotation
126 default = param.default
136 default = param.default
127 empty = Parameter.empty
137 not_found = (name, empty, empty)
128 not_found = (None, None)
138 if kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY):
129 if kind == Parameter.POSITIONAL_OR_KEYWORD:
130 if name in kwargs:
131 yield name, kwargs.pop(name)
132 elif ann is not empty:
133 if default is empty:
134 yield name, ann
135 else:
136 yield name, ann
137 elif default is not empty:
138 yield name, default
139 else:
140 yield not_found
141 elif kind == Parameter.KEYWORD_ONLY:
142 if name in kwargs:
139 if name in kwargs:
143 yield name, kwargs.pop(name)
140 value = kwargs.pop(name)
144 elif ann is not empty:
141 elif ann is not empty:
145 yield name, ann
142 value = ann
146 elif default is not empty:
143 elif default is not empty:
147 yield name, default
144 value = default
148 else:
145 else:
149 yield not_found
146 yield not_found
147 yield (name, value, default)
150 elif kind == Parameter.VAR_KEYWORD:
148 elif kind == Parameter.VAR_KEYWORD:
151 # In this case name=kwargs and we yield the items in kwargs with their keys.
149 # In this case name=kwargs and we yield the items in kwargs with their keys.
152 for k, v in kwargs.copy().items():
150 for k, v in kwargs.copy().items():
153 kwargs.pop(k)
151 kwargs.pop(k)
154 yield k, v
152 yield k, v, empty
155
153
156 def _find_abbreviations(f, kwargs):
154 def _find_abbreviations(f, kwargs):
157 """Find the abbreviations for a function and kwargs passed to interact."""
155 """Find the abbreviations for a function and kwargs passed to interact."""
158 new_kwargs = []
156 new_kwargs = []
159 for param in signature(f).parameters.values():
157 for param in signature(f).parameters.values():
160 for name, value in _yield_abbreviations_for_parameter(param, kwargs):
158 for name, value, default in _yield_abbreviations_for_parameter(param, kwargs):
161 if value is None:
159 if value is empty:
162 raise ValueError('cannot find widget or abbreviation for argument: {!r}'.format(name))
160 raise ValueError('cannot find widget or abbreviation for argument: {!r}'.format(name))
163 new_kwargs.append((name, value))
161 new_kwargs.append((name, value, default))
164 return new_kwargs
162 return new_kwargs
165
163
166 def _widgets_from_abbreviations(seq):
164 def _widgets_from_abbreviations(seq):
167 """Given a sequence of (name, abbrev) tuples, return a sequence of Widgets."""
165 """Given a sequence of (name, abbrev) tuples, return a sequence of Widgets."""
168 result = []
166 result = []
169 for name, abbrev in seq:
167 for name, abbrev, default in seq:
170 widget = _widget_from_abbrev(abbrev)
168 widget = _widget_from_abbrev(abbrev, default)
171 widget.description = name
169 widget.description = name
172 result.append(widget)
170 result.append(widget)
173 return result
171 return result
@@ -187,7 +185,7 b' def interactive(__interact_f, **kwargs):'
187 # Before we proceed, let's make sure that the user has passed a set of args+kwargs
185 # Before we proceed, let's make sure that the user has passed a set of args+kwargs
188 # that will lead to a valid call of the function. This protects against unspecified
186 # that will lead to a valid call of the function. This protects against unspecified
189 # and doubly-specified arguments.
187 # and doubly-specified arguments.
190 getcallargs(f, **{n:v for n,v in new_kwargs})
188 getcallargs(f, **{n:v for n,v,_ in new_kwargs})
191 # Now build the widgets from the abbreviations.
189 # Now build the widgets from the abbreviations.
192 kwargs_widgets.extend(_widgets_from_abbreviations(new_kwargs))
190 kwargs_widgets.extend(_widgets_from_abbreviations(new_kwargs))
193 kwargs_widgets.extend(_widgets_from_abbreviations(sorted(kwargs.items(), key = lambda x: x[0])))
191 kwargs_widgets.extend(_widgets_from_abbreviations(sorted(kwargs.items(), key = lambda x: x[0])))
@@ -22,7 +22,6 b' import IPython.testing.tools as tt'
22 from IPython.html import widgets
22 from IPython.html import widgets
23 from IPython.html.widgets import interact, interactive, Widget, interaction
23 from IPython.html.widgets import interact, interactive, Widget, interaction
24 from IPython.utils.py3compat import annotate
24 from IPython.utils.py3compat import annotate
25 # from IPython.utils.capture import capture_output
26
25
27 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
28 # Utility stuff
27 # Utility stuff
@@ -248,7 +247,7 b' def test_list_tuple_invalid():'
248
247
249 def test_defaults():
248 def test_defaults():
250 @annotate(n=10)
249 @annotate(n=10)
251 def f(n, f=4.5):
250 def f(n, f=4.5, g=1):
252 pass
251 pass
253
252
254 c = interactive(f)
253 c = interactive(f)
@@ -261,6 +260,31 b' def test_defaults():'
261 cls=widgets.FloatSliderWidget,
260 cls=widgets.FloatSliderWidget,
262 value=4.5,
261 value=4.5,
263 ),
262 ),
263 g=dict(
264 cls=widgets.IntSliderWidget,
265 value=1,
266 ),
267 )
268
269 def test_default_values():
270 @annotate(n=10, f=(0, 10.), g=5)
271 def f(n, f=4.5, g=1):
272 pass
273
274 c = interactive(f)
275 check_widgets(c,
276 n=dict(
277 cls=widgets.IntSliderWidget,
278 value=10,
279 ),
280 f=dict(
281 cls=widgets.FloatSliderWidget,
282 value=4.5,
283 ),
284 g=dict(
285 cls=widgets.IntSliderWidget,
286 value=5,
287 ),
264 )
288 )
265
289
266 def test_annotations():
290 def test_annotations():
General Comments 0
You need to be logged in to leave comments. Login now