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 in |
|
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 |
|
|
140 | value = kwargs.pop(name) | |
144 | elif ann is not empty: |
|
141 | elif ann is not empty: | |
145 |
|
|
142 | value = ann | |
146 | elif default is not empty: |
|
143 | elif default is not empty: | |
147 |
|
|
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 |
|
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