Show More
The requested changes are too big and content was truncated. Show full diff
@@ -0,0 +1,251 b'' | |||
|
1 | """Interact with functions using widgets.""" | |
|
2 | ||
|
3 | #----------------------------------------------------------------------------- | |
|
4 | # Copyright (c) 2013, the IPython Development Team. | |
|
5 | # | |
|
6 | # Distributed under the terms of the Modified BSD License. | |
|
7 | # | |
|
8 | # The full license is in the file COPYING.txt, distributed with this software. | |
|
9 | #----------------------------------------------------------------------------- | |
|
10 | ||
|
11 | #----------------------------------------------------------------------------- | |
|
12 | # Imports | |
|
13 | #----------------------------------------------------------------------------- | |
|
14 | ||
|
15 | from __future__ import print_function | |
|
16 | ||
|
17 | try: # Python >= 3.3 | |
|
18 | from inspect import signature, Parameter | |
|
19 | except ImportError: | |
|
20 | from IPython.utils.signatures import signature, Parameter | |
|
21 | from inspect import getcallargs | |
|
22 | ||
|
23 | from IPython.html.widgets import (Widget, TextWidget, | |
|
24 | FloatSliderWidget, IntSliderWidget, CheckboxWidget, DropdownWidget, | |
|
25 | ContainerWidget, DOMWidget) | |
|
26 | from IPython.display import display, clear_output | |
|
27 | from IPython.utils.py3compat import string_types, unicode_type | |
|
28 | from IPython.utils.traitlets import HasTraits, Any, Unicode | |
|
29 | ||
|
30 | #----------------------------------------------------------------------------- | |
|
31 | # Classes and Functions | |
|
32 | #----------------------------------------------------------------------------- | |
|
33 | ||
|
34 | ||
|
35 | def _matches(o, pattern): | |
|
36 | """Match a pattern of types in a sequence.""" | |
|
37 | if not len(o) == len(pattern): | |
|
38 | return False | |
|
39 | comps = zip(o,pattern) | |
|
40 | return all(isinstance(obj,kind) for obj,kind in comps) | |
|
41 | ||
|
42 | ||
|
43 | def _get_min_max_value(min, max, value=None, step=None): | |
|
44 | """Return min, max, value given input values with possible None.""" | |
|
45 | if value is None: | |
|
46 | if not max > min: | |
|
47 | raise ValueError('max must be greater than min: (min={0}, max={1})'.format(min, max)) | |
|
48 | value = min + abs(min-max)/2 | |
|
49 | value = type(min)(value) | |
|
50 | elif min is None and max is None: | |
|
51 | if value == 0.0: | |
|
52 | min, max, value = 0.0, 1.0, 0.5 | |
|
53 | elif value == 0: | |
|
54 | min, max, value = 0, 1, 0 | |
|
55 | elif isinstance(value, (int, float)): | |
|
56 | min, max = (-value, 3*value) if value > 0 else (3*value, -value) | |
|
57 | else: | |
|
58 | raise TypeError('expected a number, got: %r' % value) | |
|
59 | else: | |
|
60 | raise ValueError('unable to infer range, value from: ({0}, {1}, {2})'.format(min, max, value)) | |
|
61 | if step is not None: | |
|
62 | # ensure value is on a step | |
|
63 | r = (value - min) % step | |
|
64 | value = value - r | |
|
65 | return min, max, value | |
|
66 | ||
|
67 | def _widget_abbrev_single_value(o): | |
|
68 | """Make widgets from single values, which can be used as parameter defaults.""" | |
|
69 | if isinstance(o, string_types): | |
|
70 | return TextWidget(value=unicode_type(o)) | |
|
71 | elif isinstance(o, dict): | |
|
72 | return DropdownWidget(values=o) | |
|
73 | elif isinstance(o, bool): | |
|
74 | return CheckboxWidget(value=o) | |
|
75 | elif isinstance(o, float): | |
|
76 | min, max, value = _get_min_max_value(None, None, o) | |
|
77 | return FloatSliderWidget(value=o, min=min, max=max) | |
|
78 | elif isinstance(o, int): | |
|
79 | min, max, value = _get_min_max_value(None, None, o) | |
|
80 | return IntSliderWidget(value=o, min=min, max=max) | |
|
81 | else: | |
|
82 | return None | |
|
83 | ||
|
84 | def _widget_abbrev(o): | |
|
85 | """Make widgets from abbreviations: single values, lists or tuples.""" | |
|
86 | float_or_int = (float, int) | |
|
87 | if isinstance(o, (list, tuple)): | |
|
88 | if o and all(isinstance(x, string_types) for x in o): | |
|
89 | return DropdownWidget(values=[unicode_type(k) for k in o]) | |
|
90 | elif _matches(o, (float_or_int, float_or_int)): | |
|
91 | min, max, value = _get_min_max_value(o[0], o[1]) | |
|
92 | if all(isinstance(_, int) for _ in o): | |
|
93 | cls = IntSliderWidget | |
|
94 | else: | |
|
95 | cls = FloatSliderWidget | |
|
96 | return cls(value=value, min=min, max=max) | |
|
97 | elif _matches(o, (float_or_int, float_or_int, float_or_int)): | |
|
98 | step = o[2] | |
|
99 | if step <= 0: | |
|
100 | raise ValueError("step must be >= 0, not %r" % step) | |
|
101 | min, max, value = _get_min_max_value(o[0], o[1], step=step) | |
|
102 | if all(isinstance(_, int) for _ in o): | |
|
103 | cls = IntSliderWidget | |
|
104 | else: | |
|
105 | cls = FloatSliderWidget | |
|
106 | return cls(value=value, min=min, max=max, step=step) | |
|
107 | else: | |
|
108 | return _widget_abbrev_single_value(o) | |
|
109 | ||
|
110 | def _widget_from_abbrev(abbrev): | |
|
111 | """Build a Widget intstance given an abbreviation or Widget.""" | |
|
112 | if isinstance(abbrev, Widget) or isinstance(abbrev, fixed): | |
|
113 | return abbrev | |
|
114 | ||
|
115 | widget = _widget_abbrev(abbrev) | |
|
116 | if widget is None: | |
|
117 | raise ValueError("%r cannot be transformed to a Widget" % (abbrev,)) | |
|
118 | return widget | |
|
119 | ||
|
120 | def _yield_abbreviations_for_parameter(param, kwargs): | |
|
121 | """Get an abbreviation for a function parameter.""" | |
|
122 | name = param.name | |
|
123 | kind = param.kind | |
|
124 | ann = param.annotation | |
|
125 | default = param.default | |
|
126 | empty = Parameter.empty | |
|
127 | not_found = (None, None) | |
|
128 | if kind == Parameter.POSITIONAL_OR_KEYWORD: | |
|
129 | if name in kwargs: | |
|
130 | yield name, kwargs.pop(name) | |
|
131 | elif ann is not empty: | |
|
132 | if default is empty: | |
|
133 | yield name, ann | |
|
134 | else: | |
|
135 | yield name, ann | |
|
136 | elif default is not empty: | |
|
137 | yield name, default | |
|
138 | else: | |
|
139 | yield not_found | |
|
140 | elif kind == Parameter.KEYWORD_ONLY: | |
|
141 | if name in kwargs: | |
|
142 | yield name, kwargs.pop(name) | |
|
143 | elif ann is not empty: | |
|
144 | yield name, ann | |
|
145 | elif default is not empty: | |
|
146 | yield name, default | |
|
147 | else: | |
|
148 | yield not_found | |
|
149 | elif kind == Parameter.VAR_KEYWORD: | |
|
150 | # In this case name=kwargs and we yield the items in kwargs with their keys. | |
|
151 | for k, v in kwargs.copy().items(): | |
|
152 | kwargs.pop(k) | |
|
153 | yield k, v | |
|
154 | ||
|
155 | def _find_abbreviations(f, kwargs): | |
|
156 | """Find the abbreviations for a function and kwargs passed to interact.""" | |
|
157 | new_kwargs = [] | |
|
158 | for param in signature(f).parameters.values(): | |
|
159 | for name, value in _yield_abbreviations_for_parameter(param, kwargs): | |
|
160 | if value is None: | |
|
161 | raise ValueError('cannot find widget or abbreviation for argument: {!r}'.format(name)) | |
|
162 | new_kwargs.append((name, value)) | |
|
163 | return new_kwargs | |
|
164 | ||
|
165 | def _widgets_from_abbreviations(seq): | |
|
166 | """Given a sequence of (name, abbrev) tuples, return a sequence of Widgets.""" | |
|
167 | result = [] | |
|
168 | for name, abbrev in seq: | |
|
169 | widget = _widget_from_abbrev(abbrev) | |
|
170 | widget.description = name | |
|
171 | result.append(widget) | |
|
172 | return result | |
|
173 | ||
|
174 | def interactive(__interact_f, **kwargs): | |
|
175 | """Build a group of widgets to interact with a function.""" | |
|
176 | f = __interact_f | |
|
177 | co = kwargs.pop('clear_output', True) | |
|
178 | kwargs_widgets = [] | |
|
179 | container = ContainerWidget() | |
|
180 | container.result = None | |
|
181 | container.args = [] | |
|
182 | container.kwargs = dict() | |
|
183 | kwargs = kwargs.copy() | |
|
184 | ||
|
185 | new_kwargs = _find_abbreviations(f, kwargs) | |
|
186 | # Before we proceed, let's make sure that the user has passed a set of args+kwargs | |
|
187 | # that will lead to a valid call of the function. This protects against unspecified | |
|
188 | # and doubly-specified arguments. | |
|
189 | getcallargs(f, **{n:v for n,v in new_kwargs}) | |
|
190 | # Now build the widgets from the abbreviations. | |
|
191 | kwargs_widgets.extend(_widgets_from_abbreviations(new_kwargs)) | |
|
192 | kwargs_widgets.extend(_widgets_from_abbreviations(sorted(kwargs.items(), key = lambda x: x[0]))) | |
|
193 | ||
|
194 | # This has to be done as an assignment, not using container.children.append, | |
|
195 | # so that traitlets notices the update. We skip any objects (such as fixed) that | |
|
196 | # are not DOMWidgets. | |
|
197 | c = [w for w in kwargs_widgets if isinstance(w, DOMWidget)] | |
|
198 | container.children = c | |
|
199 | ||
|
200 | # Build the callback | |
|
201 | def call_f(name, old, new): | |
|
202 | container.kwargs = {} | |
|
203 | for widget in kwargs_widgets: | |
|
204 | value = widget.value | |
|
205 | container.kwargs[widget.description] = value | |
|
206 | if co: | |
|
207 | clear_output(wait=True) | |
|
208 | container.result = f(**container.kwargs) | |
|
209 | ||
|
210 | # Wire up the widgets | |
|
211 | for widget in kwargs_widgets: | |
|
212 | widget.on_trait_change(call_f, 'value') | |
|
213 | ||
|
214 | container.on_displayed(lambda _: call_f(None, None, None)) | |
|
215 | ||
|
216 | return container | |
|
217 | ||
|
218 | def interact(__interact_f=None, **kwargs): | |
|
219 | """interact(f, **kwargs) | |
|
220 | ||
|
221 | Interact with a function using widgets.""" | |
|
222 | # positional arg support in: https://gist.github.com/8851331 | |
|
223 | if __interact_f is not None: | |
|
224 | # This branch handles the cases: | |
|
225 | # 1. interact(f, **kwargs) | |
|
226 | # 2. @interact | |
|
227 | # def f(*args, **kwargs): | |
|
228 | # ... | |
|
229 | f = __interact_f | |
|
230 | w = interactive(f, **kwargs) | |
|
231 | f.widget = w | |
|
232 | display(w) | |
|
233 | return f | |
|
234 | else: | |
|
235 | # This branch handles the case: | |
|
236 | # @interact(a=30, b=40) | |
|
237 | # def f(*args, **kwargs): | |
|
238 | # ... | |
|
239 | def dec(f): | |
|
240 | w = interactive(f, **kwargs) | |
|
241 | f.widget = w | |
|
242 | display(w) | |
|
243 | return f | |
|
244 | return dec | |
|
245 | ||
|
246 | class fixed(HasTraits): | |
|
247 | """A pseudo-widget whose value is fixed and never synced to the client.""" | |
|
248 | value = Any(help="Any Python object") | |
|
249 | description = Unicode('', help="Any Python object") | |
|
250 | def __init__(self, value, **kwargs): | |
|
251 | super(fixed, self).__init__(value=value, **kwargs) |
|
1 | NO CONTENT: new file 100644 |
@@ -0,0 +1,408 b'' | |||
|
1 | """Test interact and interactive.""" | |
|
2 | ||
|
3 | #----------------------------------------------------------------------------- | |
|
4 | # Copyright (C) 2014 The IPython Development Team | |
|
5 | # | |
|
6 | # Distributed under the terms of the BSD License. The full license is in | |
|
7 | # the file COPYING, distributed as part of this software. | |
|
8 | #----------------------------------------------------------------------------- | |
|
9 | ||
|
10 | #----------------------------------------------------------------------------- | |
|
11 | # Imports | |
|
12 | #----------------------------------------------------------------------------- | |
|
13 | ||
|
14 | from __future__ import print_function | |
|
15 | ||
|
16 | from collections import OrderedDict | |
|
17 | ||
|
18 | import nose.tools as nt | |
|
19 | import IPython.testing.tools as tt | |
|
20 | ||
|
21 | # from IPython.core.getipython import get_ipython | |
|
22 | from IPython.html import widgets | |
|
23 | from IPython.html.widgets import interact, interactive, Widget, interaction | |
|
24 | from IPython.utils.py3compat import annotate | |
|
25 | # from IPython.utils.capture import capture_output | |
|
26 | ||
|
27 | #----------------------------------------------------------------------------- | |
|
28 | # Utility stuff | |
|
29 | #----------------------------------------------------------------------------- | |
|
30 | ||
|
31 | class DummyComm(object): | |
|
32 | comm_id = 'a-b-c-d' | |
|
33 | def send(self, *args, **kwargs): | |
|
34 | pass | |
|
35 | ||
|
36 | def close(self, *args, **kwargs): | |
|
37 | pass | |
|
38 | ||
|
39 | _widget_attrs = {} | |
|
40 | displayed = [] | |
|
41 | ||
|
42 | def setup(): | |
|
43 | _widget_attrs['comm'] = Widget.comm | |
|
44 | Widget.comm = DummyComm() | |
|
45 | _widget_attrs['_ipython_display_'] = Widget._ipython_display_ | |
|
46 | def raise_not_implemented(*args, **kwargs): | |
|
47 | raise NotImplementedError() | |
|
48 | Widget._ipython_display_ = raise_not_implemented | |
|
49 | ||
|
50 | def teardown(): | |
|
51 | for attr, value in _widget_attrs.items(): | |
|
52 | setattr(Widget, attr, value) | |
|
53 | ||
|
54 | def f(**kwargs): | |
|
55 | pass | |
|
56 | ||
|
57 | def clear_display(): | |
|
58 | global displayed | |
|
59 | displayed = [] | |
|
60 | ||
|
61 | def record_display(*args): | |
|
62 | displayed.extend(args) | |
|
63 | ||
|
64 | #----------------------------------------------------------------------------- | |
|
65 | # Actual tests | |
|
66 | #----------------------------------------------------------------------------- | |
|
67 | ||
|
68 | def check_widget(w, **d): | |
|
69 | """Check a single widget against a dict""" | |
|
70 | for attr, expected in d.items(): | |
|
71 | if attr == 'cls': | |
|
72 | nt.assert_is(w.__class__, expected) | |
|
73 | else: | |
|
74 | value = getattr(w, attr) | |
|
75 | nt.assert_equal(value, expected, | |
|
76 | "%s.%s = %r != %r" % (w.__class__.__name__, attr, value, expected) | |
|
77 | ) | |
|
78 | ||
|
79 | def check_widgets(container, **to_check): | |
|
80 | """Check that widgets are created as expected""" | |
|
81 | # build a widget dictionary, so it matches | |
|
82 | widgets = {} | |
|
83 | for w in container.children: | |
|
84 | widgets[w.description] = w | |
|
85 | ||
|
86 | for key, d in to_check.items(): | |
|
87 | nt.assert_in(key, widgets) | |
|
88 | check_widget(widgets[key], **d) | |
|
89 | ||
|
90 | ||
|
91 | def test_single_value_string(): | |
|
92 | a = u'hello' | |
|
93 | c = interactive(f, a=a) | |
|
94 | w = c.children[0] | |
|
95 | check_widget(w, | |
|
96 | cls=widgets.TextWidget, | |
|
97 | description='a', | |
|
98 | value=a, | |
|
99 | ) | |
|
100 | ||
|
101 | def test_single_value_bool(): | |
|
102 | for a in (True, False): | |
|
103 | c = interactive(f, a=a) | |
|
104 | w = c.children[0] | |
|
105 | check_widget(w, | |
|
106 | cls=widgets.CheckboxWidget, | |
|
107 | description='a', | |
|
108 | value=a, | |
|
109 | ) | |
|
110 | ||
|
111 | def test_single_value_dict(): | |
|
112 | for d in [ | |
|
113 | dict(a=5), | |
|
114 | dict(a=5, b='b', c=dict), | |
|
115 | ]: | |
|
116 | c = interactive(f, d=d) | |
|
117 | w = c.children[0] | |
|
118 | check_widget(w, | |
|
119 | cls=widgets.DropdownWidget, | |
|
120 | description='d', | |
|
121 | values=d, | |
|
122 | value=next(iter(d.values())), | |
|
123 | ) | |
|
124 | ||
|
125 | def test_single_value_float(): | |
|
126 | for a in (2.25, 1.0, -3.5): | |
|
127 | c = interactive(f, a=a) | |
|
128 | w = c.children[0] | |
|
129 | check_widget(w, | |
|
130 | cls=widgets.FloatSliderWidget, | |
|
131 | description='a', | |
|
132 | value=a, | |
|
133 | min= -a if a > 0 else 3*a, | |
|
134 | max= 3*a if a > 0 else -a, | |
|
135 | step=0.1, | |
|
136 | readout=True, | |
|
137 | ) | |
|
138 | ||
|
139 | def test_single_value_int(): | |
|
140 | for a in (1, 5, -3): | |
|
141 | c = interactive(f, a=a) | |
|
142 | nt.assert_equal(len(c.children), 1) | |
|
143 | w = c.children[0] | |
|
144 | check_widget(w, | |
|
145 | cls=widgets.IntSliderWidget, | |
|
146 | description='a', | |
|
147 | value=a, | |
|
148 | min= -a if a > 0 else 3*a, | |
|
149 | max= 3*a if a > 0 else -a, | |
|
150 | step=1, | |
|
151 | readout=True, | |
|
152 | ) | |
|
153 | ||
|
154 | def test_list_tuple_2_int(): | |
|
155 | with nt.assert_raises(ValueError): | |
|
156 | c = interactive(f, tup=(1,1)) | |
|
157 | with nt.assert_raises(ValueError): | |
|
158 | c = interactive(f, tup=(1,-1)) | |
|
159 | for min, max in [ (0,1), (1,10), (1,2), (-5,5), (-20,-19) ]: | |
|
160 | c = interactive(f, tup=(min, max), lis=[min, max]) | |
|
161 | nt.assert_equal(len(c.children), 2) | |
|
162 | d = dict( | |
|
163 | cls=widgets.IntSliderWidget, | |
|
164 | min=min, | |
|
165 | max=max, | |
|
166 | step=1, | |
|
167 | readout=True, | |
|
168 | ) | |
|
169 | check_widgets(c, tup=d, lis=d) | |
|
170 | ||
|
171 | def test_list_tuple_3_int(): | |
|
172 | with nt.assert_raises(ValueError): | |
|
173 | c = interactive(f, tup=(1,2,0)) | |
|
174 | with nt.assert_raises(ValueError): | |
|
175 | c = interactive(f, tup=(1,2,-1)) | |
|
176 | for min, max, step in [ (0,2,1), (1,10,2), (1,100,2), (-5,5,4), (-100,-20,4) ]: | |
|
177 | c = interactive(f, tup=(min, max, step), lis=[min, max, step]) | |
|
178 | nt.assert_equal(len(c.children), 2) | |
|
179 | d = dict( | |
|
180 | cls=widgets.IntSliderWidget, | |
|
181 | min=min, | |
|
182 | max=max, | |
|
183 | step=step, | |
|
184 | readout=True, | |
|
185 | ) | |
|
186 | check_widgets(c, tup=d, lis=d) | |
|
187 | ||
|
188 | def test_list_tuple_2_float(): | |
|
189 | with nt.assert_raises(ValueError): | |
|
190 | c = interactive(f, tup=(1.0,1.0)) | |
|
191 | with nt.assert_raises(ValueError): | |
|
192 | c = interactive(f, tup=(0.5,-0.5)) | |
|
193 | for min, max in [ (0.5, 1.5), (1.1,10.2), (1,2.2), (-5.,5), (-20,-19.) ]: | |
|
194 | c = interactive(f, tup=(min, max), lis=[min, max]) | |
|
195 | nt.assert_equal(len(c.children), 2) | |
|
196 | d = dict( | |
|
197 | cls=widgets.FloatSliderWidget, | |
|
198 | min=min, | |
|
199 | max=max, | |
|
200 | step=.1, | |
|
201 | readout=True, | |
|
202 | ) | |
|
203 | check_widgets(c, tup=d, lis=d) | |
|
204 | ||
|
205 | def test_list_tuple_3_float(): | |
|
206 | with nt.assert_raises(ValueError): | |
|
207 | c = interactive(f, tup=(1,2,0.0)) | |
|
208 | with nt.assert_raises(ValueError): | |
|
209 | c = interactive(f, tup=(-1,-2,1.)) | |
|
210 | with nt.assert_raises(ValueError): | |
|
211 | c = interactive(f, tup=(1,2.,-1.)) | |
|
212 | for min, max, step in [ (0.,2,1), (1,10.,2), (1,100,2.), (-5.,5.,4), (-100,-20.,4.) ]: | |
|
213 | c = interactive(f, tup=(min, max, step), lis=[min, max, step]) | |
|
214 | nt.assert_equal(len(c.children), 2) | |
|
215 | d = dict( | |
|
216 | cls=widgets.FloatSliderWidget, | |
|
217 | min=min, | |
|
218 | max=max, | |
|
219 | step=step, | |
|
220 | readout=True, | |
|
221 | ) | |
|
222 | check_widgets(c, tup=d, lis=d) | |
|
223 | ||
|
224 | def test_list_tuple_str(): | |
|
225 | values = ['hello', 'there', 'guy'] | |
|
226 | first = values[0] | |
|
227 | dvalues = OrderedDict((v,v) for v in values) | |
|
228 | c = interactive(f, tup=tuple(values), lis=list(values)) | |
|
229 | nt.assert_equal(len(c.children), 2) | |
|
230 | d = dict( | |
|
231 | cls=widgets.DropdownWidget, | |
|
232 | value=first, | |
|
233 | values=dvalues | |
|
234 | ) | |
|
235 | check_widgets(c, tup=d, lis=d) | |
|
236 | ||
|
237 | def test_list_tuple_invalid(): | |
|
238 | for bad in [ | |
|
239 | (), | |
|
240 | (5, 'hi'), | |
|
241 | ('hi', 5), | |
|
242 | ({},), | |
|
243 | (None,), | |
|
244 | ]: | |
|
245 | with nt.assert_raises(ValueError): | |
|
246 | print(bad) # because there is no custom message in assert_raises | |
|
247 | c = interactive(f, tup=bad) | |
|
248 | ||
|
249 | def test_defaults(): | |
|
250 | @annotate(n=10) | |
|
251 | def f(n, f=4.5): | |
|
252 | pass | |
|
253 | ||
|
254 | c = interactive(f) | |
|
255 | check_widgets(c, | |
|
256 | n=dict( | |
|
257 | cls=widgets.IntSliderWidget, | |
|
258 | value=10, | |
|
259 | ), | |
|
260 | f=dict( | |
|
261 | cls=widgets.FloatSliderWidget, | |
|
262 | value=4.5, | |
|
263 | ), | |
|
264 | ) | |
|
265 | ||
|
266 | def test_annotations(): | |
|
267 | @annotate(n=10, f=widgets.FloatTextWidget()) | |
|
268 | def f(n, f): | |
|
269 | pass | |
|
270 | ||
|
271 | c = interactive(f) | |
|
272 | check_widgets(c, | |
|
273 | n=dict( | |
|
274 | cls=widgets.IntSliderWidget, | |
|
275 | value=10, | |
|
276 | ), | |
|
277 | f=dict( | |
|
278 | cls=widgets.FloatTextWidget, | |
|
279 | ), | |
|
280 | ) | |
|
281 | ||
|
282 | def test_priority(): | |
|
283 | @annotate(annotate='annotate', kwarg='annotate') | |
|
284 | def f(kwarg='default', annotate='default', default='default'): | |
|
285 | pass | |
|
286 | ||
|
287 | c = interactive(f, kwarg='kwarg') | |
|
288 | check_widgets(c, | |
|
289 | kwarg=dict( | |
|
290 | cls=widgets.TextWidget, | |
|
291 | value='kwarg', | |
|
292 | ), | |
|
293 | annotate=dict( | |
|
294 | cls=widgets.TextWidget, | |
|
295 | value='annotate', | |
|
296 | ), | |
|
297 | ) | |
|
298 | ||
|
299 | @nt.with_setup(clear_display) | |
|
300 | def test_decorator_kwarg(): | |
|
301 | with tt.monkeypatch(interaction, 'display', record_display): | |
|
302 | @interact(a=5) | |
|
303 | def foo(a): | |
|
304 | pass | |
|
305 | nt.assert_equal(len(displayed), 1) | |
|
306 | w = displayed[0].children[0] | |
|
307 | check_widget(w, | |
|
308 | cls=widgets.IntSliderWidget, | |
|
309 | value=5, | |
|
310 | ) | |
|
311 | ||
|
312 | @nt.with_setup(clear_display) | |
|
313 | def test_decorator_no_call(): | |
|
314 | with tt.monkeypatch(interaction, 'display', record_display): | |
|
315 | @interact | |
|
316 | def foo(a='default'): | |
|
317 | pass | |
|
318 | nt.assert_equal(len(displayed), 1) | |
|
319 | w = displayed[0].children[0] | |
|
320 | check_widget(w, | |
|
321 | cls=widgets.TextWidget, | |
|
322 | value='default', | |
|
323 | ) | |
|
324 | ||
|
325 | @nt.with_setup(clear_display) | |
|
326 | def test_call_interact(): | |
|
327 | def foo(a='default'): | |
|
328 | pass | |
|
329 | with tt.monkeypatch(interaction, 'display', record_display): | |
|
330 | ifoo = interact(foo) | |
|
331 | nt.assert_equal(len(displayed), 1) | |
|
332 | w = displayed[0].children[0] | |
|
333 | check_widget(w, | |
|
334 | cls=widgets.TextWidget, | |
|
335 | value='default', | |
|
336 | ) | |
|
337 | ||
|
338 | @nt.with_setup(clear_display) | |
|
339 | def test_call_interact_kwargs(): | |
|
340 | def foo(a='default'): | |
|
341 | pass | |
|
342 | with tt.monkeypatch(interaction, 'display', record_display): | |
|
343 | ifoo = interact(foo, a=10) | |
|
344 | nt.assert_equal(len(displayed), 1) | |
|
345 | w = displayed[0].children[0] | |
|
346 | check_widget(w, | |
|
347 | cls=widgets.IntSliderWidget, | |
|
348 | value=10, | |
|
349 | ) | |
|
350 | ||
|
351 | @nt.with_setup(clear_display) | |
|
352 | def test_call_decorated_on_trait_change(): | |
|
353 | """test calling @interact decorated functions""" | |
|
354 | d = {} | |
|
355 | with tt.monkeypatch(interaction, 'display', record_display): | |
|
356 | @interact | |
|
357 | def foo(a='default'): | |
|
358 | d['a'] = a | |
|
359 | return a | |
|
360 | nt.assert_equal(len(displayed), 1) | |
|
361 | w = displayed[0].children[0] | |
|
362 | check_widget(w, | |
|
363 | cls=widgets.TextWidget, | |
|
364 | value='default', | |
|
365 | ) | |
|
366 | # test calling the function directly | |
|
367 | a = foo('hello') | |
|
368 | nt.assert_equal(a, 'hello') | |
|
369 | nt.assert_equal(d['a'], 'hello') | |
|
370 | ||
|
371 | # test that setting trait values calls the function | |
|
372 | w.value = 'called' | |
|
373 | nt.assert_equal(d['a'], 'called') | |
|
374 | ||
|
375 | @nt.with_setup(clear_display) | |
|
376 | def test_call_decorated_kwargs_on_trait_change(): | |
|
377 | """test calling @interact(foo=bar) decorated functions""" | |
|
378 | d = {} | |
|
379 | with tt.monkeypatch(interaction, 'display', record_display): | |
|
380 | @interact(a='kwarg') | |
|
381 | def foo(a='default'): | |
|
382 | d['a'] = a | |
|
383 | return a | |
|
384 | nt.assert_equal(len(displayed), 1) | |
|
385 | w = displayed[0].children[0] | |
|
386 | check_widget(w, | |
|
387 | cls=widgets.TextWidget, | |
|
388 | value='kwarg', | |
|
389 | ) | |
|
390 | # test calling the function directly | |
|
391 | a = foo('hello') | |
|
392 | nt.assert_equal(a, 'hello') | |
|
393 | nt.assert_equal(d['a'], 'hello') | |
|
394 | ||
|
395 | # test that setting trait values calls the function | |
|
396 | w.value = 'called' | |
|
397 | nt.assert_equal(d['a'], 'called') | |
|
398 | ||
|
399 | def test_fixed(): | |
|
400 | c = interactive(f, a=widgets.fixed(5), b='text') | |
|
401 | nt.assert_equal(len(c.children), 1) | |
|
402 | w = c.children[0] | |
|
403 | check_widget(w, | |
|
404 | cls=widgets.TextWidget, | |
|
405 | value='text', | |
|
406 | description='b', | |
|
407 | ) | |
|
408 |
This diff has been collapsed as it changes many lines, (819 lines changed) Show them Hide them | |||
@@ -0,0 +1,819 b'' | |||
|
1 | """Function signature objects for callables | |
|
2 | ||
|
3 | Back port of Python 3.3's function signature tools from the inspect module, | |
|
4 | modified to be compatible with Python 2.6, 2.7 and 3.2+. | |
|
5 | """ | |
|
6 | ||
|
7 | #----------------------------------------------------------------------------- | |
|
8 | # Python 3.3 stdlib inspect.py is public domain | |
|
9 | # | |
|
10 | # Backports Copyright (C) 2013 Aaron Iles | |
|
11 | # Used under Apache License Version 2.0 | |
|
12 | # | |
|
13 | # Further Changes are Copyright (C) 2013 The IPython Development Team | |
|
14 | # | |
|
15 | # Distributed under the terms of the BSD License. The full license is in | |
|
16 | # the file COPYING, distributed as part of this software. | |
|
17 | #----------------------------------------------------------------------------- | |
|
18 | ||
|
19 | from __future__ import absolute_import, division, print_function | |
|
20 | import itertools | |
|
21 | import functools | |
|
22 | import re | |
|
23 | import types | |
|
24 | ||
|
25 | ||
|
26 | # patch for single-file | |
|
27 | # we don't support 2.6, so we can just import OrderedDict | |
|
28 | from collections import OrderedDict | |
|
29 | ||
|
30 | __version__ = '0.3' | |
|
31 | # end patch | |
|
32 | ||
|
33 | __all__ = ['BoundArguments', 'Parameter', 'Signature', 'signature'] | |
|
34 | ||
|
35 | ||
|
36 | _WrapperDescriptor = type(type.__call__) | |
|
37 | _MethodWrapper = type(all.__call__) | |
|
38 | ||
|
39 | _NonUserDefinedCallables = (_WrapperDescriptor, | |
|
40 | _MethodWrapper, | |
|
41 | types.BuiltinFunctionType) | |
|
42 | ||
|
43 | ||
|
44 | def formatannotation(annotation, base_module=None): | |
|
45 | if isinstance(annotation, type): | |
|
46 | if annotation.__module__ in ('builtins', '__builtin__', base_module): | |
|
47 | return annotation.__name__ | |
|
48 | return annotation.__module__+'.'+annotation.__name__ | |
|
49 | return repr(annotation) | |
|
50 | ||
|
51 | ||
|
52 | def _get_user_defined_method(cls, method_name, *nested): | |
|
53 | try: | |
|
54 | if cls is type: | |
|
55 | return | |
|
56 | meth = getattr(cls, method_name) | |
|
57 | for name in nested: | |
|
58 | meth = getattr(meth, name, meth) | |
|
59 | except AttributeError: | |
|
60 | return | |
|
61 | else: | |
|
62 | if not isinstance(meth, _NonUserDefinedCallables): | |
|
63 | # Once '__signature__' will be added to 'C'-level | |
|
64 | # callables, this check won't be necessary | |
|
65 | return meth | |
|
66 | ||
|
67 | ||
|
68 | def signature(obj): | |
|
69 | '''Get a signature object for the passed callable.''' | |
|
70 | ||
|
71 | if not callable(obj): | |
|
72 | raise TypeError('{0!r} is not a callable object'.format(obj)) | |
|
73 | ||
|
74 | if isinstance(obj, types.MethodType): | |
|
75 | # In this case we skip the first parameter of the underlying | |
|
76 | # function (usually `self` or `cls`). | |
|
77 | sig = signature(obj.__func__) | |
|
78 | return sig.replace(parameters=tuple(sig.parameters.values())[1:]) | |
|
79 | ||
|
80 | try: | |
|
81 | sig = obj.__signature__ | |
|
82 | except AttributeError: | |
|
83 | pass | |
|
84 | else: | |
|
85 | if sig is not None: | |
|
86 | return sig | |
|
87 | ||
|
88 | try: | |
|
89 | # Was this function wrapped by a decorator? | |
|
90 | wrapped = obj.__wrapped__ | |
|
91 | except AttributeError: | |
|
92 | pass | |
|
93 | else: | |
|
94 | return signature(wrapped) | |
|
95 | ||
|
96 | if isinstance(obj, types.FunctionType): | |
|
97 | return Signature.from_function(obj) | |
|
98 | ||
|
99 | if isinstance(obj, functools.partial): | |
|
100 | sig = signature(obj.func) | |
|
101 | ||
|
102 | new_params = OrderedDict(sig.parameters.items()) | |
|
103 | ||
|
104 | partial_args = obj.args or () | |
|
105 | partial_keywords = obj.keywords or {} | |
|
106 | try: | |
|
107 | ba = sig.bind_partial(*partial_args, **partial_keywords) | |
|
108 | except TypeError as ex: | |
|
109 | msg = 'partial object {0!r} has incorrect arguments'.format(obj) | |
|
110 | raise ValueError(msg) | |
|
111 | ||
|
112 | for arg_name, arg_value in ba.arguments.items(): | |
|
113 | param = new_params[arg_name] | |
|
114 | if arg_name in partial_keywords: | |
|
115 | # We set a new default value, because the following code | |
|
116 | # is correct: | |
|
117 | # | |
|
118 | # >>> def foo(a): print(a) | |
|
119 | # >>> print(partial(partial(foo, a=10), a=20)()) | |
|
120 | # 20 | |
|
121 | # >>> print(partial(partial(foo, a=10), a=20)(a=30)) | |
|
122 | # 30 | |
|
123 | # | |
|
124 | # So, with 'partial' objects, passing a keyword argument is | |
|
125 | # like setting a new default value for the corresponding | |
|
126 | # parameter | |
|
127 | # | |
|
128 | # We also mark this parameter with '_partial_kwarg' | |
|
129 | # flag. Later, in '_bind', the 'default' value of this | |
|
130 | # parameter will be added to 'kwargs', to simulate | |
|
131 | # the 'functools.partial' real call. | |
|
132 | new_params[arg_name] = param.replace(default=arg_value, | |
|
133 | _partial_kwarg=True) | |
|
134 | ||
|
135 | elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and | |
|
136 | not param._partial_kwarg): | |
|
137 | new_params.pop(arg_name) | |
|
138 | ||
|
139 | return sig.replace(parameters=new_params.values()) | |
|
140 | ||
|
141 | sig = None | |
|
142 | if isinstance(obj, type): | |
|
143 | # obj is a class or a metaclass | |
|
144 | ||
|
145 | # First, let's see if it has an overloaded __call__ defined | |
|
146 | # in its metaclass | |
|
147 | call = _get_user_defined_method(type(obj), '__call__') | |
|
148 | if call is not None: | |
|
149 | sig = signature(call) | |
|
150 | else: | |
|
151 | # Now we check if the 'obj' class has a '__new__' method | |
|
152 | new = _get_user_defined_method(obj, '__new__') | |
|
153 | if new is not None: | |
|
154 | sig = signature(new) | |
|
155 | else: | |
|
156 | # Finally, we should have at least __init__ implemented | |
|
157 | init = _get_user_defined_method(obj, '__init__') | |
|
158 | if init is not None: | |
|
159 | sig = signature(init) | |
|
160 | elif not isinstance(obj, _NonUserDefinedCallables): | |
|
161 | # An object with __call__ | |
|
162 | # We also check that the 'obj' is not an instance of | |
|
163 | # _WrapperDescriptor or _MethodWrapper to avoid | |
|
164 | # infinite recursion (and even potential segfault) | |
|
165 | call = _get_user_defined_method(type(obj), '__call__', 'im_func') | |
|
166 | if call is not None: | |
|
167 | sig = signature(call) | |
|
168 | ||
|
169 | if sig is not None: | |
|
170 | return sig | |
|
171 | ||
|
172 | if isinstance(obj, types.BuiltinFunctionType): | |
|
173 | # Raise a nicer error message for builtins | |
|
174 | msg = 'no signature found for builtin function {0!r}'.format(obj) | |
|
175 | raise ValueError(msg) | |
|
176 | ||
|
177 | raise ValueError('callable {0!r} is not supported by signature'.format(obj)) | |
|
178 | ||
|
179 | ||
|
180 | class _void(object): | |
|
181 | '''A private marker - used in Parameter & Signature''' | |
|
182 | ||
|
183 | ||
|
184 | class _empty(object): | |
|
185 | pass | |
|
186 | ||
|
187 | ||
|
188 | class _ParameterKind(int): | |
|
189 | def __new__(self, *args, **kwargs): | |
|
190 | obj = int.__new__(self, *args) | |
|
191 | obj._name = kwargs['name'] | |
|
192 | return obj | |
|
193 | ||
|
194 | def __str__(self): | |
|
195 | return self._name | |
|
196 | ||
|
197 | def __repr__(self): | |
|
198 | return '<_ParameterKind: {0!r}>'.format(self._name) | |
|
199 | ||
|
200 | ||
|
201 | _POSITIONAL_ONLY = _ParameterKind(0, name='POSITIONAL_ONLY') | |
|
202 | _POSITIONAL_OR_KEYWORD = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD') | |
|
203 | _VAR_POSITIONAL = _ParameterKind(2, name='VAR_POSITIONAL') | |
|
204 | _KEYWORD_ONLY = _ParameterKind(3, name='KEYWORD_ONLY') | |
|
205 | _VAR_KEYWORD = _ParameterKind(4, name='VAR_KEYWORD') | |
|
206 | ||
|
207 | ||
|
208 | class Parameter(object): | |
|
209 | '''Represents a parameter in a function signature. | |
|
210 | ||
|
211 | Has the following public attributes: | |
|
212 | ||
|
213 | * name : str | |
|
214 | The name of the parameter as a string. | |
|
215 | * default : object | |
|
216 | The default value for the parameter if specified. If the | |
|
217 | parameter has no default value, this attribute is not set. | |
|
218 | * annotation | |
|
219 | The annotation for the parameter if specified. If the | |
|
220 | parameter has no annotation, this attribute is not set. | |
|
221 | * kind : str | |
|
222 | Describes how argument values are bound to the parameter. | |
|
223 | Possible values: `Parameter.POSITIONAL_ONLY`, | |
|
224 | `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`, | |
|
225 | `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`. | |
|
226 | ''' | |
|
227 | ||
|
228 | __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg') | |
|
229 | ||
|
230 | POSITIONAL_ONLY = _POSITIONAL_ONLY | |
|
231 | POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD | |
|
232 | VAR_POSITIONAL = _VAR_POSITIONAL | |
|
233 | KEYWORD_ONLY = _KEYWORD_ONLY | |
|
234 | VAR_KEYWORD = _VAR_KEYWORD | |
|
235 | ||
|
236 | empty = _empty | |
|
237 | ||
|
238 | def __init__(self, name, kind, default=_empty, annotation=_empty, | |
|
239 | _partial_kwarg=False): | |
|
240 | ||
|
241 | if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD, | |
|
242 | _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD): | |
|
243 | raise ValueError("invalid value for 'Parameter.kind' attribute") | |
|
244 | self._kind = kind | |
|
245 | ||
|
246 | if default is not _empty: | |
|
247 | if kind in (_VAR_POSITIONAL, _VAR_KEYWORD): | |
|
248 | msg = '{0} parameters cannot have default values'.format(kind) | |
|
249 | raise ValueError(msg) | |
|
250 | self._default = default | |
|
251 | self._annotation = annotation | |
|
252 | ||
|
253 | if name is None: | |
|
254 | if kind != _POSITIONAL_ONLY: | |
|
255 | raise ValueError("None is not a valid name for a " | |
|
256 | "non-positional-only parameter") | |
|
257 | self._name = name | |
|
258 | else: | |
|
259 | name = str(name) | |
|
260 | if kind != _POSITIONAL_ONLY and not re.match(r'[a-z_]\w*$', name, re.I): | |
|
261 | msg = '{0!r} is not a valid parameter name'.format(name) | |
|
262 | raise ValueError(msg) | |
|
263 | self._name = name | |
|
264 | ||
|
265 | self._partial_kwarg = _partial_kwarg | |
|
266 | ||
|
267 | @property | |
|
268 | def name(self): | |
|
269 | return self._name | |
|
270 | ||
|
271 | @property | |
|
272 | def default(self): | |
|
273 | return self._default | |
|
274 | ||
|
275 | @property | |
|
276 | def annotation(self): | |
|
277 | return self._annotation | |
|
278 | ||
|
279 | @property | |
|
280 | def kind(self): | |
|
281 | return self._kind | |
|
282 | ||
|
283 | def replace(self, name=_void, kind=_void, annotation=_void, | |
|
284 | default=_void, _partial_kwarg=_void): | |
|
285 | '''Creates a customized copy of the Parameter.''' | |
|
286 | ||
|
287 | if name is _void: | |
|
288 | name = self._name | |
|
289 | ||
|
290 | if kind is _void: | |
|
291 | kind = self._kind | |
|
292 | ||
|
293 | if annotation is _void: | |
|
294 | annotation = self._annotation | |
|
295 | ||
|
296 | if default is _void: | |
|
297 | default = self._default | |
|
298 | ||
|
299 | if _partial_kwarg is _void: | |
|
300 | _partial_kwarg = self._partial_kwarg | |
|
301 | ||
|
302 | return type(self)(name, kind, default=default, annotation=annotation, | |
|
303 | _partial_kwarg=_partial_kwarg) | |
|
304 | ||
|
305 | def __str__(self): | |
|
306 | kind = self.kind | |
|
307 | ||
|
308 | formatted = self._name | |
|
309 | if kind == _POSITIONAL_ONLY: | |
|
310 | if formatted is None: | |
|
311 | formatted = '' | |
|
312 | formatted = '<{0}>'.format(formatted) | |
|
313 | ||
|
314 | # Add annotation and default value | |
|
315 | if self._annotation is not _empty: | |
|
316 | formatted = '{0}:{1}'.format(formatted, | |
|
317 | formatannotation(self._annotation)) | |
|
318 | ||
|
319 | if self._default is not _empty: | |
|
320 | formatted = '{0}={1}'.format(formatted, repr(self._default)) | |
|
321 | ||
|
322 | if kind == _VAR_POSITIONAL: | |
|
323 | formatted = '*' + formatted | |
|
324 | elif kind == _VAR_KEYWORD: | |
|
325 | formatted = '**' + formatted | |
|
326 | ||
|
327 | return formatted | |
|
328 | ||
|
329 | def __repr__(self): | |
|
330 | return '<{0} at {1:#x} {2!r}>'.format(self.__class__.__name__, | |
|
331 | id(self), self.name) | |
|
332 | ||
|
333 | def __hash__(self): | |
|
334 | msg = "unhashable type: '{0}'".format(self.__class__.__name__) | |
|
335 | raise TypeError(msg) | |
|
336 | ||
|
337 | def __eq__(self, other): | |
|
338 | return (issubclass(other.__class__, Parameter) and | |
|
339 | self._name == other._name and | |
|
340 | self._kind == other._kind and | |
|
341 | self._default == other._default and | |
|
342 | self._annotation == other._annotation) | |
|
343 | ||
|
344 | def __ne__(self, other): | |
|
345 | return not self.__eq__(other) | |
|
346 | ||
|
347 | ||
|
348 | class BoundArguments(object): | |
|
349 | '''Result of `Signature.bind` call. Holds the mapping of arguments | |
|
350 | to the function's parameters. | |
|
351 | ||
|
352 | Has the following public attributes: | |
|
353 | ||
|
354 | * arguments : OrderedDict | |
|
355 | An ordered mutable mapping of parameters' names to arguments' values. | |
|
356 | Does not contain arguments' default values. | |
|
357 | * signature : Signature | |
|
358 | The Signature object that created this instance. | |
|
359 | * args : tuple | |
|
360 | Tuple of positional arguments values. | |
|
361 | * kwargs : dict | |
|
362 | Dict of keyword arguments values. | |
|
363 | ''' | |
|
364 | ||
|
365 | def __init__(self, signature, arguments): | |
|
366 | self.arguments = arguments | |
|
367 | self._signature = signature | |
|
368 | ||
|
369 | @property | |
|
370 | def signature(self): | |
|
371 | return self._signature | |
|
372 | ||
|
373 | @property | |
|
374 | def args(self): | |
|
375 | args = [] | |
|
376 | for param_name, param in self._signature.parameters.items(): | |
|
377 | if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or | |
|
378 | param._partial_kwarg): | |
|
379 | # Keyword arguments mapped by 'functools.partial' | |
|
380 | # (Parameter._partial_kwarg is True) are mapped | |
|
381 | # in 'BoundArguments.kwargs', along with VAR_KEYWORD & | |
|
382 | # KEYWORD_ONLY | |
|
383 | break | |
|
384 | ||
|
385 | try: | |
|
386 | arg = self.arguments[param_name] | |
|
387 | except KeyError: | |
|
388 | # We're done here. Other arguments | |
|
389 | # will be mapped in 'BoundArguments.kwargs' | |
|
390 | break | |
|
391 | else: | |
|
392 | if param.kind == _VAR_POSITIONAL: | |
|
393 | # *args | |
|
394 | args.extend(arg) | |
|
395 | else: | |
|
396 | # plain argument | |
|
397 | args.append(arg) | |
|
398 | ||
|
399 | return tuple(args) | |
|
400 | ||
|
401 | @property | |
|
402 | def kwargs(self): | |
|
403 | kwargs = {} | |
|
404 | kwargs_started = False | |
|
405 | for param_name, param in self._signature.parameters.items(): | |
|
406 | if not kwargs_started: | |
|
407 | if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or | |
|
408 | param._partial_kwarg): | |
|
409 | kwargs_started = True | |
|
410 | else: | |
|
411 | if param_name not in self.arguments: | |
|
412 | kwargs_started = True | |
|
413 | continue | |
|
414 | ||
|
415 | if not kwargs_started: | |
|
416 | continue | |
|
417 | ||
|
418 | try: | |
|
419 | arg = self.arguments[param_name] | |
|
420 | except KeyError: | |
|
421 | pass | |
|
422 | else: | |
|
423 | if param.kind == _VAR_KEYWORD: | |
|
424 | # **kwargs | |
|
425 | kwargs.update(arg) | |
|
426 | else: | |
|
427 | # plain keyword argument | |
|
428 | kwargs[param_name] = arg | |
|
429 | ||
|
430 | return kwargs | |
|
431 | ||
|
432 | def __hash__(self): | |
|
433 | msg = "unhashable type: '{0}'".format(self.__class__.__name__) | |
|
434 | raise TypeError(msg) | |
|
435 | ||
|
436 | def __eq__(self, other): | |
|
437 | return (issubclass(other.__class__, BoundArguments) and | |
|
438 | self.signature == other.signature and | |
|
439 | self.arguments == other.arguments) | |
|
440 | ||
|
441 | def __ne__(self, other): | |
|
442 | return not self.__eq__(other) | |
|
443 | ||
|
444 | ||
|
445 | class Signature(object): | |
|
446 | '''A Signature object represents the overall signature of a function. | |
|
447 | It stores a Parameter object for each parameter accepted by the | |
|
448 | function, as well as information specific to the function itself. | |
|
449 | ||
|
450 | A Signature object has the following public attributes and methods: | |
|
451 | ||
|
452 | * parameters : OrderedDict | |
|
453 | An ordered mapping of parameters' names to the corresponding | |
|
454 | Parameter objects (keyword-only arguments are in the same order | |
|
455 | as listed in `code.co_varnames`). | |
|
456 | * return_annotation : object | |
|
457 | The annotation for the return type of the function if specified. | |
|
458 | If the function has no annotation for its return type, this | |
|
459 | attribute is not set. | |
|
460 | * bind(*args, **kwargs) -> BoundArguments | |
|
461 | Creates a mapping from positional and keyword arguments to | |
|
462 | parameters. | |
|
463 | * bind_partial(*args, **kwargs) -> BoundArguments | |
|
464 | Creates a partial mapping from positional and keyword arguments | |
|
465 | to parameters (simulating 'functools.partial' behavior.) | |
|
466 | ''' | |
|
467 | ||
|
468 | __slots__ = ('_return_annotation', '_parameters') | |
|
469 | ||
|
470 | _parameter_cls = Parameter | |
|
471 | _bound_arguments_cls = BoundArguments | |
|
472 | ||
|
473 | empty = _empty | |
|
474 | ||
|
475 | def __init__(self, parameters=None, return_annotation=_empty, | |
|
476 | __validate_parameters__=True): | |
|
477 | '''Constructs Signature from the given list of Parameter | |
|
478 | objects and 'return_annotation'. All arguments are optional. | |
|
479 | ''' | |
|
480 | ||
|
481 | if parameters is None: | |
|
482 | params = OrderedDict() | |
|
483 | else: | |
|
484 | if __validate_parameters__: | |
|
485 | params = OrderedDict() | |
|
486 | top_kind = _POSITIONAL_ONLY | |
|
487 | ||
|
488 | for idx, param in enumerate(parameters): | |
|
489 | kind = param.kind | |
|
490 | if kind < top_kind: | |
|
491 | msg = 'wrong parameter order: {0} before {1}' | |
|
492 | msg = msg.format(top_kind, param.kind) | |
|
493 | raise ValueError(msg) | |
|
494 | else: | |
|
495 | top_kind = kind | |
|
496 | ||
|
497 | name = param.name | |
|
498 | if name is None: | |
|
499 | name = str(idx) | |
|
500 | param = param.replace(name=name) | |
|
501 | ||
|
502 | if name in params: | |
|
503 | msg = 'duplicate parameter name: {0!r}'.format(name) | |
|
504 | raise ValueError(msg) | |
|
505 | params[name] = param | |
|
506 | else: | |
|
507 | params = OrderedDict(((param.name, param) | |
|
508 | for param in parameters)) | |
|
509 | ||
|
510 | self._parameters = params | |
|
511 | self._return_annotation = return_annotation | |
|
512 | ||
|
513 | @classmethod | |
|
514 | def from_function(cls, func): | |
|
515 | '''Constructs Signature for the given python function''' | |
|
516 | ||
|
517 | if not isinstance(func, types.FunctionType): | |
|
518 | raise TypeError('{0!r} is not a Python function'.format(func)) | |
|
519 | ||
|
520 | Parameter = cls._parameter_cls | |
|
521 | ||
|
522 | # Parameter information. | |
|
523 | func_code = func.__code__ | |
|
524 | pos_count = func_code.co_argcount | |
|
525 | arg_names = func_code.co_varnames | |
|
526 | positional = tuple(arg_names[:pos_count]) | |
|
527 | keyword_only_count = getattr(func_code, 'co_kwonlyargcount', 0) | |
|
528 | keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)] | |
|
529 | annotations = getattr(func, '__annotations__', {}) | |
|
530 | defaults = func.__defaults__ | |
|
531 | kwdefaults = getattr(func, '__kwdefaults__', None) | |
|
532 | ||
|
533 | if defaults: | |
|
534 | pos_default_count = len(defaults) | |
|
535 | else: | |
|
536 | pos_default_count = 0 | |
|
537 | ||
|
538 | parameters = [] | |
|
539 | ||
|
540 | # Non-keyword-only parameters w/o defaults. | |
|
541 | non_default_count = pos_count - pos_default_count | |
|
542 | for name in positional[:non_default_count]: | |
|
543 | annotation = annotations.get(name, _empty) | |
|
544 | parameters.append(Parameter(name, annotation=annotation, | |
|
545 | kind=_POSITIONAL_OR_KEYWORD)) | |
|
546 | ||
|
547 | # ... w/ defaults. | |
|
548 | for offset, name in enumerate(positional[non_default_count:]): | |
|
549 | annotation = annotations.get(name, _empty) | |
|
550 | parameters.append(Parameter(name, annotation=annotation, | |
|
551 | kind=_POSITIONAL_OR_KEYWORD, | |
|
552 | default=defaults[offset])) | |
|
553 | ||
|
554 | # *args | |
|
555 | if func_code.co_flags & 0x04: | |
|
556 | name = arg_names[pos_count + keyword_only_count] | |
|
557 | annotation = annotations.get(name, _empty) | |
|
558 | parameters.append(Parameter(name, annotation=annotation, | |
|
559 | kind=_VAR_POSITIONAL)) | |
|
560 | ||
|
561 | # Keyword-only parameters. | |
|
562 | for name in keyword_only: | |
|
563 | default = _empty | |
|
564 | if kwdefaults is not None: | |
|
565 | default = kwdefaults.get(name, _empty) | |
|
566 | ||
|
567 | annotation = annotations.get(name, _empty) | |
|
568 | parameters.append(Parameter(name, annotation=annotation, | |
|
569 | kind=_KEYWORD_ONLY, | |
|
570 | default=default)) | |
|
571 | # **kwargs | |
|
572 | if func_code.co_flags & 0x08: | |
|
573 | index = pos_count + keyword_only_count | |
|
574 | if func_code.co_flags & 0x04: | |
|
575 | index += 1 | |
|
576 | ||
|
577 | name = arg_names[index] | |
|
578 | annotation = annotations.get(name, _empty) | |
|
579 | parameters.append(Parameter(name, annotation=annotation, | |
|
580 | kind=_VAR_KEYWORD)) | |
|
581 | ||
|
582 | return cls(parameters, | |
|
583 | return_annotation=annotations.get('return', _empty), | |
|
584 | __validate_parameters__=False) | |
|
585 | ||
|
586 | @property | |
|
587 | def parameters(self): | |
|
588 | try: | |
|
589 | return types.MappingProxyType(self._parameters) | |
|
590 | except AttributeError: | |
|
591 | return OrderedDict(self._parameters.items()) | |
|
592 | ||
|
593 | @property | |
|
594 | def return_annotation(self): | |
|
595 | return self._return_annotation | |
|
596 | ||
|
597 | def replace(self, parameters=_void, return_annotation=_void): | |
|
598 | '''Creates a customized copy of the Signature. | |
|
599 | Pass 'parameters' and/or 'return_annotation' arguments | |
|
600 | to override them in the new copy. | |
|
601 | ''' | |
|
602 | ||
|
603 | if parameters is _void: | |
|
604 | parameters = self.parameters.values() | |
|
605 | ||
|
606 | if return_annotation is _void: | |
|
607 | return_annotation = self._return_annotation | |
|
608 | ||
|
609 | return type(self)(parameters, | |
|
610 | return_annotation=return_annotation) | |
|
611 | ||
|
612 | def __hash__(self): | |
|
613 | msg = "unhashable type: '{0}'".format(self.__class__.__name__) | |
|
614 | raise TypeError(msg) | |
|
615 | ||
|
616 | def __eq__(self, other): | |
|
617 | if (not issubclass(type(other), Signature) or | |
|
618 | self.return_annotation != other.return_annotation or | |
|
619 | len(self.parameters) != len(other.parameters)): | |
|
620 | return False | |
|
621 | ||
|
622 | other_positions = dict((param, idx) | |
|
623 | for idx, param in enumerate(other.parameters.keys())) | |
|
624 | ||
|
625 | for idx, (param_name, param) in enumerate(self.parameters.items()): | |
|
626 | if param.kind == _KEYWORD_ONLY: | |
|
627 | try: | |
|
628 | other_param = other.parameters[param_name] | |
|
629 | except KeyError: | |
|
630 | return False | |
|
631 | else: | |
|
632 | if param != other_param: | |
|
633 | return False | |
|
634 | else: | |
|
635 | try: | |
|
636 | other_idx = other_positions[param_name] | |
|
637 | except KeyError: | |
|
638 | return False | |
|
639 | else: | |
|
640 | if (idx != other_idx or | |
|
641 | param != other.parameters[param_name]): | |
|
642 | return False | |
|
643 | ||
|
644 | return True | |
|
645 | ||
|
646 | def __ne__(self, other): | |
|
647 | return not self.__eq__(other) | |
|
648 | ||
|
649 | def _bind(self, args, kwargs, partial=False): | |
|
650 | '''Private method. Don't use directly.''' | |
|
651 | ||
|
652 | arguments = OrderedDict() | |
|
653 | ||
|
654 | parameters = iter(self.parameters.values()) | |
|
655 | parameters_ex = () | |
|
656 | arg_vals = iter(args) | |
|
657 | ||
|
658 | if partial: | |
|
659 | # Support for binding arguments to 'functools.partial' objects. | |
|
660 | # See 'functools.partial' case in 'signature()' implementation | |
|
661 | # for details. | |
|
662 | for param_name, param in self.parameters.items(): | |
|
663 | if (param._partial_kwarg and param_name not in kwargs): | |
|
664 | # Simulating 'functools.partial' behavior | |
|
665 | kwargs[param_name] = param.default | |
|
666 | ||
|
667 | while True: | |
|
668 | # Let's iterate through the positional arguments and corresponding | |
|
669 | # parameters | |
|
670 | try: | |
|
671 | arg_val = next(arg_vals) | |
|
672 | except StopIteration: | |
|
673 | # No more positional arguments | |
|
674 | try: | |
|
675 | param = next(parameters) | |
|
676 | except StopIteration: | |
|
677 | # No more parameters. That's it. Just need to check that | |
|
678 | # we have no `kwargs` after this while loop | |
|
679 | break | |
|
680 | else: | |
|
681 | if param.kind == _VAR_POSITIONAL: | |
|
682 | # That's OK, just empty *args. Let's start parsing | |
|
683 | # kwargs | |
|
684 | break | |
|
685 | elif param.name in kwargs: | |
|
686 | if param.kind == _POSITIONAL_ONLY: | |
|
687 | msg = '{arg!r} parameter is positional only, ' \ | |
|
688 | 'but was passed as a keyword' | |
|
689 | msg = msg.format(arg=param.name) | |
|
690 | raise TypeError(msg) | |
|
691 | parameters_ex = (param,) | |
|
692 | break | |
|
693 | elif (param.kind == _VAR_KEYWORD or | |
|
694 | param.default is not _empty): | |
|
695 | # That's fine too - we have a default value for this | |
|
696 | # parameter. So, lets start parsing `kwargs`, starting | |
|
697 | # with the current parameter | |
|
698 | parameters_ex = (param,) | |
|
699 | break | |
|
700 | else: | |
|
701 | if partial: | |
|
702 | parameters_ex = (param,) | |
|
703 | break | |
|
704 | else: | |
|
705 | msg = '{arg!r} parameter lacking default value' | |
|
706 | msg = msg.format(arg=param.name) | |
|
707 | raise TypeError(msg) | |
|
708 | else: | |
|
709 | # We have a positional argument to process | |
|
710 | try: | |
|
711 | param = next(parameters) | |
|
712 | except StopIteration: | |
|
713 | raise TypeError('too many positional arguments') | |
|
714 | else: | |
|
715 | if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY): | |
|
716 | # Looks like we have no parameter for this positional | |
|
717 | # argument | |
|
718 | raise TypeError('too many positional arguments') | |
|
719 | ||
|
720 | if param.kind == _VAR_POSITIONAL: | |
|
721 | # We have an '*args'-like argument, let's fill it with | |
|
722 | # all positional arguments we have left and move on to | |
|
723 | # the next phase | |
|
724 | values = [arg_val] | |
|
725 | values.extend(arg_vals) | |
|
726 | arguments[param.name] = tuple(values) | |
|
727 | break | |
|
728 | ||
|
729 | if param.name in kwargs: | |
|
730 | raise TypeError('multiple values for argument ' | |
|
731 | '{arg!r}'.format(arg=param.name)) | |
|
732 | ||
|
733 | arguments[param.name] = arg_val | |
|
734 | ||
|
735 | # Now, we iterate through the remaining parameters to process | |
|
736 | # keyword arguments | |
|
737 | kwargs_param = None | |
|
738 | for param in itertools.chain(parameters_ex, parameters): | |
|
739 | if param.kind == _POSITIONAL_ONLY: | |
|
740 | # This should never happen in case of a properly built | |
|
741 | # Signature object (but let's have this check here | |
|
742 | # to ensure correct behaviour just in case) | |
|
743 | raise TypeError('{arg!r} parameter is positional only, ' | |
|
744 | 'but was passed as a keyword'. \ | |
|
745 | format(arg=param.name)) | |
|
746 | ||
|
747 | if param.kind == _VAR_KEYWORD: | |
|
748 | # Memorize that we have a '**kwargs'-like parameter | |
|
749 | kwargs_param = param | |
|
750 | continue | |
|
751 | ||
|
752 | param_name = param.name | |
|
753 | try: | |
|
754 | arg_val = kwargs.pop(param_name) | |
|
755 | except KeyError: | |
|
756 | # We have no value for this parameter. It's fine though, | |
|
757 | # if it has a default value, or it is an '*args'-like | |
|
758 | # parameter, left alone by the processing of positional | |
|
759 | # arguments. | |
|
760 | if (not partial and param.kind != _VAR_POSITIONAL and | |
|
761 | param.default is _empty): | |
|
762 | raise TypeError('{arg!r} parameter lacking default value'. \ | |
|
763 | format(arg=param_name)) | |
|
764 | ||
|
765 | else: | |
|
766 | arguments[param_name] = arg_val | |
|
767 | ||
|
768 | if kwargs: | |
|
769 | if kwargs_param is not None: | |
|
770 | # Process our '**kwargs'-like parameter | |
|
771 | arguments[kwargs_param.name] = kwargs | |
|
772 | else: | |
|
773 | raise TypeError('too many keyword arguments') | |
|
774 | ||
|
775 | return self._bound_arguments_cls(self, arguments) | |
|
776 | ||
|
777 | def bind(self, *args, **kwargs): | |
|
778 | '''Get a BoundArguments object, that maps the passed `args` | |
|
779 | and `kwargs` to the function's signature. Raises `TypeError` | |
|
780 | if the passed arguments can not be bound. | |
|
781 | ''' | |
|
782 | return self._bind(args, kwargs) | |
|
783 | ||
|
784 | def bind_partial(self, *args, **kwargs): | |
|
785 | '''Get a BoundArguments object, that partially maps the | |
|
786 | passed `args` and `kwargs` to the function's signature. | |
|
787 | Raises `TypeError` if the passed arguments can not be bound. | |
|
788 | ''' | |
|
789 | return self._bind(args, kwargs, partial=True) | |
|
790 | ||
|
791 | def __str__(self): | |
|
792 | result = [] | |
|
793 | render_kw_only_separator = True | |
|
794 | for idx, param in enumerate(self.parameters.values()): | |
|
795 | formatted = str(param) | |
|
796 | ||
|
797 | kind = param.kind | |
|
798 | if kind == _VAR_POSITIONAL: | |
|
799 | # OK, we have an '*args'-like parameter, so we won't need | |
|
800 | # a '*' to separate keyword-only arguments | |
|
801 | render_kw_only_separator = False | |
|
802 | elif kind == _KEYWORD_ONLY and render_kw_only_separator: | |
|
803 | # We have a keyword-only parameter to render and we haven't | |
|
804 | # rendered an '*args'-like parameter before, so add a '*' | |
|
805 | # separator to the parameters list ("foo(arg1, *, arg2)" case) | |
|
806 | result.append('*') | |
|
807 | # This condition should be only triggered once, so | |
|
808 | # reset the flag | |
|
809 | render_kw_only_separator = False | |
|
810 | ||
|
811 | result.append(formatted) | |
|
812 | ||
|
813 | rendered = '({0})'.format(', '.join(result)) | |
|
814 | ||
|
815 | if self.return_annotation is not _empty: | |
|
816 | anno = formatannotation(self.return_annotation) | |
|
817 | rendered += ' -> {0}'.format(anno) | |
|
818 | ||
|
819 | return rendered |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
@@ -14,12 +14,17 b'' | |||
|
14 | 14 | display: box; |
|
15 | 15 | box-orient: horizontal; |
|
16 | 16 | box-align: stretch; |
|
17 | ||
|
18 | display: flex; | |
|
19 | flex-direction: row; | |
|
20 | align-items: stretch; | |
|
17 | 21 | } |
|
18 | 22 | |
|
19 | 23 | .hbox > * { |
|
20 | 24 | -webkit-box-flex: 0; |
|
21 | 25 | -moz-box-flex: 0; |
|
22 | 26 | box-flex: 0; |
|
27 | flex: auto; | |
|
23 | 28 | } |
|
24 | 29 | |
|
25 | 30 | .vbox { |
@@ -36,30 +41,38 b'' | |||
|
36 | 41 | box-align: stretch; |
|
37 | 42 | /* width must be 100% to force FF to behave like webkit */ |
|
38 | 43 | width: 100%; |
|
44 | ||
|
45 | display: flex; | |
|
46 | flex-direction: column; | |
|
47 | align-items: stretch; | |
|
39 | 48 | } |
|
40 | 49 | |
|
41 | 50 | .vbox > * { |
|
42 | 51 | -webkit-box-flex: 0; |
|
43 | 52 | -moz-box-flex: 0; |
|
44 | 53 | box-flex: 0; |
|
54 | flex: auto; | |
|
45 | 55 | } |
|
46 | 56 | |
|
47 | 57 | .reverse { |
|
48 | 58 | -webkit-box-direction: reverse; |
|
49 | 59 | -moz-box-direction: reverse; |
|
50 | 60 | box-direction: reverse; |
|
61 | flex-direction: column-reverse; | |
|
51 | 62 | } |
|
52 | 63 | |
|
53 | 64 | .box-flex0 { |
|
54 | 65 | -webkit-box-flex: 0; |
|
55 | 66 | -moz-box-flex: 0; |
|
56 | 67 | box-flex: 0; |
|
68 | flex: auto; | |
|
57 | 69 | } |
|
58 | 70 | |
|
59 | 71 | .box-flex1 { |
|
60 | 72 | -webkit-box-flex: 1; |
|
61 | 73 | -moz-box-flex: 1; |
|
62 | 74 | box-flex: 1; |
|
75 | flex: 1; | |
|
63 | 76 | } |
|
64 | 77 | |
|
65 | 78 | .box-flex { |
@@ -70,15 +83,24 b'' | |||
|
70 | 83 | -webkit-box-flex: 2; |
|
71 | 84 | -moz-box-flex: 2; |
|
72 | 85 | box-flex: 2; |
|
86 | flex: 2; | |
|
73 | 87 | } |
|
74 | 88 | |
|
75 | 89 | .box-group1 { |
|
90 | /* | |
|
91 | Deprecated | |
|
92 | Grouping isn't supported in http://dev.w3.org/csswg/css-flexbox/ | |
|
93 | */ | |
|
76 | 94 | -webkit-box-flex-group: 1; |
|
77 | 95 | -moz-box-flex-group: 1; |
|
78 | 96 | box-flex-group: 1; |
|
79 | 97 | } |
|
80 | 98 | |
|
81 | 99 | .box-group2 { |
|
100 | /* | |
|
101 | Deprecated | |
|
102 | Grouping isn't supported in http://dev.w3.org/csswg/css-flexbox/ | |
|
103 | */ | |
|
82 | 104 | -webkit-box-flex-group: 2; |
|
83 | 105 | -moz-box-flex-group: 2; |
|
84 | 106 | box-flex-group: 2; |
@@ -88,34 +110,40 b'' | |||
|
88 | 110 | -webkit-box-pack: start; |
|
89 | 111 | -moz-box-pack: start; |
|
90 | 112 | box-pack: start; |
|
113 | justify-content: flex-start; | |
|
91 | 114 | } |
|
92 | 115 | |
|
93 | 116 | .end { |
|
94 | 117 | -webkit-box-pack: end; |
|
95 | 118 | -moz-box-pack: end; |
|
96 | 119 | box-pack: end; |
|
120 | justify-content: flex-end; | |
|
97 | 121 | } |
|
98 | 122 | |
|
99 | 123 | .center { |
|
100 | 124 | -webkit-box-pack: center; |
|
101 | 125 | -moz-box-pack: center; |
|
102 | 126 | box-pack: center; |
|
127 | justify-content: center; | |
|
103 | 128 | } |
|
104 | 129 | |
|
105 | 130 | .align-start { |
|
106 |
|
|
|
107 |
|
|
|
108 |
|
|
|
131 | -webkit-box-align: start; | |
|
132 | -moz-box-align: start; | |
|
133 | box-align: start; | |
|
134 | align-content: flex-start; | |
|
109 | 135 | } |
|
110 | 136 | |
|
111 | 137 | .align-end { |
|
112 |
|
|
|
113 |
|
|
|
114 |
|
|
|
138 | -webkit-box-align: end; | |
|
139 | -moz-box-align: end; | |
|
140 | box-align: end; | |
|
141 | align-content: flex-end; | |
|
115 | 142 | } |
|
116 | 143 | |
|
117 | 144 | .align-center { |
|
118 |
|
|
|
119 |
|
|
|
120 |
|
|
|
145 | -webkit-box-align: center; | |
|
146 | -moz-box-align: center; | |
|
147 | box-align: center; | |
|
148 | align-content: center; | |
|
121 | 149 | } |
@@ -540,6 +540,7 b' var IPython = (function (IPython) {' | |||
|
540 | 540 | var ShortcutManager = function (delay) { |
|
541 | 541 | this._shortcuts = {} |
|
542 | 542 | this._counts = {} |
|
543 | this._timers = {} | |
|
543 | 544 | this.delay = delay || 800; // delay in milliseconds |
|
544 | 545 | } |
|
545 | 546 | |
@@ -633,17 +634,21 b' var IPython = (function (IPython) {' | |||
|
633 | 634 | ShortcutManager.prototype.count_handler = function (shortcut, event, data) { |
|
634 | 635 | var that = this; |
|
635 | 636 | var c = this._counts; |
|
637 | var t = this._timers; | |
|
638 | var timer = null; | |
|
636 | 639 | if (c[shortcut] === data.count-1) { |
|
637 | 640 | c[shortcut] = 0; |
|
641 | var timer = t[shortcut]; | |
|
642 | if (timer) {clearTimeout(timer); delete t[shortcut];} | |
|
638 | 643 | return data.handler(event); |
|
639 | 644 | } else { |
|
640 | 645 | c[shortcut] = c[shortcut] + 1; |
|
641 | setTimeout(function () { | |
|
646 | timer = setTimeout(function () { | |
|
642 | 647 | c[shortcut] = 0; |
|
643 | 648 | }, that.delay); |
|
649 | t[shortcut] = timer; | |
|
644 | 650 | } |
|
645 | 651 | return false; |
|
646 | ||
|
647 | 652 | } |
|
648 | 653 | |
|
649 | 654 | ShortcutManager.prototype.call_handler = function (event) { |
@@ -36,9 +36,6 b' div.prompt {' | |||
|
36 | 36 | div.inner_cell { |
|
37 | 37 | .vbox(); |
|
38 | 38 | .box-flex1(); |
|
39 | ||
|
40 | /* This is required for FF to add scrollbars when code cells overflow. */ | |
|
41 | overflow: auto; | |
|
42 | 39 | } |
|
43 | 40 | |
|
44 | 41 | /* This is needed so that empty prompt areas can collapse to zero height when there |
@@ -22,12 +22,12 b'' | |||
|
22 | 22 | overflow-x: auto; |
|
23 | 23 | } |
|
24 | 24 | |
|
25 |
@-moz-document |
|
|
26 |
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
|
25 | @-moz-document { | |
|
26 | /* Firefox does weird and terrible things (#3549) when overflow-x is auto */ | |
|
27 | /* It doesn't respect the overflow setting anyway, so we can workaround it with this */ | |
|
28 | .CodeMirror-scroll { | |
|
29 | overflow-x: hidden; | |
|
30 | } | |
|
31 | 31 | } |
|
32 | 32 | |
|
33 | 33 | .CodeMirror-lines { |
@@ -4,23 +4,23 b'' | |||
|
4 | 4 | .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} |
|
5 | 5 | .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box} |
|
6 | 6 | .corner-all{border-radius:4px} |
|
7 | .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch} | |
|
8 | .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0} | |
|
9 | .vbox{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%} | |
|
10 | .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0} | |
|
11 | .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse} | |
|
12 | .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0} | |
|
13 | .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1} | |
|
14 | .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1} | |
|
15 | .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2} | |
|
7 | .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch} | |
|
8 | .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto} | |
|
9 | .vbox{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch} | |
|
10 | .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto} | |
|
11 | .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:column-reverse} | |
|
12 | .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto} | |
|
13 | .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
14 | .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
15 | .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2} | |
|
16 | 16 | .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1} |
|
17 | 17 | .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2} |
|
18 | .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start} | |
|
19 | .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end} | |
|
20 | .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center} | |
|
21 | .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start} | |
|
22 | .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end} | |
|
23 | .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center} | |
|
18 | .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start} | |
|
19 | .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;justify-content:flex-end} | |
|
20 | .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;justify-content:center} | |
|
21 | .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start;align-content:flex-start} | |
|
22 | .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end;align-content:flex-end} | |
|
23 | .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center;align-content:center} | |
|
24 | 24 | div.error{margin:2em;text-align:center} |
|
25 | 25 | div.error>h1{font-size:500%;line-height:normal} |
|
26 | 26 | div.error>p{font-size:200%;line-height:normal} |
@@ -68,18 +68,18 b' input.engine_num_input{width:60px}' | |||
|
68 | 68 | .ansibgpurple{background-color:#f0f} |
|
69 | 69 | .ansibgcyan{background-color:#0ff} |
|
70 | 70 | .ansibggray{background-color:#808080} |
|
71 | div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%}div.cell.selected{border-radius:4px;border:thin #ababab solid} | |
|
71 | div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch}div.cell.selected{border-radius:4px;border:thin #ababab solid} | |
|
72 | 72 | div.cell.edit_mode{border-radius:4px;border:thin #008000 solid} |
|
73 | 73 | div.cell{width:100%;padding:5px 5px 5px 0;margin:0;outline:none} |
|
74 | 74 | div.prompt{min-width:11ex;padding:.4em;margin:0;font-family:monospace;text-align:right;line-height:1.231em} |
|
75 |
div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1; |
|
|
75 | div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
76 | 76 | div.prompt:empty{padding-top:0;padding-bottom:0} |
|
77 | div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch} | |
|
77 | div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch} | |
|
78 | 78 | div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7} |
|
79 | 79 | div.input_prompt{color:#000080;border-top:1px solid transparent} |
|
80 | 80 | .CodeMirror{line-height:1.231em;height:auto;background:none;} |
|
81 | 81 | .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto} |
|
82 |
@-moz-document |
|
|
82 | @-moz-document {.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em} | |
|
83 | 83 | .CodeMirror-linenumber{padding:0 8px 0 4px} |
|
84 | 84 | .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px} |
|
85 | 85 | .CodeMirror pre{padding:0;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
@@ -104,18 +104,18 b' pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .j' | |||
|
104 | 104 | .cm-s-ipython span.cm-operator{color:#a2f;font-weight:bold} |
|
105 | 105 | .cm-s-ipython span.cm-meta{color:#a2f} |
|
106 | 106 | .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat} |
|
107 | div.output_wrapper{position:relative;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%} | |
|
107 | div.output_wrapper{position:relative;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch} | |
|
108 | 108 | div.output_scroll{height:24em;width:100%;overflow:auto;border-radius:4px;-webkit-box-shadow:inset 0 2px 8px rgba(0,0,0,0.8);-moz-box-shadow:inset 0 2px 8px rgba(0,0,0,0.8);box-shadow:inset 0 2px 8px rgba(0,0,0,0.8)} |
|
109 | div.output_collapsed{margin:0;padding:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%} | |
|
109 | div.output_collapsed{margin:0;padding:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch} | |
|
110 | 110 | div.out_prompt_overlay{height:100%;padding:0 .4em;position:absolute;border-radius:4px} |
|
111 | 111 | div.out_prompt_overlay:hover{-webkit-box-shadow:inset 0 0 1px #000;-moz-box-shadow:inset 0 0 1px #000;box-shadow:inset 0 0 1px #000;background:rgba(240,240,240,0.5)} |
|
112 | 112 | div.output_prompt{color:#8b0000} |
|
113 | div.output_area{padding:0;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}div.output_area .MathJax_Display{text-align:left !important} | |
|
113 | div.output_area{padding:0;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}div.output_area .MathJax_Display{text-align:left !important} | |
|
114 | 114 | div.output_area .rendered_html table{margin-left:0;margin-right:0} |
|
115 | 115 | div.output_area .rendered_html img{margin-left:0;margin-right:0} |
|
116 | .output{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%} | |
|
116 | .output{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch} | |
|
117 | 117 | div.output_area pre{font-family:monospace;margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;color:#000;background-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;line-height:inherit} |
|
118 | div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1} | |
|
118 | div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
119 | 119 | div.output_text{text-align:left;color:#000;font-family:monospace;line-height:1.231em} |
|
120 | 120 | div.output_stderr{background:#fdd;} |
|
121 | 121 | div.output_latex{text-align:left} |
@@ -165,30 +165,30 b' p.p-space{margin-bottom:10px}' | |||
|
165 | 165 | .rendered_html *+p{margin-top:1em} |
|
166 | 166 | .rendered_html img{display:block;margin-left:auto;margin-right:auto} |
|
167 | 167 | .rendered_html *+img{margin-top:1em} |
|
168 | div.text_cell{padding:5px 5px 5px 0;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch} | |
|
168 | div.text_cell{padding:5px 5px 5px 0;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch} | |
|
169 | 169 | div.text_cell_input{color:#000;border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7} |
|
170 | 170 | div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000} |
|
171 | 171 | a.anchor-link:link{text-decoration:none;padding:0 20px;visibility:hidden} |
|
172 | 172 | h1:hover .anchor-link,h2:hover .anchor-link,h3:hover .anchor-link,h4:hover .anchor-link,h5:hover .anchor-link,h6:hover .anchor-link{visibility:visible} |
|
173 | 173 | div.cell.text_cell.rendered{padding:0} |
|
174 | .widget-area{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}.widget-area .widget-subarea{padding:.44em .4em .4em 1px;margin-left:6px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2} | |
|
174 | .widget-area{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.widget-area .widget-subarea{padding:.44em .4em .4em 1px;margin-left:6px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2} | |
|
175 | 175 | .widget-hlabel{min-width:10ex;padding-right:8px;padding-top:3px;text-align:right;vertical-align:text-top} |
|
176 | 176 | .widget-vlabel{padding-bottom:5px;text-align:center;vertical-align:text-bottom} |
|
177 | 177 | .widget-hreadout{padding-left:8px;padding-top:3px;text-align:left;vertical-align:text-top} |
|
178 | 178 | .widget-vreadout{padding-top:5px;text-align:center;vertical-align:text-top} |
|
179 | 179 | .slide-track{border:1px solid #ccc;background:#fff;border-radius:4px;} |
|
180 | .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}.widget-hslider .ui-slider{border:0 !important;background:none !important;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important} | |
|
181 | .widget-vslider{padding-bottom:8px;overflow:visible;width:5px;max-width:5px;height:250px;margin-left:12px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%}.widget-vslider .ui-slider{border:0 !important;background:none !important;margin-left:-4px;margin-top:5px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px} | |
|
180 | .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.widget-hslider .ui-slider{border:0 !important;background:none !important;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important} | |
|
181 | .widget-vslider{padding-bottom:8px;overflow:visible;width:5px;max-width:5px;height:250px;margin-left:12px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch}.widget-vslider .ui-slider{border:0 !important;background:none !important;margin-left:-4px;margin-top:5px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px} | |
|
182 | 182 | .widget-text{width:350px;margin-bottom:0} |
|
183 | 183 | .widget-listbox{width:364px;margin-bottom:0} |
|
184 | 184 | .widget-numeric-text{width:150px} |
|
185 | 185 | .widget-progress{width:363px}.widget-progress .bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none} |
|
186 | 186 | .widget-combo-btn{min-width:138px;} |
|
187 | .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box} | |
|
188 | .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch} | |
|
189 | .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;height:30px} | |
|
190 | .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%} | |
|
191 | .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;width:30px} | |
|
187 | .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box} | |
|
188 | .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch} | |
|
189 | .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch;height:30px} | |
|
190 | .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch} | |
|
191 | .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch;width:30px} | |
|
192 | 192 | .widget-modal{overflow:hidden;position:absolute !important;top:0;left:0;margin-left:0 !important} |
|
193 | 193 | .widget-modal-body{max-height:none !important} |
|
194 | 194 | .widget-container{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box} |
@@ -1,7 +1,3 b'' | |||
|
1 | .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0} | |
|
2 | .clearfix:after{clear:both} | |
|
3 | .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0} | |
|
4 | .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} | |
|
5 | 1 | article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block} |
|
6 | 2 | audio,canvas,video{display:inline-block;*display:inline;*zoom:1} |
|
7 | 3 | audio:not([controls]){display:none} |
@@ -856,6 +852,10 b' a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decorati' | |||
|
856 | 852 | .show{display:block} |
|
857 | 853 | .invisible{visibility:hidden} |
|
858 | 854 | .affix{position:fixed} |
|
855 | .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0} | |
|
856 | .clearfix:after{clear:both} | |
|
857 | .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0} | |
|
858 | .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} | |
|
859 | 859 | @-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden} |
|
860 | 860 | .visible-phone{display:none !important} |
|
861 | 861 | .visible-tablet{display:none !important} |
@@ -1267,23 +1267,23 b' a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .' | |||
|
1267 | 1267 | .icon-renren:before{content:"\f18b"} |
|
1268 | 1268 | .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box} |
|
1269 | 1269 | .corner-all{border-radius:4px} |
|
1270 | .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch} | |
|
1271 | .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0} | |
|
1272 | .vbox{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%} | |
|
1273 | .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0} | |
|
1274 | .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse} | |
|
1275 | .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0} | |
|
1276 | .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1} | |
|
1277 | .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1} | |
|
1278 | .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2} | |
|
1270 | .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch} | |
|
1271 | .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto} | |
|
1272 | .vbox{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch} | |
|
1273 | .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto} | |
|
1274 | .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:column-reverse} | |
|
1275 | .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto} | |
|
1276 | .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
1277 | .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
1278 | .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2} | |
|
1279 | 1279 | .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1} |
|
1280 | 1280 | .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2} |
|
1281 | .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start} | |
|
1282 | .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end} | |
|
1283 | .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center} | |
|
1284 | .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start} | |
|
1285 | .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end} | |
|
1286 | .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center} | |
|
1281 | .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start} | |
|
1282 | .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;justify-content:flex-end} | |
|
1283 | .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;justify-content:center} | |
|
1284 | .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start;align-content:flex-start} | |
|
1285 | .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end;align-content:flex-end} | |
|
1286 | .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center;align-content:center} | |
|
1287 | 1287 | div.error{margin:2em;text-align:center} |
|
1288 | 1288 | div.error>h1{font-size:500%;line-height:normal} |
|
1289 | 1289 | div.error>p{font-size:200%;line-height:normal} |
@@ -1345,18 +1345,18 b' input.engine_num_input{width:60px}' | |||
|
1345 | 1345 | .ansibgpurple{background-color:#f0f} |
|
1346 | 1346 | .ansibgcyan{background-color:#0ff} |
|
1347 | 1347 | .ansibggray{background-color:#808080} |
|
1348 | div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%}div.cell.selected{border-radius:4px;border:thin #ababab solid} | |
|
1348 | div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch}div.cell.selected{border-radius:4px;border:thin #ababab solid} | |
|
1349 | 1349 | div.cell.edit_mode{border-radius:4px;border:thin #008000 solid} |
|
1350 | 1350 | div.cell{width:100%;padding:5px 5px 5px 0;margin:0;outline:none} |
|
1351 | 1351 | div.prompt{min-width:11ex;padding:.4em;margin:0;font-family:monospace;text-align:right;line-height:1.231em} |
|
1352 |
div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1; |
|
|
1352 | div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
1353 | 1353 | div.prompt:empty{padding-top:0;padding-bottom:0} |
|
1354 | div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch} | |
|
1354 | div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch} | |
|
1355 | 1355 | div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7} |
|
1356 | 1356 | div.input_prompt{color:#000080;border-top:1px solid transparent} |
|
1357 | 1357 | .CodeMirror{line-height:1.231em;height:auto;background:none;} |
|
1358 | 1358 | .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto} |
|
1359 |
@-moz-document |
|
|
1359 | @-moz-document {.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em} | |
|
1360 | 1360 | .CodeMirror-linenumber{padding:0 8px 0 4px} |
|
1361 | 1361 | .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px} |
|
1362 | 1362 | .CodeMirror pre{padding:0;border:0;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
@@ -1381,18 +1381,18 b' pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .j' | |||
|
1381 | 1381 | .cm-s-ipython span.cm-operator{color:#a2f;font-weight:bold} |
|
1382 | 1382 | .cm-s-ipython span.cm-meta{color:#a2f} |
|
1383 | 1383 | .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat} |
|
1384 | div.output_wrapper{position:relative;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%} | |
|
1384 | div.output_wrapper{position:relative;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch} | |
|
1385 | 1385 | div.output_scroll{height:24em;width:100%;overflow:auto;border-radius:4px;-webkit-box-shadow:inset 0 2px 8px rgba(0,0,0,0.8);-moz-box-shadow:inset 0 2px 8px rgba(0,0,0,0.8);box-shadow:inset 0 2px 8px rgba(0,0,0,0.8)} |
|
1386 | div.output_collapsed{margin:0;padding:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%} | |
|
1386 | div.output_collapsed{margin:0;padding:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch} | |
|
1387 | 1387 | div.out_prompt_overlay{height:100%;padding:0 .4em;position:absolute;border-radius:4px} |
|
1388 | 1388 | div.out_prompt_overlay:hover{-webkit-box-shadow:inset 0 0 1px #000;-moz-box-shadow:inset 0 0 1px #000;box-shadow:inset 0 0 1px #000;background:rgba(240,240,240,0.5)} |
|
1389 | 1389 | div.output_prompt{color:#8b0000} |
|
1390 | div.output_area{padding:0;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}div.output_area .MathJax_Display{text-align:left !important} | |
|
1390 | div.output_area{padding:0;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}div.output_area .MathJax_Display{text-align:left !important} | |
|
1391 | 1391 | div.output_area .rendered_html table{margin-left:0;margin-right:0} |
|
1392 | 1392 | div.output_area .rendered_html img{margin-left:0;margin-right:0} |
|
1393 | .output{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%} | |
|
1393 | .output{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch} | |
|
1394 | 1394 | div.output_area pre{font-family:monospace;margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;color:#000;background-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;line-height:inherit} |
|
1395 | div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1} | |
|
1395 | div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
1396 | 1396 | div.output_text{text-align:left;color:#000;font-family:monospace;line-height:1.231em} |
|
1397 | 1397 | div.output_stderr{background:#fdd;} |
|
1398 | 1398 | div.output_latex{text-align:left} |
@@ -1442,30 +1442,30 b' p.p-space{margin-bottom:10px}' | |||
|
1442 | 1442 | .rendered_html *+p{margin-top:1em} |
|
1443 | 1443 | .rendered_html img{display:block;margin-left:auto;margin-right:auto} |
|
1444 | 1444 | .rendered_html *+img{margin-top:1em} |
|
1445 | div.text_cell{padding:5px 5px 5px 0;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch} | |
|
1445 | div.text_cell{padding:5px 5px 5px 0;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch} | |
|
1446 | 1446 | div.text_cell_input{color:#000;border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7} |
|
1447 | 1447 | div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000} |
|
1448 | 1448 | a.anchor-link:link{text-decoration:none;padding:0 20px;visibility:hidden} |
|
1449 | 1449 | h1:hover .anchor-link,h2:hover .anchor-link,h3:hover .anchor-link,h4:hover .anchor-link,h5:hover .anchor-link,h6:hover .anchor-link{visibility:visible} |
|
1450 | 1450 | div.cell.text_cell.rendered{padding:0} |
|
1451 | .widget-area{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}.widget-area .widget-subarea{padding:.44em .4em .4em 1px;margin-left:6px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2} | |
|
1451 | .widget-area{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.widget-area .widget-subarea{padding:.44em .4em .4em 1px;margin-left:6px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2} | |
|
1452 | 1452 | .widget-hlabel{min-width:10ex;padding-right:8px;padding-top:3px;text-align:right;vertical-align:text-top} |
|
1453 | 1453 | .widget-vlabel{padding-bottom:5px;text-align:center;vertical-align:text-bottom} |
|
1454 | 1454 | .widget-hreadout{padding-left:8px;padding-top:3px;text-align:left;vertical-align:text-top} |
|
1455 | 1455 | .widget-vreadout{padding-top:5px;text-align:center;vertical-align:text-top} |
|
1456 | 1456 | .slide-track{border:1px solid #ccc;background:#fff;border-radius:4px;} |
|
1457 | .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}.widget-hslider .ui-slider{border:0 !important;background:none !important;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important} | |
|
1458 | .widget-vslider{padding-bottom:8px;overflow:visible;width:5px;max-width:5px;height:250px;margin-left:12px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%}.widget-vslider .ui-slider{border:0 !important;background:none !important;margin-left:-4px;margin-top:5px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px} | |
|
1457 | .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.widget-hslider .ui-slider{border:0 !important;background:none !important;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important} | |
|
1458 | .widget-vslider{padding-bottom:8px;overflow:visible;width:5px;max-width:5px;height:250px;margin-left:12px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch}.widget-vslider .ui-slider{border:0 !important;background:none !important;margin-left:-4px;margin-top:5px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px} | |
|
1459 | 1459 | .widget-text{width:350px;margin-bottom:0} |
|
1460 | 1460 | .widget-listbox{width:364px;margin-bottom:0} |
|
1461 | 1461 | .widget-numeric-text{width:150px} |
|
1462 | 1462 | .widget-progress{width:363px}.widget-progress .bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none} |
|
1463 | 1463 | .widget-combo-btn{min-width:138px;} |
|
1464 | .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box} | |
|
1465 | .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch} | |
|
1466 | .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;height:30px} | |
|
1467 | .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%} | |
|
1468 | .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;width:30px} | |
|
1464 | .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box} | |
|
1465 | .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch} | |
|
1466 | .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch;height:30px} | |
|
1467 | .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch} | |
|
1468 | .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch;width:30px} | |
|
1469 | 1469 | .widget-modal{overflow:hidden;position:absolute !important;top:0;left:0;margin-left:0 !important} |
|
1470 | 1470 | .widget-modal-body{max-height:none !important} |
|
1471 | 1471 | .widget-container{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box} |
@@ -1482,7 +1482,7 b' pre,code,kbd,samp{white-space:pre-wrap}' | |||
|
1482 | 1482 | #fonttest{font-family:monospace} |
|
1483 | 1483 | p{margin-bottom:0} |
|
1484 | 1484 | .end_space{height:200px} |
|
1485 | .celltoolbar{border:thin solid #cfcfcf;border-bottom:none;background:#eee;border-radius:3px 3px 0 0;width:100%;-webkit-box-pack:end;height:22px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse} | |
|
1485 | .celltoolbar{border:thin solid #cfcfcf;border-bottom:none;background:#eee;border-radius:3px 3px 0 0;width:100%;-webkit-box-pack:end;height:22px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch;-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:column-reverse} | |
|
1486 | 1486 | .ctb_hideshow{display:none;vertical-align:bottom;padding-right:2px} |
|
1487 | 1487 | .celltoolbar>div{padding-top:0} |
|
1488 | 1488 | .ctb_global_show .ctb_show.ctb_hideshow{display:block} |
@@ -9,3 +9,4 b' from .widget_int import IntTextWidget, BoundedIntTextWidget, IntSliderWidget, In' | |||
|
9 | 9 | from .widget_selection import RadioButtonsWidget, ToggleButtonsWidget, DropdownWidget, SelectWidget |
|
10 | 10 | from .widget_selectioncontainer import TabWidget, AccordionWidget |
|
11 | 11 | from .widget_string import HTMLWidget, LatexWidget, TextWidget, TextareaWidget |
|
12 | from .interaction import interact, interactive, fixed |
@@ -53,7 +53,7 b' class FloatSliderWidget(_BoundedFloatWidget):' | |||
|
53 | 53 | _view_name = Unicode('FloatSliderView', sync=True) |
|
54 | 54 | orientation = Enum([u'horizontal', u'vertical'], u'horizontal', |
|
55 | 55 | help="Vertical or horizontal.", sync=True) |
|
56 |
readout = Bool( |
|
|
56 | readout = Bool(True, help="Display the current value of the slider next to it.", sync=True) | |
|
57 | 57 | |
|
58 | 58 | |
|
59 | 59 | class FloatProgressWidget(_BoundedFloatWidget): |
@@ -53,7 +53,7 b' class IntSliderWidget(_BoundedIntWidget):' | |||
|
53 | 53 | _view_name = Unicode('IntSliderView', sync=True) |
|
54 | 54 | orientation = Enum([u'horizontal', u'vertical'], u'horizontal', |
|
55 | 55 | help="Vertical or horizontal.", sync=True) |
|
56 |
readout = Bool( |
|
|
56 | readout = Bool(True, help="Display the current value of the slider next to it.", sync=True) | |
|
57 | 57 | |
|
58 | 58 | |
|
59 | 59 | class IntProgressWidget(_BoundedIntWidget): |
@@ -86,6 +86,7 b' class InProcessShellChannel(InProcessChannel):' | |||
|
86 | 86 | 'object_info', |
|
87 | 87 | 'history', |
|
88 | 88 | 'shutdown', |
|
89 | 'kernel_info', | |
|
89 | 90 | ] |
|
90 | 91 | |
|
91 | 92 | #-------------------------------------------------------------------------- |
@@ -127,6 +128,12 b' class InProcessShellChannel(InProcessChannel):' | |||
|
127 | 128 | # FIXME: What to do here? |
|
128 | 129 | raise NotImplementedError('Cannot shutdown in-process kernel') |
|
129 | 130 | |
|
131 | def kernel_info(self): | |
|
132 | """Request kernel info.""" | |
|
133 | msg = self.client.session.msg('kernel_info_request') | |
|
134 | self._dispatch_to_kernel(msg) | |
|
135 | return msg['header']['msg_id'] | |
|
136 | ||
|
130 | 137 | #-------------------------------------------------------------------------- |
|
131 | 138 | # Protected interface |
|
132 | 139 | #-------------------------------------------------------------------------- |
@@ -223,6 +223,21 b' else:' | |||
|
223 | 223 | filename = fname |
|
224 | 224 | builtin_mod.execfile(filename, *where) |
|
225 | 225 | |
|
226 | ||
|
227 | def annotate(**kwargs): | |
|
228 | """Python 3 compatible function annotation for Python 2.""" | |
|
229 | if not kwargs: | |
|
230 | raise ValueError('annotations must be provided as keyword arguments') | |
|
231 | def dec(f): | |
|
232 | if hasattr(f, '__annotations__'): | |
|
233 | for k, v in kwargs.items(): | |
|
234 | f.__annotations__[k] = v | |
|
235 | else: | |
|
236 | f.__annotations__ = kwargs | |
|
237 | return f | |
|
238 | return dec | |
|
239 | ||
|
240 | ||
|
226 | 241 | # Parts below taken from six: |
|
227 | 242 | # Copyright (c) 2010-2013 Benjamin Peterson |
|
228 | 243 | # |
@@ -32,7 +32,7 b' from IPython.utils.traitlets import (' | |||
|
32 | 32 | HasTraits, MetaHasTraits, TraitType, Any, CBytes, Dict, |
|
33 | 33 | Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError, |
|
34 | 34 | Undefined, Type, This, Instance, TCPAddress, List, Tuple, |
|
35 |
ObjectName, DottedObjectName, CRegExp, |
|
|
35 | ObjectName, DottedObjectName, CRegExp, link | |
|
36 | 36 | ) |
|
37 | 37 | from IPython.utils import py3compat |
|
38 | 38 | from IPython.testing.decorators import skipif |
@@ -974,9 +974,9 b' def test_dict_assignment():' | |||
|
974 | 974 | nt.assert_equal(d, c.value) |
|
975 | 975 | nt.assert_true(c.value is d) |
|
976 | 976 | |
|
977 |
class Test |
|
|
977 | class TestLink(TestCase): | |
|
978 | 978 | def test_connect_same(self): |
|
979 |
"""Verify two traitlets of the same type can be |
|
|
979 | """Verify two traitlets of the same type can be linked together using link.""" | |
|
980 | 980 | |
|
981 | 981 | # Create two simple classes with Int traitlets. |
|
982 | 982 | class A(HasTraits): |
@@ -985,9 +985,9 b' class TestBind(TestCase):' | |||
|
985 | 985 | b = A(value=8) |
|
986 | 986 | |
|
987 | 987 | # Conenct the two classes. |
|
988 |
c = |
|
|
988 | c = link((a, 'value'), (b, 'value')) | |
|
989 | 989 | |
|
990 |
# Make sure the values are the same at the point of |
|
|
990 | # Make sure the values are the same at the point of linking. | |
|
991 | 991 | self.assertEqual(a.value, b.value) |
|
992 | 992 | |
|
993 | 993 | # Change one of the values to make sure they stay in sync. |
@@ -996,8 +996,8 b' class TestBind(TestCase):' | |||
|
996 | 996 | b.value = 6 |
|
997 | 997 | self.assertEqual(a.value, b.value) |
|
998 | 998 | |
|
999 |
def test_ |
|
|
1000 |
"""Verify two traitlets of different types can be |
|
|
999 | def test_link_different(self): | |
|
1000 | """Verify two traitlets of different types can be linked together using link.""" | |
|
1001 | 1001 | |
|
1002 | 1002 | # Create two simple classes with Int traitlets. |
|
1003 | 1003 | class A(HasTraits): |
@@ -1008,9 +1008,9 b' class TestBind(TestCase):' | |||
|
1008 | 1008 | b = B(count=8) |
|
1009 | 1009 | |
|
1010 | 1010 | # Conenct the two classes. |
|
1011 |
c = |
|
|
1011 | c = link((a, 'value'), (b, 'count')) | |
|
1012 | 1012 | |
|
1013 |
# Make sure the values are the same at the point of |
|
|
1013 | # Make sure the values are the same at the point of linking. | |
|
1014 | 1014 | self.assertEqual(a.value, b.count) |
|
1015 | 1015 | |
|
1016 | 1016 | # Change one of the values to make sure they stay in sync. |
@@ -1019,8 +1019,8 b' class TestBind(TestCase):' | |||
|
1019 | 1019 | b.count = 4 |
|
1020 | 1020 | self.assertEqual(a.value, b.count) |
|
1021 | 1021 | |
|
1022 |
def test_un |
|
|
1023 |
"""Verify two |
|
|
1022 | def test_unlink(self): | |
|
1023 | """Verify two linked traitlets can be unlinked.""" | |
|
1024 | 1024 | |
|
1025 | 1025 | # Create two simple classes with Int traitlets. |
|
1026 | 1026 | class A(HasTraits): |
@@ -1028,17 +1028,17 b' class TestBind(TestCase):' | |||
|
1028 | 1028 | a = A(value=9) |
|
1029 | 1029 | b = A(value=8) |
|
1030 | 1030 | |
|
1031 |
# Con |
|
|
1032 |
c = |
|
|
1031 | # Connect the two classes. | |
|
1032 | c = link((a, 'value'), (b, 'value')) | |
|
1033 | 1033 | a.value = 4 |
|
1034 |
c.un |
|
|
1034 | c.unlink() | |
|
1035 | 1035 | |
|
1036 | # Change one of the values to make sure they stay in sync. | |
|
1036 | # Change one of the values to make sure they don't stay in sync. | |
|
1037 | 1037 | a.value = 5 |
|
1038 | 1038 | self.assertNotEqual(a.value, b.value) |
|
1039 | 1039 | |
|
1040 | 1040 | def test_callbacks(self): |
|
1041 |
"""Verify two |
|
|
1041 | """Verify two linked traitlets have their callbacks called once.""" | |
|
1042 | 1042 | |
|
1043 | 1043 | # Create two simple classes with Int traitlets. |
|
1044 | 1044 | class A(HasTraits): |
@@ -1057,8 +1057,8 b' class TestBind(TestCase):' | |||
|
1057 | 1057 | callback_count.append('b') |
|
1058 | 1058 | b.on_trait_change(b_callback, 'count') |
|
1059 | 1059 | |
|
1060 |
# Con |
|
|
1061 |
c = |
|
|
1060 | # Connect the two classes. | |
|
1061 | c = link((a, 'value'), (b, 'count')) | |
|
1062 | 1062 | |
|
1063 | 1063 | # Make sure b's count was set to a's value once. |
|
1064 | 1064 | self.assertEqual(''.join(callback_count), 'b') |
@@ -184,8 +184,8 b' def getmembers(object, predicate=None):' | |||
|
184 | 184 | return results |
|
185 | 185 | |
|
186 | 186 | @skip_doctest |
|
187 |
class |
|
|
188 |
""" |
|
|
187 | class link(object): | |
|
188 | """Link traits from different objects together so they remain in sync. | |
|
189 | 189 | |
|
190 | 190 | Parameters |
|
191 | 191 | ---------- |
@@ -194,7 +194,7 b' class bind(object):' | |||
|
194 | 194 | Examples |
|
195 | 195 | -------- |
|
196 | 196 | |
|
197 |
>>> c = |
|
|
197 | >>> c = link((obj1, 'value'), (obj2, 'value'), (obj3, 'value')) | |
|
198 | 198 | >>> obj1.value = 5 # updates other objects as well |
|
199 | 199 | """ |
|
200 | 200 | updating = False |
@@ -233,7 +233,7 b' class bind(object):' | |||
|
233 | 233 | if obj is not sending_obj or attr != sending_attr: |
|
234 | 234 | setattr(obj, attr, new) |
|
235 | 235 | |
|
236 |
def un |
|
|
236 | def unlink(self): | |
|
237 | 237 | for key, callback in self.objects.items(): |
|
238 | 238 | (obj,attr) = key |
|
239 | 239 | obj.on_trait_change(callback, attr, remove=True) |
@@ -14,35 +14,29 b' Authors' | |||
|
14 | 14 | * MinRK |
|
15 | 15 | """ |
|
16 | 16 | |
|
17 | import os | |
|
18 | 17 | import sys |
|
19 | 18 | import json |
|
20 | 19 | import zmq |
|
21 | 20 | |
|
22 | 21 | from IPython.kernel.zmq.session import Session |
|
23 | from IPython.parallel.util import disambiguate_url | |
|
24 | 22 | from IPython.utils.py3compat import str_to_bytes |
|
25 | 23 | from IPython.utils.path import get_security_file |
|
26 | 24 | |
|
27 | 25 | def main(connection_file): |
|
28 | 26 | """watch iopub channel, and print messages""" |
|
29 | ||
|
27 | ||
|
30 | 28 | ctx = zmq.Context.instance() |
|
31 | ||
|
29 | ||
|
32 | 30 | with open(connection_file) as f: |
|
33 | 31 | cfg = json.loads(f.read()) |
|
34 | ||
|
35 | location = cfg['location'] | |
|
36 |
|
|
|
37 | session = Session(key=str_to_bytes(cfg['exec_key'])) | |
|
38 | ||
|
39 | query = ctx.socket(zmq.DEALER) | |
|
40 | query.connect(disambiguate_url(cfg['url'], location)) | |
|
41 | session.send(query, "connection_request") | |
|
42 | idents,msg = session.recv(query, mode=0) | |
|
43 | c = msg['content'] | |
|
44 | iopub_url = disambiguate_url(c['iopub'], location) | |
|
32 | ||
|
33 | reg_url = cfg['interface'] | |
|
34 | iopub_port = cfg['iopub'] | |
|
35 | iopub_url = "%s:%s"%(reg_url, iopub_port) | |
|
36 | ||
|
37 | session = Session(key=str_to_bytes(cfg['key'])) | |
|
45 | 38 | sub = ctx.socket(zmq.SUB) |
|
39 | ||
|
46 | 40 | # This will subscribe to all messages: |
|
47 | 41 | sub.setsockopt(zmq.SUBSCRIBE, b'') |
|
48 | 42 | # replace with b'' with b'engine.1.stdout' to subscribe only to engine 1's stdout |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
General Comments 0
You need to be logged in to leave comments.
Login now