PKH}ipywidgets/__init__.py"""Interactive widgets for the Jupyter notebook. Provide simple interactive controls in the notebook. Each Widget corresponds to an object in Python and Javascript, with controls on the page. To put a Widget on the page, you can display it with IPython's display machinery:: from ipywidgets import IntSlider from IPython.display import display slider = IntSlider(min=1, max=10) display(slider) Moving the slider will change the value. Most Widgets have a current value, accessible as a `value` attribute. """ import os from IPython import get_ipython from ._version import version_info, __version__, __frontend_version__ from .widgets import * def load_ipython_extension(ip): """Set up IPython to work with widgets""" if not hasattr(ip, 'kernel'): return register_comm_target(ip.kernel) def register_comm_target(kernel=None): """Register the jupyter.widget comm target""" if kernel is None: kernel = get_ipython().kernel kernel.comm_manager.register_target('jupyter.widget', Widget.handle_comm_opened) kernel.comm_manager.register_target('jupyter.widget.version', handle_version_comm_opened) # deprecated alias handle_kernel = register_comm_target def _handle_ipython(): """Register with the comm target at import if running in IPython""" ip = get_ipython() if ip is None: return load_ipython_extension(ip) _handle_ipython() def find_static_assets(): import warnings try: import widgetsnbextension if hasattr(widgetsnbextension, 'find_static_assets'): return widgetsnbextension.find_static_assets() else: warnings.warn("""The version of ipywidgets that you have installed only works with Jupyter Notebook 4.2 or later. Your version of the Jupyter Notebook is too old. If you'd like to use ipywidgets with an older version of the notebook, use ipywidgets 4.x or earlier. """, RuntimeWarning) return [] except ImportError: warnings.warn("""To use the widgets with your installed Jupyter Notebook version, please install ipywidgets 4.x or earlier.""", RuntimeWarning) return [] PKH'[V hhipywidgets/_version.pyversion_info = (5, 0, 0) __version__ = '.'.join(map(str, version_info)) __frontend_version__ = '~1.0.0' PK\H;qK K #ipywidgets/widgets/widget_output.py"""Output class. Represents a widget that can be used to display output within the widget area. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .domwidget import DOMWidget import sys from traitlets import Unicode, List from IPython.display import clear_output from jupyter_client.session import Message from IPython import get_ipython class Output(DOMWidget): """Widget used as a context manager to display output. This widget can capture and display stdout, stderr, and rich output. To use it, create an instance of it and display it. Then use it as a context manager. Any output produced while in it's context will be captured and displayed in it instead of the standard output area. Example:: import ipywidgets as widgets from IPython.display import display out = widgets.Output() display(out) print('prints to output area') with out: print('prints to output widget') """ _view_name = Unicode('OutputView').tag(sync=True) _model_name = Unicode('OutputModel').tag(sync=True) _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) def clear_output(self, *pargs, **kwargs): with self: clear_output(*pargs, **kwargs) def __enter__(self): """Called upon entering output widget context manager.""" self._flush() kernel = get_ipython().kernel session = kernel.session send = session.send self._original_send = send self._session = session def send_hook(stream, msg_or_type, content=None, parent=None, ident=None, buffers=None, track=False, header=None, metadata=None): # Handle both prebuild messages and unbuilt messages. if isinstance(msg_or_type, (Message, dict)): msg_type = msg_or_type['msg_type'] msg = dict(msg_or_type) else: msg_type = msg_or_type msg = session.msg(msg_type, content=content, parent=parent, header=header, metadata=metadata) # If this is a message type that we want to forward, forward it. if stream is kernel.iopub_socket and msg_type in ['clear_output', 'stream', 'display_data']: self.send(msg) else: send(stream, msg, ident=ident, buffers=buffers, track=track) session.send = send_hook def __exit__(self, exception_type, exception_value, traceback): """Called upon exiting output widget context manager.""" self._flush() self._session.send = self._original_send def _flush(self): """Flush stdout and stderr buffers.""" sys.stdout.flush() sys.stderr.flush() PKH/"ipywidgets/widgets/widget_color.py"""Color class. Represents an HTML Color . """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .domwidget import DOMWidget from .widget import register from .trait_types import Color from traitlets import Unicode, Bool @register('Jupyter.ColorPicker') class ColorPicker(DOMWidget): value = Color('black').tag(sync=True) concise = Bool().tag(sync=True) description = Unicode().tag(sync=True) _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_name = Unicode('ColorPickerView').tag(sync=True) _model_name = Unicode('ColorPickerModel').tag(sync=True) PKHj#"ipywidgets/widgets/widget_image.py"""Image class. Represents an image in the frontend using a widget. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import base64 from .domwidget import DOMWidget from .widget import register from traitlets import Unicode, CUnicode, Bytes @register('Jupyter.Image') class Image(DOMWidget): """Displays an image as a widget. The `value` of this widget accepts a byte string. The byte string is the raw image data that you want the browser to display. You can explicitly define the format of the byte string using the `format` trait (which defaults to "png"). """ _view_name = Unicode('ImageView').tag(sync=True) _model_name = Unicode('ImageModel').tag(sync=True) _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) # Define the custom state properties to sync with the front-end format = Unicode('png').tag(sync=True) width = CUnicode().tag(sync=True) height = CUnicode().tag(sync=True) _b64value = Unicode().tag(sync=True) value = Bytes() def _value_changed(self, name, old, new): self._b64value = base64.b64encode(new) PKZH˓z(/(/ipywidgets/widgets/eventful.py"""Contains eventful dict and list implementations.""" # void function used as a callback placeholder. def _void(*p, **k): return None class EventfulDict(dict): """Eventful dictionary. This class inherits from the Python intrinsic dictionary class, dict. It adds events to the get, set, and del actions and optionally allows you to intercept and cancel these actions. The eventfulness isn't recursive. In other words, if you add a dict as a child, the events of that dict won't be listened to. If you find you need something recursive, listen to the `add` and `set` methods, and then cancel `dict` values from being set, and instead set EventfulDicts that wrap those dicts. Then you can wire the events to the same handlers if necessary. See the on_events, on_add, on_set, and on_del methods for registering event handlers.""" def __init__(self, *args, **kwargs): """Public constructor""" self._add_callback = _void self._del_callback = _void self._set_callback = _void dict.__init__(self, *args, **kwargs) def on_events(self, add_callback=None, set_callback=None, del_callback=None): """Register callbacks for add, set, and del actions. See the doctstrings for on_(add/set/del) for details about each callback. add_callback: [callback = None] set_callback: [callback = None] del_callback: [callback = None]""" self.on_add(add_callback) self.on_set(set_callback) self.on_del(del_callback) def on_add(self, callback): """Register a callback for when an item is added to the dict. Allows the listener to detect when items are added to the dictionary and optionally cancel the addition. callback: callable or None If you want to ignore the addition event, pass None as the callback. The callback should have a signature of callback(key, value). The callback should return a boolean True if the additon should be canceled, False or None otherwise.""" self._add_callback = callback if callable(callback) else _void def on_del(self, callback): """Register a callback for when an item is deleted from the dict. Allows the listener to detect when items are deleted from the dictionary and optionally cancel the deletion. callback: callable or None If you want to ignore the deletion event, pass None as the callback. The callback should have a signature of callback(key). The callback should return a boolean True if the deletion should be canceled, False or None otherwise.""" self._del_callback = callback if callable(callback) else _void def on_set(self, callback): """Register a callback for when an item is changed in the dict. Allows the listener to detect when items are changed in the dictionary and optionally cancel the change. callback: callable or None If you want to ignore the change event, pass None as the callback. The callback should have a signature of callback(key, value). The callback should return a boolean True if the change should be canceled, False or None otherwise.""" self._set_callback = callback if callable(callback) else _void def pop(self, key): """Returns the value of an item in the dictionary and then deletes the item from the dictionary.""" if self._can_del(key): return dict.pop(self, key) else: raise Exception('Cannot `pop`, deletion of key "{}" failed.'.format(key)) def popitem(self): """Pop the next key/value pair from the dictionary.""" key = next(iter(self)) return key, self.pop(key) def update(self, other_dict): """Copy the key/value pairs from another dictionary into this dictionary, overwriting any conflicting keys in this dictionary.""" for (key, value) in other_dict.items(): self[key] = value def clear(self): """Clear the dictionary.""" for key in list(self.keys()): del self[key] def __setitem__(self, key, value): if (key in self and self._can_set(key, value)) or \ (key not in self and self._can_add(key, value)): return dict.__setitem__(self, key, value) def __delitem__(self, key): if self._can_del(key): return dict.__delitem__(self, key) def _can_add(self, key, value): """Check if the item can be added to the dict.""" return not bool(self._add_callback(key, value)) def _can_del(self, key): """Check if the item can be deleted from the dict.""" return not bool(self._del_callback(key)) def _can_set(self, key, value): """Check if the item can be changed in the dict.""" return not bool(self._set_callback(key, value)) class EventfulList(list): """Eventful list. This class inherits from the Python intrinsic `list` class. It adds events that allow you to listen for actions that modify the list. You can optionally cancel the actions. See the on_del, on_set, on_insert, on_sort, and on_reverse methods for registering an event handler. Some of the method docstrings were taken from the Python documentation at https://docs.python.org/2/tutorial/datastructures.html""" def __init__(self, *pargs, **kwargs): """Public constructor""" self._insert_callback = _void self._set_callback = _void self._del_callback = _void self._sort_callback = _void self._reverse_callback = _void list.__init__(self, *pargs, **kwargs) def on_events(self, insert_callback=None, set_callback=None, del_callback=None, reverse_callback=None, sort_callback=None): """Register callbacks for add, set, and del actions. See the doctstrings for on_(insert/set/del/reverse/sort) for details about each callback. insert_callback: [callback = None] set_callback: [callback = None] del_callback: [callback = None] reverse_callback: [callback = None] sort_callback: [callback = None]""" self.on_insert(insert_callback) self.on_set(set_callback) self.on_del(del_callback) self.on_reverse(reverse_callback) self.on_sort(sort_callback) def on_insert(self, callback): """Register a callback for when an item is inserted into the list. Allows the listener to detect when items are inserted into the list and optionally cancel the insertion. callback: callable or None If you want to ignore the insertion event, pass None as the callback. The callback should have a signature of callback(index, value). The callback should return a boolean True if the insertion should be canceled, False or None otherwise.""" self._insert_callback = callback if callable(callback) else _void def on_del(self, callback): """Register a callback for item deletion. Allows the listener to detect when items are deleted from the list and optionally cancel the deletion. callback: callable or None If you want to ignore the deletion event, pass None as the callback. The callback should have a signature of callback(index). The callback should return a boolean True if the deletion should be canceled, False or None otherwise.""" self._del_callback = callback if callable(callback) else _void def on_set(self, callback): """Register a callback for items are set. Allows the listener to detect when items are set and optionally cancel the setting. Note, `set` is also called when one or more items are added to the end of the list. callback: callable or None If you want to ignore the set event, pass None as the callback. The callback should have a signature of callback(index, value). The callback should return a boolean True if the set should be canceled, False or None otherwise.""" self._set_callback = callback if callable(callback) else _void def on_reverse(self, callback): """Register a callback for list reversal. callback: callable or None If you want to ignore the reverse event, pass None as the callback. The callback should have a signature of callback(). The callback should return a boolean True if the reverse should be canceled, False or None otherwise.""" self._reverse_callback = callback if callable(callback) else _void def on_sort(self, callback): """Register a callback for sortting of the list. callback: callable or None If you want to ignore the sort event, pass None as the callback. The callback signature should match that of Python list's `.sort` method or `callback(*pargs, **kwargs)` as a catch all. The callback should return a boolean True if the reverse should be canceled, False or None otherwise.""" self._sort_callback = callback if callable(callback) else _void def append(self, x): """Add an item to the end of the list.""" self[len(self):] = [x] def extend(self, L): """Extend the list by appending all the items in the given list.""" self[len(self):] = L def remove(self, x): """Remove the first item from the list whose value is x. It is an error if there is no such item.""" del self[self.index(x)] def pop(self, i=None): """Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list.""" if i is None: i = len(self) - 1 val = self[i] del self[i] return val def reverse(self): """Reverse the elements of the list, in place.""" if self._can_reverse(): list.reverse(self) def insert(self, index, value): """Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).""" if self._can_insert(index, value): list.insert(self, index, value) def sort(self, *pargs, **kwargs): """Sort the items of the list in place (the arguments can be used for sort customization, see Python's sorted() for their explanation).""" if self._can_sort(*pargs, **kwargs): list.sort(self, *pargs, **kwargs) def __delitem__(self, index): if self._can_del(index): list.__delitem__(self, index) def __setitem__(self, index, value): if self._can_set(index, value): list.__setitem__(self, index, value) def __setslice__(self, start, end, value): if self._can_set(slice(start, end), value): list.__setslice__(self, start, end, value) def _can_insert(self, index, value): """Check if the item can be inserted.""" return not bool(self._insert_callback(index, value)) def _can_del(self, index): """Check if the item can be deleted.""" return not bool(self._del_callback(index)) def _can_set(self, index, value): """Check if the item can be set.""" return not bool(self._set_callback(index, value)) def _can_reverse(self): """Check if the list can be reversed.""" return not bool(self._reverse_callback()) def _can_sort(self, *pargs, **kwargs): """Check if the list can be sorted.""" return not bool(self._sort_callback(*pargs, **kwargs)) PK\H\dօ/ipywidgets/widgets/widget_selectioncontainer.py"""SelectionContainer class. Represents a multipage container that can be used to group other widgets into pages. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .widget_box import Box, register from traitlets import Unicode, Dict, CInt class _SelectionContainer(Box): """Base class used to display multiple child widgets.""" _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) _titles = Dict(help="Titles of the pages").tag(sync=True) selected_index = CInt().tag(sync=True) # Public methods def set_title(self, index, title): """Sets the title of a container page. Parameters ---------- index : int Index of the container page title : unicode New title """ self._titles[index] = title self.send_state('_titles') def get_title(self, index): """Gets the title of a container pages. Parameters ---------- index : int Index of the container page """ if index in self._titles: return self._titles[index] else: return None @register('Jupyter.Accordion') class Accordion(_SelectionContainer): """Displays children each on a separate accordion page.""" _view_name = Unicode('AccordionView').tag(sync=True) _model_name = Unicode('AccordionModel').tag(sync=True) @register('Jupyter.Tab') class Tab(_SelectionContainer): """Displays children each on a separate accordion tab.""" _view_name = Unicode('TabView').tag(sync=True) _model_name = Unicode('TabModel').tag(sync=True) PK'Hb?&ipywidgets/widgets/widget_selection.py"""Selection classes. Represents an enumeration using a widget. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from collections import OrderedDict from .domwidget import DOMWidget from .widget import register from traitlets import (Unicode, Bool, Any, Dict, TraitError, CaselessStrEnum, Tuple, List, Union, observe, validate) from ipython_genutils.py3compat import unicode_type def _value_to_label(value, obj): options = obj._make_options(obj.options) return next((k for k, v in options if obj.equals(v, value)), '') def _label_to_value(k, obj): return obj._options_dict[k] class _Selection(DOMWidget): """Base class for Selection widgets ``options`` can be specified as a list or dict. If given as a list, it will be transformed to a dict of the form ``{unicode_type(value): value}``. When programmatically setting the value, a reverse lookup is performed among the options to check that the value is valid. The reverse lookup uses the equality operator by default, but another predicate may be provided via the ``equals`` keyword argument. For example, when dealing with numpy arrays, one may set equals=np.array_equal. """ value = Any(help="Selected value").tag(sync=True, to_json=_value_to_label, from_json=_label_to_value) options = Union([List(), Dict()], help="""List of (key, value) tuples or dict of values that the user can select. The keys of this list are the strings that will be displayed in the UI, representing the actual Python choices. The keys of this list are also available as _options_labels. """) _options_dict = Dict(read_only=True) _options_labels = Tuple(read_only=True).tag(sync=True) _options_values = Tuple(read_only=True) _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) disabled = Bool(help="Enable or disable user changes").tag(sync=True) description = Unicode(help="Description of the value this widget represents").tag(sync=True) def __init__(self, *args, **kwargs): self.equals = kwargs.pop('equals', lambda x, y: x == y) super(_Selection, self).__init__(*args, **kwargs) def _make_options(self, x): # Return a list of key-value pairs where the keys are strings # If x is a dict, convert it to list format. if isinstance(x, (OrderedDict, dict)): return [(unicode_type(k), v) for k, v in x.items()] # If x is an ordinary list, use the option values as names. for y in x: if not isinstance(y, (list, tuple)) or len(y) < 2: return [(unicode_type(i), i) for i in x] # Value is already in the correct format. return x @validate('options') def _validate_options(self, proposal): """Handles when the options tuple has been changed. Setting options implies setting option labels from the keys of the dict. """ new = proposal['value'] options = self._make_options(new) self.set_trait('_options_dict', { i[0]: i[1] for i in options }) self.set_trait('_options_labels', [ i[0] for i in options ]) self.set_trait('_options_values', [ i[1] for i in options ]) self._value_in_options() return new def _value_in_options(self): # ensure that the chosen value is one of the choices if self._options_values: if self.value not in self._options_values: self.value = next(iter(self._options_values)) @validate('value') def _validate_value(self, proposal): value = proposal['value'] if _value_to_label(value, self): return value else: raise TraitError('Invalid selection') def _values_to_labels(values, obj): return tuple(_value_to_label(v, obj) for v in values) def _labels_to_values(k, obj): return tuple(_label_to_value(l, obj) for l in k) class _MultipleSelection(_Selection): """Base class for MultipleSelection widgets. As with ``_Selection``, ``options`` can be specified as a list or dict. If given as a list, it will be transformed to a dict of the form ``{unicode_type(value): value}``. Despite its name, the ``value`` attribute is a tuple, even if only a single option is selected. """ value = Tuple(help="Selected values").tag(sync=True, to_json=_values_to_labels, from_json=_labels_to_values) def _value_in_options(self): new_value = [] for v in self.value: if v in self._options_dict.values(): new_value.append(v) self.value = new_value @validate('value') def _validate_value(self, proposal): value = proposal['value'] if all(_value_to_label(v, self) for v in value): return value else: raise TraitError('Invalid selection') @register('Jupyter.ToggleButtons') class ToggleButtons(_Selection): """Group of toggle buttons that represent an enumeration. Only one toggle button can be toggled at any point in time. """ _view_name = Unicode('ToggleButtonsView').tag(sync=True) _model_name = Unicode('ToggleButtonsModel').tag(sync=True) tooltips = List(Unicode()).tag(sync=True) icons = List(Unicode()).tag(sync=True) button_style = CaselessStrEnum( values=['primary', 'success', 'info', 'warning', 'danger', ''], default_value='', allow_none=True, help="""Use a predefined styling for the buttons.""").tag(sync=True) @register('Jupyter.Dropdown') class Dropdown(_Selection): """Allows you to select a single item from a dropdown.""" _view_name = Unicode('DropdownView').tag(sync=True) _model_name = Unicode('DropdownModel').tag(sync=True) button_style = CaselessStrEnum( values=['primary', 'success', 'info', 'warning', 'danger', ''], default_value='', allow_none=True, help="""Use a predefined styling for the buttons.""").tag(sync=True) @register('Jupyter.RadioButtons') class RadioButtons(_Selection): """Group of radio buttons that represent an enumeration. Only one radio button can be toggled at any point in time. """ _view_name = Unicode('RadioButtonsView').tag(sync=True) _model_name = Unicode('RadioButtonsModel').tag(sync=True) @register('Jupyter.Select') class Select(_Selection): """Listbox that only allows one item to be selected at any given time.""" _view_name = Unicode('SelectView').tag(sync=True) _model_name = Unicode('SelectModel').tag(sync=True) @register('Jupyter.SelectionSlider') class SelectionSlider(_Selection): """Slider to select a single item from a list or dictionary.""" _view_name = Unicode('SelectionSliderView').tag(sync=True) _model_name = Unicode('SelectionSliderModel').tag(sync=True) orientation = CaselessStrEnum( values=['horizontal', 'vertical'], default_value='horizontal', allow_none=False, help="Vertical or horizontal.").tag(sync=True) readout = Bool(True, help="Display the current selected label next to the slider").tag(sync=True) continuous_update = Bool(True, help="Update the value of the widget as the user is holding the slider.").tag(sync=True) @register('Jupyter.SelectMultiple') class SelectMultiple(_MultipleSelection): """Listbox that allows many items to be selected at any given time. Despite their names, inherited from ``_Selection``, the currently chosen option values, ``value``, or their labels, ``selected_labels`` must both be updated with a list-like object. """ _view_name = Unicode('SelectMultipleView').tag(sync=True) _model_name = Unicode('SelectMultipleModel').tag(sync=True) PKnH XXipywidgets/widgets/domwidget.py"""Contains the DOMWidget class""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from traitlets import Unicode, Dict, Instance, Bool, List, \ CaselessStrEnum, Tuple, CUnicode, Int, Set, observe from .widget import Widget, widget_serialization from .trait_types import Color from .widget_layout import Layout from warnings import warn # TODO: Remove when traitlet deprection is removed post 5.0 class DOMWidget(Widget): """Widget that can be inserted into the DOM""" _model_name = Unicode('DOMWidgetModel').tag(sync=True) visible = Bool(True, allow_none=True, help="Whether the widget is visible. False collapses the empty space, while None preserves the empty space.").tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 _dom_classes = Tuple(help="DOM classes applied to widget.$el.").tag(sync=True) layout = Instance(Layout, allow_none=True).tag(sync=True, **widget_serialization) def _layout_default(self): return Layout() width = CUnicode().tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 height = CUnicode().tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 padding = CUnicode().tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 margin = CUnicode().tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 color = Color(None, allow_none=True).tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 background_color = Color(None, allow_none=True).tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 border_color = Color(None, allow_none=True).tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 border_width = CUnicode().tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 border_radius = CUnicode().tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 border_style = CaselessStrEnum(values=[ # http://www.w3schools.com/cssref/pr_border-style.asp # TODO: Deprecated in ipywidgets 5.0 'none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset', 'initial', 'inherit', ''], default_value='').tag(sync=True) font_style = CaselessStrEnum(values=[ # http://www.w3schools.com/cssref/pr_font_font-style.asp # TODO: Deprecated in ipywidgets 5.0 'normal', 'italic', 'oblique', 'initial', 'inherit', ''], default_value='').tag(sync=True) font_weight = CaselessStrEnum(values=[ # http://www.w3schools.com/cssref/pr_font_weight.asp # TODO: Deprecated in ipywidgets 5.0 'normal', 'bold', 'bolder', 'lighter', 'initial', 'inherit', ''] + list(map(str, range(100,1000,100))), default_value='').tag(sync=True) font_size = CUnicode().tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 font_family = Unicode().tag(sync=True) # TODO: Deprecated in ipywidgets 5.0 def __init__(self, *pargs, **kwargs): super(DOMWidget, self).__init__(*pargs, **kwargs) # Deprecation added in 5.0. TODO: Remove me and corresponging traits. self._deprecate_traits(['width', 'height', 'padding', 'margin', 'color', 'background_color', 'border_color', 'border_width', 'border_radius', 'border_style', 'font_style', 'font_weight', 'font_size', 'font_family', 'visible']) @observe('border_width', 'border_style', 'border_color') def _update_border(self, change): name, new = change['name'], change['new'] if new is not None and new != '': if name != 'border_width' and not self.border_width: self.border_width = 1 if name != 'border_style' and self.border_style == '': self.border_style = 'solid' def add_class(self, className): """ Adds a class to the top level element of the widget. Doesn't add the class if it already exists. """ if className not in self._dom_classes: self._dom_classes = list(self._dom_classes) + [className] return self def remove_class(self, className): """ Removes a class from the top level element of the widget. Doesn't remove the class if it doesn't exist. """ if className in self._dom_classes: self._dom_classes = [c for c in self._dom_classes if c != className] return self def _deprecate_traits(self, traits): # TODO: Deprecation added in 5.0. Remove me and corresponging traits. def traitWarn(change): warn("%s deprecated" % change['name'], DeprecationWarning) self.observe(traitWarn, names=traits) PKH'ipywidgets/widgets/widget_controller.py"""Controller class. Represents a Gamepad or Joystick controller. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .widget import Widget, register, widget_serialization from .domwidget import DOMWidget from traitlets import Bool, Int, Float, Unicode, List, Instance @register('Jupyter.ControllerButton') class Button(Widget): """Represents a gamepad or joystick button.""" value = Float(min=0.0, max=1.0, read_only=True).tag(sync=True) pressed = Bool(read_only=True).tag(sync=True) _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_name = Unicode('ControllerButtonView').tag(sync=True) _model_name = Unicode('ControllerButtonModel').tag(sync=True) @register('Jupyter.ControllerAxis') class Axis(Widget): """Represents a gamepad or joystick axis.""" value = Float(min=-1.0, max=1.0, read_only=True).tag(sync=True) _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_name = Unicode('ControllerAxisView').tag(sync=True) _model_name = Unicode('ControllerAxisModel').tag(sync=True) @register('Jupyter.Controller') class Controller(DOMWidget): """Represents a game controller.""" index = Int().tag(sync=True) # General information about the gamepad, button and axes mapping, name. # These values are all read-only and set by the JavaScript side. name = Unicode(read_only=True).tag(sync=True) mapping = Unicode(read_only=True).tag(sync=True) connected = Bool(read_only=True).tag(sync=True) timestamp = Float(read_only=True).tag(sync=True) # Buttons and axes - read-only buttons = List(trait=Instance(Button), read_only=True).tag(sync=True, **widget_serialization) axes = List(trait=Instance(Axis), read_only=True).tag(sync=True, **widget_serialization) _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_name = Unicode('ControllerView').tag(sync=True) _model_name = Unicode('ControllerModel').tag(sync=True) PKH]$$"ipywidgets/widgets/widget_float.py"""Float class. Represents an unbounded float using a widget. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .domwidget import DOMWidget from .widget import register from .trait_types import Color from traitlets import (Unicode, CFloat, Bool, CaselessStrEnum, Tuple, TraitError, validate) class _Float(DOMWidget): value = CFloat(0.0, help="Float value").tag(sync=True) disabled = Bool(False, help="Enable or disable user changes").tag(sync=True) description = Unicode(help="Description of the value this widget represents").tag(sync=True) _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) def __init__(self, value=None, **kwargs): if value is not None: kwargs['value'] = value super(_Float, self).__init__(**kwargs) class _BoundedFloat(_Float): max = CFloat(100.0, help="Max value").tag(sync=True) min = CFloat(0.0, help="Min value").tag(sync=True) step = CFloat(0.1, help="Minimum step to increment the value (ignored by some views)").tag(sync=True) @validate('value') def _validate_value(self, proposal): """Cap and floor value""" value = proposal['value'] if self.min > value or self.max < value: value = min(max(value, self.min), self.max) return value @validate('min') def _validate_min(self, proposal): """Enforce min <= value <= max""" min = proposal['value'] if min > self.max: raise TraitError('Setting min > max') if min > self.value: self.value = min return min @validate('max') def _validate_max(self, proposal): """Enforce min <= value <= max""" max = proposal['value'] if max < self.min: raise TraitError('setting max < min') if max < self.value: self.value = max return max @register('Jupyter.FloatText') class FloatText(_Float): """ Displays a float value within a textbox. For a textbox in which the value must be within a specific range, use BoundedFloatText. Parameters ---------- value : float value displayed description : str description displayed next to the text box color : str Unicode color code (eg. '#C13535'), optional color of the value displayed """ _view_name = Unicode('FloatTextView').tag(sync=True) _model_name = Unicode('IntTextModel').tag(sync=True) @register('Jupyter.BoundedFloatText') class BoundedFloatText(_BoundedFloat): """ Displays a float value within a textbox. Value must be within the range specified. For a textbox in which the value doesn't need to be within a specific range, use FloatText. Parameters ---------- value : float value displayed min : float minimal value of the range of possible values displayed max : float maximal value of the range of possible values displayed description : str description displayed next to the textbox color : str Unicode color code (eg. '#C13535'), optional color of the value displayed """ _view_name = Unicode('FloatTextView').tag(sync=True) _model_name = Unicode('IntTextModel').tag(sync=True) @register('Jupyter.FloatSlider') class FloatSlider(_BoundedFloat): """ Slider/trackbar of floating values with the specified range. Parameters ---------- value : float position of the slider min : float minimal position of the slider max : float maximal position of the slider step : float step of the trackbar description : str name of the slider orientation : {'vertical', 'horizontal}, optional default is horizontal readout : {True, False}, optional default is True, display the current value of the slider next to it slider_color : str Unicode color code (eg. '#C13535'), optional color of the slider color : str Unicode color code (eg. '#C13535'), optional color of the value displayed (if readout == True) """ _view_name = Unicode('FloatSliderView').tag(sync=True) _model_name = Unicode('IntSliderModel').tag(sync=True) orientation = CaselessStrEnum(values=['horizontal', 'vertical'], default_value='horizontal', help="Vertical or horizontal.").tag(sync=True) _range = Bool(False, help="Display a range selector").tag(sync=True) readout = Bool(True, help="Display the current value of the slider next to it.").tag(sync=True) slider_color = Color(None, allow_none=True).tag(sync=True) continuous_update = Bool(True, help="Update the value of the widget as the user is holding the slider.").tag(sync=True) @register('Jupyter.FloatProgress') class FloatProgress(_BoundedFloat): """ Displays a progress bar. Parameters ----------- value : float position within the range of the progress bar min : float minimal position of the slider max : float maximal position of the slider step : float step of the progress bar description : str name of the progress bar bar_style: {'success', 'info', 'warning', 'danger', ''}, optional color of the progress bar, default is '' (blue) colors are: 'success'-green, 'info'-light blue, 'warning'-orange, 'danger'-red """ _view_name = Unicode('ProgressView').tag(sync=True) _model_name = Unicode('ProgressModel').tag(sync=True) orientation = CaselessStrEnum(values=['horizontal', 'vertical'], default_value='horizontal', help="Vertical or horizontal.").tag(sync=True) bar_style = CaselessStrEnum( values=['success', 'info', 'warning', 'danger', ''], default_value='', allow_none=True, help="""Use a predefined styling for the progess bar.""").tag(sync=True) class _FloatRange(_Float): value = Tuple(CFloat(), CFloat(), default_value=(0.0, 1.0), help="Tuple of (lower, upper) bounds").tag(sync=True) @property def lower(self): return self.value[0] @lower.setter def lower(self, lower): self.value = (lower, self.value[1]) @property def upper(self): return self.value[1] @upper.setter def upper(self, upper): self.value = (self.value[0], upper) @validate('value') def _validate_value(self, proposal): lower, upper = proposal['value'] if upper < lower: raise TraitError('setting lower > upper') return lower, upper class _BoundedFloatRange(_FloatRange): step = CFloat(1.0, help="Minimum step that the value can take (ignored by some views)").tag(sync=True) max = CFloat(100.0, help="Max value").tag(sync=True) min = CFloat(0.0, help="Min value").tag(sync=True) def __init__(self, *args, **kwargs): min, max = kwargs.get('min', 0.0), kwargs.get('max', 100.0) if not kwargs.get('value', None): kwargs['value'] = (0.75 * min + 0.25 * max, 0.25 * min + 0.75 * max) super(_BoundedFloatRange, self).__init__(*args, **kwargs) @validate('min', 'max') def _validate_bounds(self, proposal): trait = proposal['trait'] new = proposal['value'] if trait.name == 'min' and new > self.max: raise TraitError('setting min > max') if trait.name == 'max' and new < self.min: raise TraitError('setting max < min') if trait.name == 'min': self.value = (max(new, self.value[0]), max(new, self.value[1])) if trait.name == 'max': self.value = (min(new, self.value[0]), min(new, self.value[1])) return new @validate('value') def _validate_value(self, proposal): lower, upper = super(_BoundedFloatRange, self)._validate_value(proposal) lower, upper = min(lower, self.max), min(upper, self.max) lower, upper = max(lower, self.min), max(upper, self.min) return lower, upper @register('Jupyter.FloatRangeSlider') class FloatRangeSlider(_BoundedFloatRange): """ Slider/trackbar that represents a pair of floats bounded by minimum and maximum value. Parameters ---------- value : float tuple range of the slider displayed min : float minimal position of the slider max : float maximal position of the slider step : float step of the trackbar description : str name of the slider orientation : {'vertical', 'horizontal}, optional default is horizontal readout : {True, False}, optional default is True, display the current value of the slider next to it slider_color : str Unicode color code (eg. '#C13535'), optional color of the slider color : str Unicode color code (eg. '#C13535'), optional color of the value displayed (if readout == True) """ _view_name = Unicode('FloatSliderView').tag(sync=True) _model_name = Unicode('IntSliderModel').tag(sync=True) orientation = CaselessStrEnum(values=['horizontal', 'vertical'], default_value='horizontal', help="Vertical or horizontal.").tag(sync=True) _range = Bool(True, help="Display a range selector").tag(sync=True) readout = Bool(True, help="Display the current value of the slider next to it.").tag(sync=True) slider_color = Color(None, allow_none=True).tag(sync=True) continuous_update = Bool(True, help="Update the value of the widget as the user is sliding the slider.").tag(sync=True) PKHc''ipywidgets/widgets/__init__.pyfrom .widget import Widget, CallbackDispatcher, register, widget_serialization, handle_version_comm_opened from .domwidget import DOMWidget from .trait_types import Color, EventfulDict, EventfulList from .widget_bool import Checkbox, ToggleButton, Valid from .widget_button import Button from .widget_box import Box, FlexBox, Proxy, PlaceProxy, HBox, VBox from .widget_float import FloatText, BoundedFloatText, FloatSlider, FloatProgress, FloatRangeSlider from .widget_image import Image from .widget_int import IntText, BoundedIntText, IntSlider, IntProgress, IntRangeSlider from .widget_color import ColorPicker from .widget_output import Output from .widget_selection import RadioButtons, ToggleButtons, Dropdown, Select, SelectionSlider, SelectMultiple from .widget_selectioncontainer import Tab, Accordion from .widget_string import HTML, Label, Latex, Text, Textarea from .widget_controller import Controller from .interaction import interact, interactive, fixed, interact_manual from .widget_link import jslink, jsdlink from .widget_layout import Layout PKH}MFFipywidgets/widgets/widget.py"""Base Widget class. Allows user to create widgets in the back-end that render in the IPython notebook front-end. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from contextlib import contextmanager import collections import sys from IPython.core.getipython import get_ipython from ipykernel.comm import Comm from traitlets.config import LoggingConfigurable from traitlets.utils.importstring import import_item from traitlets import Unicode, Dict, Instance, List, Int, Set, Bytes from ipython_genutils.py3compat import string_types, PY3 from .._version import __frontend_version__ def _widget_to_json(x, obj): if isinstance(x, dict): return {k: _widget_to_json(v, obj) for k, v in x.items()} elif isinstance(x, (list, tuple)): return [_widget_to_json(v, obj) for v in x] elif isinstance(x, Widget): return "IPY_MODEL_" + x.model_id else: return x def _json_to_widget(x, obj): if isinstance(x, dict): return {k: _json_to_widget(v, obj) for k, v in x.items()} elif isinstance(x, (list, tuple)): return [_json_to_widget(v, obj) for v in x] elif isinstance(x, string_types) and x.startswith('IPY_MODEL_') and x[10:] in Widget.widgets: return Widget.widgets[x[10:]] else: return x widget_serialization = { 'from_json': _json_to_widget, 'to_json': _widget_to_json } if PY3: _binary_types = (memoryview, bytes) else: _binary_types = (memoryview, buffer) class CallbackDispatcher(LoggingConfigurable): """A structure for registering and running callbacks""" callbacks = List() def __call__(self, *args, **kwargs): """Call all of the registered callbacks.""" value = None for callback in self.callbacks: try: local_value = callback(*args, **kwargs) except Exception as e: ip = get_ipython() if ip is None: self.log.warn("Exception in callback %s: %s", callback, e, exc_info=True) else: ip.showtraceback() else: value = local_value if local_value is not None else value return value def register_callback(self, callback, remove=False): """(Un)Register a callback Parameters ---------- callback: method handle Method to be registered or unregistered. remove=False: bool Whether to unregister the callback.""" # (Un)Register the callback. if remove and callback in self.callbacks: self.callbacks.remove(callback) elif not remove and callback not in self.callbacks: self.callbacks.append(callback) def _show_traceback(method): """decorator for showing tracebacks in IPython""" def m(self, *args, **kwargs): try: return(method(self, *args, **kwargs)) except Exception as e: ip = get_ipython() if ip is None: self.log.warn("Exception in widget method %s: %s", method, e, exc_info=True) else: ip.showtraceback() return m def register(key=None): """Returns a decorator registering a widget class in the widget registry. If no key is provided, the class name is used as a key. A key is provided for each core Jupyter widget so that the frontend can use this key regardless of the language of the kernel. """ def wrap(widget): l = key if key is not None else widget.__module__ + widget.__name__ Widget.widget_types[l] = widget return widget return wrap class Widget(LoggingConfigurable): #------------------------------------------------------------------------- # Class attributes #------------------------------------------------------------------------- _widget_construction_callback = None widgets = {} widget_types = {} @staticmethod def on_widget_constructed(callback): """Registers a callback to be called when a widget is constructed. The callback must have the following signature: callback(widget)""" Widget._widget_construction_callback = callback @staticmethod def _call_widget_constructed(widget): """Static method, called when a widget is constructed.""" if Widget._widget_construction_callback is not None and callable(Widget._widget_construction_callback): Widget._widget_construction_callback(widget) @staticmethod def handle_comm_opened(comm, msg): """Static method, called when a widget is constructed.""" class_name = str(msg['metadata']['widget_class']) if class_name in Widget.widget_types: widget_class = Widget.widget_types[class_name] else: widget_class = import_item(class_name) widget = widget_class(comm=comm) #------------------------------------------------------------------------- # Traits #------------------------------------------------------------------------- _model_module = Unicode('jupyter-js-widgets', help="""A requirejs module name in which to find _model_name. If empty, look in the global registry.""").tag(sync=True) _model_name = Unicode('WidgetModel', help="""Name of the backbone model registered in the front-end to create and sync this widget with.""").tag(sync=True) _view_module = Unicode(None, allow_none=True, help="""A requirejs module in which to find _view_name. If empty, look in the global registry.""").tag(sync=True) _view_name = Unicode(None, allow_none=True, help="""Default view registered in the front-end to use to represent the widget.""").tag(sync=True) comm = Instance('ipykernel.comm.Comm', allow_none=True) msg_throttle = Int(3, help="""Maximum number of msgs the front-end can send before receiving an idle msg from the back-end.""").tag(sync=True) keys = List() def _keys_default(self): return [name for name in self.traits(sync=True)] _property_lock = Dict() _holding_sync = False _states_to_send = Set() _display_callbacks = Instance(CallbackDispatcher, ()) _msg_callbacks = Instance(CallbackDispatcher, ()) #------------------------------------------------------------------------- # (Con/de)structor #------------------------------------------------------------------------- def __init__(self, **kwargs): """Public constructor""" self._model_id = kwargs.pop('model_id', None) super(Widget, self).__init__(**kwargs) Widget._call_widget_constructed(self) self.open() def __del__(self): """Object disposal""" self.close() #------------------------------------------------------------------------- # Properties #------------------------------------------------------------------------- def open(self): """Open a comm to the frontend if one isn't already open.""" if self.comm is None: state, buffer_keys, buffers = self._split_state_buffers(self.get_state()) args = dict(target_name='jupyter.widget', data=state) if self._model_id is not None: args['comm_id'] = self._model_id self.comm = Comm(**args) if buffers: # FIXME: workaround ipykernel missing binary message support in open-on-init # send state with binary elements as second message self.send_state() def _comm_changed(self, name, new): """Called when the comm is changed.""" if new is None: return self._model_id = self.model_id self.comm.on_msg(self._handle_msg) Widget.widgets[self.model_id] = self @property def model_id(self): """Gets the model id of this widget. If a Comm doesn't exist yet, a Comm will be created automagically.""" return self.comm.comm_id #------------------------------------------------------------------------- # Methods #------------------------------------------------------------------------- def close(self): """Close method. Closes the underlying comm. When the comm is closed, all of the widget views are automatically removed from the front-end.""" if self.comm is not None: Widget.widgets.pop(self.model_id, None) self.comm.close() self.comm = None self._ipython_display_ = None def _split_state_buffers(self, state): """Return (state_without_buffers, buffer_keys, buffers) for binary message parts""" buffer_keys, buffers = [], [] for k, v in list(state.items()): if isinstance(v, _binary_types): state.pop(k) buffers.append(v) buffer_keys.append(k) return state, buffer_keys, buffers def send_state(self, key=None): """Sends the widget state, or a piece of it, to the front-end. Parameters ---------- key : unicode, or iterable (optional) A single property's name or iterable of property names to sync with the front-end. """ state = self.get_state(key=key) state, buffer_keys, buffers = self._split_state_buffers(state) msg = {'method': 'update', 'state': state, 'buffers': buffer_keys} self._send(msg, buffers=buffers) def get_state(self, key=None): """Gets the widget state, or a piece of it. Parameters ---------- key : unicode or iterable (optional) A single property's name or iterable of property names to get. Returns ------- state : dict of states metadata : dict metadata for each field: {key: metadata} """ if key is None: keys = self.keys elif isinstance(key, string_types): keys = [key] elif isinstance(key, collections.Iterable): keys = key else: raise ValueError("key must be a string, an iterable of keys, or None") state = {} traits = self.traits() if not PY3 else {} # no need to construct traits on PY3 for k in keys: to_json = self.trait_metadata(k, 'to_json', self._trait_to_json) value = to_json(getattr(self, k), self) if not PY3 and isinstance(traits[k], Bytes) and isinstance(value, bytes): value = memoryview(value) state[k] = value return state def set_state(self, sync_data): """Called when a state is received from the front-end.""" # The order of these context managers is important. Properties must # be locked when the hold_trait_notification context manager is # released and notifications are fired. with self._lock_property(**sync_data), self.hold_trait_notifications(): for name in sync_data: if name in self.keys: from_json = self.trait_metadata(name, 'from_json', self._trait_from_json) self.set_trait(name, from_json(sync_data[name], self)) def send(self, content, buffers=None): """Sends a custom msg to the widget model in the front-end. Parameters ---------- content : dict Content of the message to send. buffers : list of binary buffers Binary buffers to send with message """ self._send({"method": "custom", "content": content}, buffers=buffers) def on_msg(self, callback, remove=False): """(Un)Register a custom msg receive callback. Parameters ---------- callback: callable callback will be passed three arguments when a message arrives:: callback(widget, content, buffers) remove: bool True if the callback should be unregistered.""" self._msg_callbacks.register_callback(callback, remove=remove) def on_displayed(self, callback, remove=False): """(Un)Register a widget displayed callback. Parameters ---------- callback: method handler Must have a signature of:: callback(widget, **kwargs) kwargs from display are passed through without modification. remove: bool True if the callback should be unregistered.""" self._display_callbacks.register_callback(callback, remove=remove) def add_traits(self, **traits): """Dynamically add trait attributes to the Widget.""" super(Widget, self).add_traits(**traits) for name, trait in traits.items(): if trait.get_metadata('sync'): self.keys.append(name) self.send_state(name) def notify_change(self, change): """Called when a property has changed.""" # Send the state before the user registered callbacks for trait changes # have all fired. name = change['name'] if self.comm is not None and name in self.keys: # Make sure this isn't information that the front-end just sent us. if self._should_send_property(name, change['new']): # Send new state to front-end self.send_state(key=name) LoggingConfigurable.notify_change(self, change) #------------------------------------------------------------------------- # Support methods #------------------------------------------------------------------------- @contextmanager def _lock_property(self, **properties): """Lock a property-value pair. The value should be the JSON state of the property. NOTE: This, in addition to the single lock for all state changes, is flawed. In the future we may want to look into buffering state changes back to the front-end.""" self._property_lock = properties try: yield finally: self._property_lock = {} @contextmanager def hold_sync(self): """Hold syncing any state until the outermost context manager exits""" if self._holding_sync is True: yield else: try: self._holding_sync = True yield finally: self._holding_sync = False self.send_state(self._states_to_send) self._states_to_send.clear() def _should_send_property(self, key, value): """Check the property lock (property_lock)""" to_json = self.trait_metadata(key, 'to_json', self._trait_to_json) if (key in self._property_lock and to_json(value, self) == self._property_lock[key]): return False elif self._holding_sync: self._states_to_send.add(key) return False else: return True # Event handlers @_show_traceback def _handle_msg(self, msg): """Called when a msg is received from the front-end""" data = msg['content']['data'] method = data['method'] # Handle backbone sync methods CREATE, PATCH, and UPDATE all in one. if method == 'backbone': if 'sync_data' in data: # get binary buffers too sync_data = data['sync_data'] for i,k in enumerate(data.get('buffer_keys', [])): sync_data[k] = msg['buffers'][i] self.set_state(sync_data) # handles all methods # Handle a state request. elif method == 'request_state': self.send_state() # Handle a custom msg from the front-end. elif method == 'custom': if 'content' in data: self._handle_custom_msg(data['content'], msg['buffers']) # Catch remainder. else: self.log.error('Unknown front-end to back-end widget msg with method "%s"' % method) def _handle_custom_msg(self, content, buffers): """Called when a custom msg is received.""" self._msg_callbacks(self, content, buffers) def _handle_displayed(self, **kwargs): """Called when a view has been displayed for this widget instance""" self._display_callbacks(self, **kwargs) @staticmethod def _trait_to_json(x, self): """Convert a trait value to json.""" return x @staticmethod def _trait_from_json(x, self): """Convert json values to objects.""" return x def _ipython_display_(self, **kwargs): """Called when `IPython.display.display` is called on the widget.""" def loud_error(message): self.log.warn(message) sys.stderr.write('%s\n' % message) # Show view. if self._view_name is not None: validated = Widget._version_validated # Before the user tries to display a widget. Validate that the # widget front-end is what is expected. if validated is None: loud_error('Widget Javascript not detected. It may not be installed properly.') elif not validated: loud_error('The installed widget Javascript is the wrong version.') self._send({"method": "display"}) self._handle_displayed(**kwargs) def _send(self, msg, buffers=None): """Sends a message to the model in the front-end.""" self.comm.send(data=msg, buffers=buffers) Widget._version_validated = None def handle_version_comm_opened(comm, msg): """Called when version comm is opened, because the front-end wants to validate the version.""" def handle_version_message(msg): Widget._version_validated = msg['content']['data']['validated'] comm.on_msg(handle_version_message) comm.send({'version': __frontend_version__}) PKHL%#ipywidgets/widgets/widget_layout.py"""Contains the Layout class""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .widget import Widget, register from traitlets import Unicode, CUnicode class Layout(Widget): """Layout specification Defines a layout that can be expressed using CSS. Supports a subset of https://developer.mozilla.org/en-US/docs/Web/CSS/Reference When a property is also accessible via a shorthand property, we only expose the shorthand. For example: - ``flex-grow``, ``flex-shrink`` and ``flex-basis`` are bound to ``flex``. - ``flex-wrap`` and ``flex-direction`` are bound to ``flex-flow``. - ``margin-[top/bottom/left/right]`` values are bound to ``margin``, etc. """ _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_name = Unicode('LayoutView').tag(sync=True) _model_name = Unicode('LayoutModel').tag(sync=True) # Keys align_content = CUnicode().tag(sync=True) align_items = CUnicode().tag(sync=True) align_self = CUnicode().tag(sync=True) bottom = CUnicode().tag(sync=True) border = CUnicode().tag(sync=True) display = CUnicode().tag(sync=True) flex = CUnicode().tag(sync=True) flex_flow = CUnicode().tag(sync=True) height = CUnicode().tag(sync=True) justify_content = CUnicode().tag(sync=True) left = CUnicode().tag(sync=True) margin = CUnicode().tag(sync=True) overflow = CUnicode().tag(sync=True) padding = CUnicode().tag(sync=True) right = CUnicode().tag(sync=True) top = CUnicode().tag(sync=True) visibility = CUnicode().tag(sync=True) width = CUnicode().tag(sync=True) PKZHD9"88!ipywidgets/widgets/interaction.py"""Interact with functions using widgets.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function from __future__ import division try: # Python >= 3.3 from inspect import signature, Parameter except ImportError: from IPython.utils.signatures import signature, Parameter from inspect import getcallargs try: from inspect import getfullargspec as check_argspec except ImportError: from inspect import getargspec as check_argspec # py2 from IPython.core.getipython import get_ipython from . import (Widget, Text, FloatSlider, IntSlider, Checkbox, Dropdown, Box, Button, DOMWidget) from IPython.display import display, clear_output from ipython_genutils.py3compat import string_types, unicode_type from traitlets import HasTraits, Any, Unicode, observe from numbers import Real, Integral from warnings import warn empty = Parameter.empty def _matches(o, pattern): """Match a pattern of types in a sequence.""" if not len(o) == len(pattern): return False comps = zip(o,pattern) return all(isinstance(obj,kind) for obj,kind in comps) def _get_min_max_value(min, max, value=None, step=None): """Return min, max, value given input values with possible None.""" if value is None: if not max > min: raise ValueError('max must be greater than min: (min={0}, max={1})'.format(min, max)) diff = max - min value = min + (diff / 2) # Ensure that value has the same type as diff if not isinstance(value, type(diff)): value = min + (diff // 2) elif min is None and max is None: if not isinstance(value, Real): raise TypeError('expected a real number, got: %r' % value) if not value: t = type(value) min, max = (t(0), t(1)) elif value > 0: min, max = (-value, 3*value) else: min, max = (3*value, -value) else: raise ValueError('unable to infer range, value from: ({0}, {1}, {2})'.format(min, max, value)) if step is not None: # ensure value is on a step r = (value - min) % step value = value - r return min, max, value def _widget_abbrev_single_value(o): """Make widgets from single values, which can be used as parameter defaults.""" if isinstance(o, string_types): return Text(value=unicode_type(o)) elif isinstance(o, dict): return Dropdown(options=o) elif isinstance(o, bool): return Checkbox(value=o) elif isinstance(o, Integral): min, max, value = _get_min_max_value(None, None, o) return IntSlider(value=o, min=min, max=max) elif isinstance(o, Real): min, max, value = _get_min_max_value(None, None, o) return FloatSlider(value=o, min=min, max=max) else: return None def _widget_abbrev(o): """Make widgets from abbreviations: single values, lists or tuples.""" if isinstance(o, list): # -------------------------------------------------------------------- # Handle deprecated behavior of using lists of length 2 or 3 in place # of tuples to specify slider widget attributes. This will be removed # in ipywidgets 6.0. if len(o) in [2, 3] and all(isinstance(x, Real) for x in o): warn("For Sliders, use a tuple: %s" % (tuple(o),), DeprecationWarning) return _widget_abbrev(tuple(o)) # -------------------------------------------------------------------- return Dropdown(options=[unicode_type(k) for k in o]) elif isinstance(o, tuple): # -------------------------------------------------------------------- # Handle deprecated behavior of using tuples for selection widget. This # will be removed in ipywidgets 6.0. if any(not isinstance(x, Real) for x in o): warn("For Selection widgets, use a list %s" %(list(o),), DeprecationWarning) return Dropdown(options=[unicode_type(k) for k in o]) # -------------------------------------------------------------------- if _matches(o, (Real, Real)): min, max, value = _get_min_max_value(o[0], o[1]) if all(isinstance(_, Integral) for _ in o): cls = IntSlider else: cls = FloatSlider return cls(value=value, min=min, max=max) elif _matches(o, (Real, Real, Real)): step = o[2] if step <= 0: raise ValueError("step must be >= 0, not %r" % step) min, max, value = _get_min_max_value(o[0], o[1], step=step) if all(isinstance(_, Integral) for _ in o): cls = IntSlider else: cls = FloatSlider return cls(value=value, min=min, max=max, step=step) else: return _widget_abbrev_single_value(o) def _widget_from_abbrev(abbrev, default=empty): """Build a Widget instance given an abbreviation or Widget.""" if isinstance(abbrev, Widget) or isinstance(abbrev, fixed): return abbrev widget = _widget_abbrev(abbrev) if default is not empty and isinstance(abbrev, (list, tuple, dict)): # if it's not a single-value abbreviation, # set the initial value from the default try: widget.value = default except Exception: # ignore failure to set default pass if widget is None: raise ValueError("%r cannot be transformed to a Widget" % (abbrev,)) return widget def _yield_abbreviations_for_parameter(param, kwargs): """Get an abbreviation for a function parameter.""" name = param.name kind = param.kind ann = param.annotation default = param.default not_found = (name, empty, empty) if kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY): if name in kwargs: value = kwargs.pop(name) elif ann is not empty: value = ann elif default is not empty: value = default else: yield not_found yield (name, value, default) elif kind == Parameter.VAR_KEYWORD: # In this case name=kwargs and we yield the items in kwargs with their keys. for k, v in kwargs.copy().items(): kwargs.pop(k) yield k, v, empty def _find_abbreviations(f, kwargs): """Find the abbreviations for a function and kwargs passed to interact.""" new_kwargs = [] try: sig = signature(f) except (ValueError, TypeError): # can't inspect, no info from function; only use kwargs return [ (key, value, value) for key, value in kwargs.items() ] for param in sig.parameters.values(): for name, value, default in _yield_abbreviations_for_parameter(param, kwargs): if value is empty: raise ValueError('cannot find widget or abbreviation for argument: {!r}'.format(name)) new_kwargs.append((name, value, default)) return new_kwargs def _widgets_from_abbreviations(seq): """Given a sequence of (name, abbrev) tuples, return a sequence of Widgets.""" result = [] for name, abbrev, default in seq: widget = _widget_from_abbrev(abbrev, default) if not widget.description: widget.description = name widget._kwarg = name result.append(widget) return result def interactive(__interact_f, **kwargs): """ Builds a group of interactive widgets tied to a function and places the group into a Box container. Returns ------- container : a Box instance containing multiple widgets Parameters ---------- __interact_f : function The function to which the interactive widgets are tied. The `**kwargs` should match the function signature. **kwargs : various, optional An interactive widget is created for each keyword argument that is a valid widget abbreviation. """ f = __interact_f co = kwargs.pop('clear_output', True) manual = kwargs.pop('__manual', False) kwargs_widgets = [] container = Box(_dom_classes=['widget-interact']) container.result = None container.args = [] container.kwargs = dict() kwargs = kwargs.copy() new_kwargs = _find_abbreviations(f, kwargs) # Before we proceed, let's make sure that the user has passed a set of args+kwargs # that will lead to a valid call of the function. This protects against unspecified # and doubly-specified arguments. try: check_argspec(f) except TypeError: # if we can't inspect, we can't validate pass else: getcallargs(f, **{n:v for n,v,_ in new_kwargs}) # Now build the widgets from the abbreviations. kwargs_widgets.extend(_widgets_from_abbreviations(new_kwargs)) # This has to be done as an assignment, not using container.children.append, # so that traitlets notices the update. We skip any objects (such as fixed) that # are not DOMWidgets. c = [w for w in kwargs_widgets if isinstance(w, DOMWidget)] # If we are only to run the function on demand, add a button to request this. if manual: manual_button = Button(description="Run %s" % f.__name__) c.append(manual_button) container.children = c # Build the callback def call_f(*args): container.kwargs = {} for widget in kwargs_widgets: value = widget.value container.kwargs[widget._kwarg] = value if co: clear_output(wait=True) if manual: manual_button.disabled = True try: container.result = f(**container.kwargs) if container.result is not None: display(container.result) except Exception as e: ip = get_ipython() if ip is None: container.log.warn("Exception in interact callback: %s", e, exc_info=True) else: ip.showtraceback() finally: if manual: manual_button.disabled = False # Wire up the widgets # If we are doing manual running, the callback is only triggered by the button # Otherwise, it is triggered for every trait change received # On-demand running also suppresses running the function with the initial parameters if manual: manual_button.on_click(call_f) # Also register input handlers on text areas, so the user can hit return to # invoke execution. for w in kwargs_widgets: if isinstance(w, Text): w.on_submit(call_f) else: for widget in kwargs_widgets: widget.observe(call_f, names='value') container.on_displayed(lambda _: call_f(dict(name=None, old=None, new=None))) return container def interact(__interact_f=None, **kwargs): """ Displays interactive widgets which are tied to a function. Expects the first argument to be a function. Parameters to this function are widget abbreviations passed in as keyword arguments (`**kwargs`). Can be used as a decorator (see examples). Returns ------- f : __interact_f with interactive widget attached to it. Parameters ---------- __interact_f : function The function to which the interactive widgets are tied. The `**kwargs` should match the function signature. Passed to :func:`interactive()` **kwargs : various, optional An interactive widget is created for each keyword argument that is a valid widget abbreviation. Passed to :func:`interactive()` Examples -------- Render an interactive text field that shows the greeting with the passed in text:: # 1. Using interact as a function def greeting(text="World"): print "Hello {}".format(text) interact(greeting, text="IPython Widgets") # 2. Using interact as a decorator @interact def greeting(text="World"): print "Hello {}".format(text) # 3. Using interact as a decorator with named parameters @interact(text="IPython Widgets") def greeting(text="World"): print "Hello {}".format(text) Render an interactive slider widget and prints square of number:: # 1. Using interact as a function def square(num=1): print "{} squared is {}".format(num, num*num) interact(square, num=5) # 2. Using interact as a decorator @interact def square(num=2): print "{} squared is {}".format(num, num*num) # 3. Using interact as a decorator with named parameters @interact(num=5) def square(num=2): print "{} squared is {}".format(num, num*num) """ # positional arg support in: https://gist.github.com/8851331 if __interact_f is not None: # This branch handles the cases 1 and 2 # 1. interact(f, **kwargs) # 2. @interact # def f(*args, **kwargs): # ... f = __interact_f w = interactive(f, **kwargs) try: f.widget = w except AttributeError: # some things (instancemethods) can't have attributes attached, # so wrap in a lambda f = lambda *args, **kwargs: __interact_f(*args, **kwargs) f.widget = w if w is not None: display(w) return f else: # This branch handles the case 3 # @interact(a=30, b=40) # def f(*args, **kwargs): # ... def dec(f): return interact(f, **kwargs) return dec def interact_manual(__interact_f=None, **kwargs): """interact_manual(f, **kwargs) As `interact()`, generates widgets for each argument, but rather than running the function after each widget change, adds a "Run" button and waits for it to be clicked. Useful if the function is long-running and has several parameters to change. """ return interact(__interact_f, __manual=True, **kwargs) class fixed(HasTraits): """A pseudo-widget whose value is fixed and never synced to the client.""" value = Any(help="Any Python object") description = Unicode('', help="Any Python object") def __init__(self, value, **kwargs): super(fixed, self).__init__(value=value, **kwargs) PKZHxDD!ipywidgets/widgets/trait_types.py# encoding: utf-8 """ Trait types for html widgets. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import re import traitlets from . import eventful _color_names = ['aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'honeydew', 'hotpink', 'indianred ', 'indigo ', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'rebeccapurple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen'] _color_re = re.compile(r'#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$') class Color(traitlets.Unicode): """A string holding a valid HTML color such as 'blue', '#060482', '#A80'""" info_text = 'a valid HTML color' default_value = traitlets.Undefined def validate(self, obj, value): if value.lower() in _color_names or _color_re.match(value): return value self.error(obj, value) class EventfulDict(traitlets.Instance): """An instance of an EventfulDict.""" def __init__(self, default_value={}, **metadata): """Create a EventfulDict trait type from a dict. The default value is created by doing ``eventful.EvenfulDict(default_value)``, which creates a copy of the ``default_value``. """ if default_value is None: args = None elif isinstance(default_value, dict): args = (default_value,) elif isinstance(default_value, SequenceTypes): args = (default_value,) else: raise TypeError('default value of EventfulDict was %s' % default_value) super(EventfulDict, self).__init__(klass=eventful.EventfulDict, args=args, **metadata) class EventfulList(traitlets.Instance): """An instance of an EventfulList.""" def __init__(self, default_value=None, **metadata): """Create a EventfulList trait type from a dict. The default value is created by doing ``eventful.EvenfulList(default_value)``, which creates a copy of the ``default_value``. """ if default_value is None: args = ((),) else: args = (default_value,) super(EventfulList, self).__init__(klass=eventful.EventfulList, args=args, **metadata) PKHWZZ ipywidgets/widgets/widget_box.py"""Box class. Represents a container that can be used to group other widgets. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .domwidget import DOMWidget from .widget import Widget, register, widget_serialization from traitlets import Unicode, Tuple, Int, CaselessStrEnum, Instance from warnings import warn @register('Jupyter.Box') class Box(DOMWidget): """Displays multiple widgets in a group.""" _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) _model_name = Unicode('BoxModel').tag(sync=True) _view_name = Unicode('BoxView').tag(sync=True) # Child widgets in the container. # Using a tuple here to force reassignment to update the list. # When a proper notifying-list trait exists, that is what should be used here. children = Tuple().tag(sync=True, **widget_serialization) _overflow_values = ['visible', 'hidden', 'scroll', 'auto', 'initial', 'inherit', ''] overflow_x = CaselessStrEnum( values=_overflow_values, default_value='', help="""Specifies what happens to content that is too large for the rendered region.""").tag(sync=True) overflow_y = CaselessStrEnum( values=_overflow_values, default_value='', help="""Specifies what happens to content that is too large for the rendered region.""").tag(sync=True) box_style = CaselessStrEnum( values=['success', 'info', 'warning', 'danger', ''], default_value='', help="""Use a predefined styling for the box.""").tag(sync=True) def __init__(self, children = (), **kwargs): kwargs['children'] = children super(Box, self).__init__(**kwargs) self.on_displayed(Box._fire_children_displayed) def _fire_children_displayed(self): for child in self.children: child._handle_displayed() @register('Jupyter.Proxy') class Proxy(DOMWidget): """A DOMWidget that holds another DOMWidget or nothing.""" _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) _model_name = Unicode('ProxyModel').tag(sync=True) _view_name = Unicode('ProxyView').tag(sync=True) # Child widget of the Proxy child = Instance(DOMWidget, allow_none=True).tag(sync=True, **widget_serialization) def __init__(self, child, **kwargs): kwargs['child'] = child super(Proxy, self).__init__(**kwargs) self.on_displayed(Proxy._fire_child_displayed) def _fire_child_displayed(self): if self.child is not None: self.child._handle_displayed() @register('Jupyter.PlaceProxy') class PlaceProxy(Proxy): """Renders the child widget at the specified selector.""" _view_name = Unicode('PlaceProxyView').tag(sync=True) _model_name = Unicode('PlaceProxyModel').tag(sync=True) selector = Unicode().tag(sync=True) def VBox(*pargs, **kwargs): """Displays multiple widgets vertically using the flexible box model.""" box = Box(*pargs, **kwargs) box.layout.display = 'flex' box.layout.flex_flow = 'column' return box def HBox(*pargs, **kwargs): """Displays multiple widgets horizontally using the flexible box model.""" box = Box(*pargs, **kwargs) box.layout.display = 'flex' return box @register('Jupyter.FlexBox') class FlexBox(Box): # TODO: Deprecated in 5.0 (entire class) """Displays multiple widgets using the flexible box model.""" _view_name = Unicode('FlexBoxView').tag(sync=True) _model_name = Unicode('FlexBoxModel').tag(sync=True) orientation = CaselessStrEnum(values=['vertical', 'horizontal'], default_value='vertical').tag(sync=True) flex = Int(help="""Specify the flexible-ness of the model.""").tag(sync=True) def _flex_changed(self, name, old, new): new = min(max(0, new), 2) if self.flex != new: self.flex = new _locations = ['start', 'center', 'end', 'baseline', 'stretch'] pack = CaselessStrEnum(values=_locations, default_value='start').tag(sync=True) align = CaselessStrEnum(values=_locations, default_value='start').tag( sync=True) def __init__(self, *pargs, **kwargs): warn('FlexBox is deprecated in ipywidgets 5.0. Use Box and Box.layout instead.', DeprecationWarning) super(FlexBox, self).__init__(*pargs, **kwargs) PKH #ipywidgets/widgets/widget_string.py"""String class. Represents a unicode string using a widget. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .domwidget import DOMWidget from .widget import CallbackDispatcher, register from traitlets import Unicode, Bool from warnings import warn class _String(DOMWidget): """Base class used to create widgets that represent a string.""" _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) value = Unicode(help="String value").tag(sync=True) disabled = Bool(False, help="Enable or disable user changes").tag(sync=True) description = Unicode(help="Description of the value this widget represents").tag(sync=True) placeholder = Unicode("", help="Placeholder text to display when nothing has been typed").tag(sync=True) def __init__(self, value=None, **kwargs): if value is not None: kwargs['value'] = value super(_String, self).__init__(**kwargs) _model_name = Unicode('StringModel').tag(sync=True) @register('Jupyter.HTML') class HTML(_String): """Renders the string `value` as HTML.""" _view_name = Unicode('HTMLView').tag(sync=True) _model_name = Unicode('HTMLModel').tag(sync=True) @register('Jupyter.Label') class Label(_String): """Label widget. It also renders math inside the string `value` as Latex (requires $ $ or $$ $$ and similar latex tags). """ _view_name = Unicode('LabelView').tag(sync=True) _model_name = Unicode('LabelModel').tag(sync=True) class Latex(Label): def __init__(self, *args, **kwargs): warn('The Latex widget is deprecated. Use Label instead') super(Latex, self).__init__(*args, **kwargs) @register('Jupyter.Textarea') class Textarea(_String): """Multiline text area widget.""" _view_name = Unicode('TextareaView').tag(sync=True) _model_name = Unicode('TextareaModel').tag(sync=True) def scroll_to_bottom(self): self.send({"method": "scroll_to_bottom"}) @register('Jupyter.Text') class Text(_String): """Single line textbox widget.""" _view_name = Unicode('TextView').tag(sync=True) _model_name = Unicode('TextModel').tag(sync=True) def __init__(self, *args, **kwargs): super(Text, self).__init__(*args, **kwargs) self._submission_callbacks = CallbackDispatcher() self.on_msg(self._handle_string_msg) def _handle_string_msg(self, _, content, buffers): """Handle a msg from the front-end. Parameters ---------- content: dict Content of the msg. """ if content.get('event', '') == 'submit': self._submission_callbacks(self) def on_submit(self, callback, remove=False): """(Un)Register a callback to handle text submission. Triggered when the user clicks enter. Parameters ---------- callback: callable Will be called with exactly one argument: the Widget instance remove: bool (optional) Whether to unregister the callback """ self._submission_callbacks.register_callback(callback, remove=remove) PKH<'x !ipywidgets/widgets/widget_bool.py"""Bool class. Represents a boolean using a widget. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .domwidget import DOMWidget from .widget import register from traitlets import Unicode, Bool, CaselessStrEnum class _Bool(DOMWidget): """A base class for creating widgets that represent booleans.""" value = Bool(False, help="Bool value").tag(sync=True) description = Unicode('', help="Description of the boolean (label).").tag(sync=True) disabled = Bool(False, help="Enable or disable user changes.").tag(sync=True) def __init__(self, value=None, **kwargs): if value is not None: kwargs['value'] = value super(_Bool, self).__init__(**kwargs) _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) _model_name = Unicode('BoolModel').tag(sync=True) @register('Jupyter.Checkbox') class Checkbox(_Bool): """Displays a boolean `value` in the form of a checkbox. Parameters ---------- value : {True,False} value of the checkbox: True-checked, False-unchecked description : str description displayed next to the checkbox """ _view_name = Unicode('CheckboxView').tag(sync=True) _model_name = Unicode('CheckboxModel').tag(sync=True) @register('Jupyter.ToggleButton') class ToggleButton(_Bool): """Displays a boolean `value` in the form of a toggle button. Parameters ---------- value : {True,False} value of the toggle button: True-pressed, False-unpressed description : str description displayed next to the button tooltip: str tooltip caption of the toggle button icon: str font-awesome icon name """ _view_name = Unicode('ToggleButtonView').tag(sync=True) _model_name = Unicode('ToggleButtonModel').tag(sync=True) tooltip = Unicode(help="Tooltip caption of the toggle button.").tag(sync=True) icon = Unicode('', help= "Font-awesome icon.").tag(sync=True) button_style = CaselessStrEnum( values=['primary', 'success', 'info', 'warning', 'danger', ''], default_value='', help="""Use a predefined styling for the button.""").tag(sync=True) @register('Jupyter.Valid') class Valid(_Bool): """Displays a boolean `value` in the form of a green check (True / valid) or a red cross (False / invalid). Parameters ---------- value: {True,False} value of the Valid widget """ readout = Unicode('Invalid', help="Message displayed when the value is False").tag(sync=True) _view_name = Unicode('ValidView').tag(sync=True) _model_name = Unicode('ValidModel').tag(sync=True) PKHup< #ipywidgets/widgets/widget_button.py"""Button class. Represents a button in the frontend using a widget. Allows user to listen for click events on the button and trigger backend code when the clicks are fired. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .domwidget import DOMWidget from .widget import CallbackDispatcher, register from traitlets import Unicode, Bool, CaselessStrEnum @register('Jupyter.Button') class Button(DOMWidget): """Button widget. This widget has an `on_click` method that allows you to listen for the user clicking on the button. The click event itself is stateless. Parameters ---------- description: str description displayed next to the button tooltip: str tooltip caption of the toggle button icon: str font-awesome icon name """ _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_name = Unicode('ButtonView').tag(sync=True) _model_name = Unicode('ButtonModel').tag(sync=True) description = Unicode('', help="Button label.").tag(sync=True) tooltip = Unicode(help="Tooltip caption of the button.").tag(sync=True) disabled = Bool(False, help="Enable or disable user changes.").tag(sync=True) icon = Unicode('', help="Font-awesome icon.").tag(sync=True) button_style = CaselessStrEnum( values=['primary', 'success', 'info', 'warning', 'danger', ''], default_value='', help="""Use a predefined styling for the button.""").tag(sync=True) def __init__(self, **kwargs): super(Button, self).__init__(**kwargs) self._click_handlers = CallbackDispatcher() self.on_msg(self._handle_button_msg) def on_click(self, callback, remove=False): """Register a callback to execute when the button is clicked. The callback will be called with one argument, the clicked button widget instance. Parameters ---------- remove: bool (optional) Set to true to remove the callback from the list of callbacks. """ self._click_handlers.register_callback(callback, remove=remove) def _handle_button_msg(self, _, content, buffers): """Handle a msg from the front-end. Parameters ---------- content: dict Content of the msg. """ if content.get('event', '') == 'click': self._click_handlers(self) PKHo{ !ipywidgets/widgets/widget_link.py"""Link and DirectionalLink classes. Propagate changes between widgets on the javascript side. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .widget import Widget, register, widget_serialization from traitlets import Unicode, Tuple, List,Instance, TraitError class WidgetTraitTuple(Tuple): """Traitlet for validating a single (Widget, 'trait_name') pair""" def __init__(self, **kwargs): super(WidgetTraitTuple, self).__init__(Instance(Widget), Unicode, **kwargs) def validate_elements(self, obj, value): value = super(WidgetTraitTuple, self).validate_elements(obj, value) widget, trait_name = value trait = widget.traits().get(trait_name) trait_repr = "%s.%s" % (widget.__class__.__name__, trait_name) # Can't raise TraitError because the parent will swallow the message # and throw it away in a new, less informative TraitError if trait is None: raise TypeError("No such trait: %s" % trait_repr) elif not trait.get_metadata('sync'): raise TypeError("%s cannot be synced" % trait_repr) return value @register('jupyter.Link') class Link(Widget): """Link Widget source: a (Widget, 'trait_name') tuple for the source trait target: a (Widget, 'trait_name') tuple that should be updated """ _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) _model_name = Unicode('LinkModel').tag(sync=True) target = WidgetTraitTuple().tag(sync=True, **widget_serialization) source = WidgetTraitTuple().tag(sync=True, **widget_serialization) def __init__(self, source, target, **kwargs): kwargs['source'] = source kwargs['target'] = target super(Link, self).__init__(**kwargs) # for compatibility with traitlet links def unlink(self): self.close() def jslink(attr1, attr2): """Link two widget attributes on the frontend so they remain in sync. The link is created in the front-end and does not rely on a roundtrip to the backend. Parameters ---------- source : a (Widget, 'trait_name') tuple for the first trait target : a (Widget, 'trait_name') tuple for the second trait Examples -------- >>> c = link((widget1, 'value'), (widget2, 'value')) """ return Link(attr1, attr2) @register('jupyter.DirectionalLink') class DirectionalLink(Link): """A directional link source: a (Widget, 'trait_name') tuple for the source trait target: a (Widget, 'trait_name') tuple that should be updated when the source trait changes. """ _model_name = Unicode('DirectionalLinkModel').tag(sync=True) def jsdlink(source, target): """Link a source widget attribute with a target widget attribute. The link is created in the front-end and does not rely on a roundtrip to the backend. Parameters ---------- source : a (Widget, 'trait_name') tuple for the source trait target : a (Widget, 'trait_name') tuple for the target trait Examples -------- >>> c = dlink((src_widget, 'value'), (tgt_widget, 'value')) """ return DirectionalLink(source, target) PKHZL"L" ipywidgets/widgets/widget_int.py"""Int class. Represents an unbounded int using a widget. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .domwidget import DOMWidget from .widget import register from .trait_types import Color from traitlets import (Unicode, CInt, Bool, CaselessStrEnum, Tuple, TraitError, validate) _int_doc_t = """ Parameters ---------- value: integer The initial value. """ _bounded_int_doc_t = """ Parameters ---------- value: integer The initial value. min: integer The lower limit for the value. max: integer The upper limit for the value. step: integer The step between allowed values. """ def _int_doc(cls): """Add int docstring template to class init.""" def __init__(self, value=None, **kwargs): if value is not None: kwargs['value'] = value super(cls, self).__init__(**kwargs) __init__.__doc__ = _int_doc_t cls.__init__ = __init__ return cls def _bounded_int_doc(cls): """Add bounded int docstring template to class init.""" def __init__(self, value=None, min=None, max=None, step=None, **kwargs): if value is not None: kwargs['value'] = value if min is not None: kwargs['min'] = min if max is not None: kwargs['max'] = max if step is not None: kwargs['step'] = step super(cls, self).__init__(**kwargs) __init__.__doc__ = _bounded_int_doc_t cls.__init__ = __init__ return cls class _Int(DOMWidget): """Base class for widgets that represent an integer.""" value = CInt(0, help="Int value").tag(sync=True) disabled = Bool(False, help="Enable or disable user changes").tag(sync=True) description = Unicode(help="Description of the value this widget represents").tag(sync=True) _model_module = Unicode('jupyter-js-widgets').tag(sync=True) _view_module = Unicode('jupyter-js-widgets').tag(sync=True) def __init__(self, value=None, **kwargs): if value is not None: kwargs['value'] = value super(_Int, self).__init__(**kwargs) class _BoundedInt(_Int): """Base class for widgets that represent an integer bounded from above and below. """ step = CInt(1, help="Minimum step to increment the value (ignored by some views)").tag(sync=True) max = CInt(100, help="Max value").tag(sync=True) min = CInt(0, help="Min value").tag(sync=True) def __init__(self, value=None, min=None, max=None, step=None, **kwargs): if value is not None: kwargs['value'] = value if min is not None: kwargs['min'] = min if max is not None: kwargs['max'] = max if step is not None: kwargs['step'] = step super(_BoundedInt, self).__init__(**kwargs) @validate('value') def _validate_value(self, proposal): """Cap and floor value""" value = proposal['value'] if self.min > value or self.max < value: value = min(max(value, self.min), self.max) return value @validate('min') def _validate_min(self, proposal): """Enforce min <= value <= max""" min = proposal['value'] if min > self.max: raise TraitError('setting min > max') if min > self.value: self.value = min return min @validate('max') def _validate_max(self, proposal): """Enforce min <= value <= max""" max = proposal['value'] if max < self.min: raise TraitError('setting max < min') if max < self.value: self.value = max return max @register('Jupyter.IntText') @_int_doc class IntText(_Int): """Textbox widget that represents an integer.""" _view_name = Unicode('IntTextView').tag(sync=True) _model_name = Unicode('IntTextModel').tag(sync=True) @register('Jupyter.BoundedIntText') @_bounded_int_doc class BoundedIntText(_BoundedInt): """Textbox widget that represents an integer bounded from above and below. """ _view_name = Unicode('IntTextView').tag(sync=True) _model_name = Unicode('IntTextModel').tag(sync=True) @register('Jupyter.IntSlider') @_bounded_int_doc class IntSlider(_BoundedInt): """Slider widget that represents an integer bounded from above and below. """ _view_name = Unicode('IntSliderView').tag(sync=True) _model_name = Unicode('IntSliderModel').tag(sync=True) orientation = CaselessStrEnum(values=['horizontal', 'vertical'], default_value='horizontal', help="Vertical or horizontal.").tag(sync=True) _range = Bool(False, help="Display a range selector").tag(sync=True) readout = Bool(True, help="Display the current value of the slider next to it.").tag(sync=True) slider_color = Color(None, allow_none=True).tag(sync=True) continuous_update = Bool(True, help="Update the value of the widget as the user is holding the slider.").tag(sync=True) @register('Jupyter.IntProgress') @_bounded_int_doc class IntProgress(_BoundedInt): """Progress bar that represents an integer bounded from above and below. """ _view_name = Unicode('ProgressView').tag(sync=True) _model_name = Unicode('ProgressModel').tag(sync=True) orientation = CaselessStrEnum(values=['horizontal', 'vertical'], default_value='horizontal', help="Vertical or horizontal.").tag(sync=True) bar_style = CaselessStrEnum( values=['success', 'info', 'warning', 'danger', ''], default_value='', help="""Use a predefined styling for the progess bar.""").tag(sync=True) class _IntRange(_Int): value = Tuple(CInt(), CInt(), default_value=(0, 1), help="Tuple of (lower, upper) bounds").tag(sync=True) @property def lower(self): return self.value[0] @lower.setter def lower(self, lower): self.value = (lower, self.value[1]) @property def upper(self): return self.value[1] @upper.setter def upper(self, upper): self.value = (self.value[0], upper) @validate('value') def _validate_value(self, proposal): lower, upper = proposal['value'] if upper < lower: raise TraitError('setting lower > upper') return lower, upper class _BoundedIntRange(_IntRange): step = CInt(1, help="Minimum step that the value can take (ignored by some views)").tag(sync=True) max = CInt(100, help="Max value").tag(sync=True) min = CInt(0, help="Min value").tag(sync=True) def __init__(self, *args, **kwargs): min, max = kwargs.get('min', 0), kwargs.get('max', 100) if not kwargs.get('value', None): kwargs['value'] = (0.75 * min + 0.25 * max, 0.25 * min + 0.75 * max) super(_BoundedIntRange, self).__init__(*args, **kwargs) @validate('min', 'max') def _validate_bounds(self, proposal): trait = proposal['trait'] new = proposal['value'] if trait.name == 'min' and new > self.max: raise TraitError('setting min > max') if trait.name == 'max' and new < self.min: raise TraitError('setting max < min') if trait.name == 'min': self.value = (max(new, self.value[0]), max(new, self.value[1])) if trait.name == 'max': self.value = (min(new, self.value[0]), min(new, self.value[1])) return new @validate('value') def _validate_value(self, proposal): lower, upper = super(_BoundedIntRange, self)._validate_value(proposal) lower, upper = min(lower, self.max), min(upper, self.max) lower, upper = max(lower, self.min), max(upper, self.min) return lower, upper @register('Jupyter.IntRangeSlider') class IntRangeSlider(_BoundedIntRange): """Slider/trackbar that represents a pair of ints bounded by minimum and maximum value. Parameters ---------- value : int tuple The pair (`lower`, `upper`) of integers min : int The lowest allowed value for `lower` max : int The highest allowed value for `upper` """ _view_name = Unicode('IntSliderView').tag(sync=True) _model_name = Unicode('IntSliderModel').tag(sync=True) orientation = CaselessStrEnum(values=['horizontal', 'vertical'], default_value='horizontal', help="Vertical or horizontal.").tag(sync=True) _range = Bool(True, help="Display a range selector").tag(sync=True) readout = Bool(True, help="Display the current value of the slider next to it.").tag(sync=True) slider_color = Color(None, allow_none=True).tag(sync=True) continuous_update = Bool(True, help="Update the value of the widget as the user is sliding the slider.").tag(sync=True) PKZH{`""%ipywidgets/widgets/tests/test_link.py# Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import nose.tools as nt from .. import jslink, jsdlink, ToggleButton from .test_interaction import setup, teardown def test_jslink_args(): with nt.assert_raises(TypeError): jslink() w1 = ToggleButton() with nt.assert_raises(TypeError): jslink((w1, 'value')) w2 = ToggleButton() jslink((w1, 'value'), (w2, 'value')) with nt.assert_raises(TypeError): jslink((w1, 'value'), (w2, 'nosuchtrait')) with nt.assert_raises(TypeError): jslink((w1, 'value'), (w2, 'traits')) def test_jsdlink_args(): with nt.assert_raises(TypeError): jsdlink() w1 = ToggleButton() with nt.assert_raises(TypeError): jsdlink((w1, 'value')) w2 = ToggleButton() jsdlink((w1, 'value'), (w2, 'value')) with nt.assert_raises(TypeError): jsdlink((w1, 'value'), (w2, 'nosuchtrait')) with nt.assert_raises(TypeError): jsdlink((w1, 'value'), (w2, 'traits')) PKZHqҸ'ipywidgets/widgets/tests/test_traits.py"""Test trait types of the widget packages.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from unittest import TestCase from traitlets import HasTraits from traitlets.tests.test_traitlets import TraitTestBase from ipywidgets import Color, EventfulDict, EventfulList class ColorTrait(HasTraits): value = Color("black") class TestColor(TraitTestBase): obj = ColorTrait() _good_values = ["blue", "#AA0", "#FFFFFF"] _bad_values = ["vanilla", "blues"] class TestEventful(TestCase): def test_list(self): """Does the EventfulList work?""" event_cache = [] class A(HasTraits): x = EventfulList([c for c in 'abc']) a = A() a.x.on_events(lambda i, x: event_cache.append('insert'), \ lambda i, x: event_cache.append('set'), \ lambda i: event_cache.append('del'), \ lambda: event_cache.append('reverse'), \ lambda *p, **k: event_cache.append('sort')) a.x.remove('c') # ab a.x.insert(0, 'z') # zab del a.x[1] # zb a.x.reverse() # bz a.x[1] = 'o' # bo a.x.append('a') # boa a.x.sort() # abo # Were the correct events captured? self.assertEqual(event_cache, ['del', 'insert', 'del', 'reverse', 'set', 'set', 'sort']) # Is the output correct? self.assertEqual(a.x, [c for c in 'abo']) def test_dict(self): """Does the EventfulDict work?""" event_cache = [] class A(HasTraits): x = EventfulDict({c: c for c in 'abc'}) a = A() a.x.on_events(lambda k, v: event_cache.append('add'), \ lambda k, v: event_cache.append('set'), \ lambda k: event_cache.append('del')) del a.x['c'] # ab a.x['z'] = 1 # abz a.x['z'] = 'z' # abz a.x.pop('a') # bz # Were the correct events captured? self.assertEqual(event_cache, ['del', 'add', 'set', 'del']) # Is the output correct? self.assertEqual(a.x, {c: c for c in 'bz'}) PKZH$ipywidgets/widgets/tests/__init__.pyPK\HSDD,ipywidgets/widgets/tests/test_interaction.py"""Test interact and interactive.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function try: from unittest.mock import patch except ImportError: from mock import patch import nose.tools as nt from ipykernel.comm import Comm import ipywidgets as widgets from traitlets import TraitError from ipywidgets import interact, interactive, Widget, interaction from ipython_genutils.py3compat import annotate #----------------------------------------------------------------------------- # Utility stuff #----------------------------------------------------------------------------- class DummyComm(Comm): comm_id = 'a-b-c-d' def open(self, *args, **kwargs): pass def send(self, *args, **kwargs): pass def close(self, *args, **kwargs): pass _widget_attrs = {} displayed = [] undefined = object() def setup(): _widget_attrs['_comm_default'] = getattr(Widget, '_comm_default', undefined) Widget._comm_default = lambda self: DummyComm() _widget_attrs['_ipython_display_'] = Widget._ipython_display_ def raise_not_implemented(*args, **kwargs): raise NotImplementedError() Widget._ipython_display_ = raise_not_implemented def teardown(): for attr, value in _widget_attrs.items(): if value is undefined: delattr(Widget, attr) else: setattr(Widget, attr, value) def f(**kwargs): pass def clear_display(): global displayed displayed = [] def record_display(*args): displayed.extend(args) #----------------------------------------------------------------------------- # Actual tests #----------------------------------------------------------------------------- def check_widget(w, **d): """Check a single widget against a dict""" for attr, expected in d.items(): if attr == 'cls': nt.assert_is(w.__class__, expected) else: value = getattr(w, attr) nt.assert_equal(value, expected, "%s.%s = %r != %r" % (w.__class__.__name__, attr, value, expected) ) def check_widgets(container, **to_check): """Check that widgets are created as expected""" # build a widget dictionary, so it matches widgets = {} for w in container.children: widgets[w.description] = w for key, d in to_check.items(): nt.assert_in(key, widgets) check_widget(widgets[key], **d) def test_single_value_string(): a = u'hello' c = interactive(f, a=a) w = c.children[0] check_widget(w, cls=widgets.Text, description='a', value=a, ) def test_single_value_bool(): for a in (True, False): c = interactive(f, a=a) w = c.children[0] check_widget(w, cls=widgets.Checkbox, description='a', value=a, ) def test_single_value_dict(): for d in [ dict(a=5), dict(a=5, b='b', c=dict), ]: c = interactive(f, d=d) w = c.children[0] check_widget(w, cls=widgets.Dropdown, description='d', options=d, value=next(iter(d.values())), ) def test_single_value_float(): for a in (2.25, 1.0, -3.5): c = interactive(f, a=a) w = c.children[0] check_widget(w, cls=widgets.FloatSlider, description='a', value=a, min= -a if a > 0 else 3*a, max= 3*a if a > 0 else -a, step=0.1, readout=True, ) def test_single_value_int(): for a in (1, 5, -3): c = interactive(f, a=a) nt.assert_equal(len(c.children), 1) w = c.children[0] check_widget(w, cls=widgets.IntSlider, description='a', value=a, min= -a if a > 0 else 3*a, max= 3*a if a > 0 else -a, step=1, readout=True, ) def test_list_tuple_2_int(): with nt.assert_raises(ValueError): c = interactive(f, tup=(1,1)) with nt.assert_raises(ValueError): c = interactive(f, tup=(1,-1)) for min, max in [ (0,1), (1,10), (1,2), (-5,5), (-20,-19) ]: c = interactive(f, tup=(min, max), lis=[min, max]) nt.assert_equal(len(c.children), 2) d = dict( cls=widgets.IntSlider, min=min, max=max, step=1, readout=True, ) check_widgets(c, tup=d, lis=d) def test_list_tuple_3_int(): with nt.assert_raises(ValueError): c = interactive(f, tup=(1,2,0)) with nt.assert_raises(ValueError): c = interactive(f, tup=(1,2,-1)) for min, max, step in [ (0,2,1), (1,10,2), (1,100,2), (-5,5,4), (-100,-20,4) ]: c = interactive(f, tup=(min, max, step), lis=[min, max, step]) nt.assert_equal(len(c.children), 2) d = dict( cls=widgets.IntSlider, min=min, max=max, step=step, readout=True, ) check_widgets(c, tup=d, lis=d) def test_list_tuple_2_float(): with nt.assert_raises(ValueError): c = interactive(f, tup=(1.0,1.0)) with nt.assert_raises(ValueError): c = interactive(f, tup=(0.5,-0.5)) for min, max in [ (0.5, 1.5), (1.1,10.2), (1,2.2), (-5.,5), (-20,-19.) ]: c = interactive(f, tup=(min, max), lis=[min, max]) nt.assert_equal(len(c.children), 2) d = dict( cls=widgets.FloatSlider, min=min, max=max, step=.1, readout=True, ) check_widgets(c, tup=d, lis=d) def test_list_tuple_3_float(): with nt.assert_raises(ValueError): c = interactive(f, tup=(1,2,0.0)) with nt.assert_raises(ValueError): c = interactive(f, tup=(-1,-2,1.)) with nt.assert_raises(ValueError): c = interactive(f, tup=(1,2.,-1.)) for min, max, step in [ (0.,2,1), (1,10.,2), (1,100,2.), (-5.,5.,4), (-100,-20.,4.) ]: c = interactive(f, tup=(min, max, step), lis=[min, max, step]) nt.assert_equal(len(c.children), 2) d = dict( cls=widgets.FloatSlider, min=min, max=max, step=step, readout=True, ) check_widgets(c, tup=d, lis=d) def test_list_tuple_str(): values = ['hello', 'there', 'guy'] first = values[0] c = interactive(f, tup=tuple(values), lis=list(values)) nt.assert_equal(len(c.children), 2) d = dict( cls=widgets.Dropdown, value=first, options=values ) check_widgets(c, tup=d, lis=d) def test_list_tuple_invalid(): for bad in [ (), ]: with nt.assert_raises(ValueError): print(bad) # because there is no custom message in assert_raises c = interactive(f, tup=bad) def test_defaults(): @annotate(n=10) def f(n, f=4.5, g=1): pass c = interactive(f) check_widgets(c, n=dict( cls=widgets.IntSlider, value=10, ), f=dict( cls=widgets.FloatSlider, value=4.5, ), g=dict( cls=widgets.IntSlider, value=1, ), ) def test_default_values(): @annotate(n=10, f=(0, 10.), g=5, h={'a': 1, 'b': 2}, j=['hi', 'there']) def f(n, f=4.5, g=1, h=2, j='there'): pass c = interactive(f) check_widgets(c, n=dict( cls=widgets.IntSlider, value=10, ), f=dict( cls=widgets.FloatSlider, value=4.5, ), g=dict( cls=widgets.IntSlider, value=5, ), h=dict( cls=widgets.Dropdown, options={'a': 1, 'b': 2}, value=2 ), j=dict( cls=widgets.Dropdown, options=['hi', 'there'], value='there' ), ) def test_default_out_of_bounds(): @annotate(f=(0, 10.), h={'a': 1}, j=['hi', 'there']) def f(f='hi', h=5, j='other'): pass c = interactive(f) check_widgets(c, f=dict( cls=widgets.FloatSlider, value=5., ), h=dict( cls=widgets.Dropdown, options={'a': 1}, value=1, ), j=dict( cls=widgets.Dropdown, options=['hi', 'there'], value='hi', ), ) def test_annotations(): @annotate(n=10, f=widgets.FloatText()) def f(n, f): pass c = interactive(f) check_widgets(c, n=dict( cls=widgets.IntSlider, value=10, ), f=dict( cls=widgets.FloatText, ), ) def test_priority(): @annotate(annotate='annotate', kwarg='annotate') def f(kwarg='default', annotate='default', default='default'): pass c = interactive(f, kwarg='kwarg') check_widgets(c, kwarg=dict( cls=widgets.Text, value='kwarg', ), annotate=dict( cls=widgets.Text, value='annotate', ), ) @nt.with_setup(clear_display) def test_decorator_kwarg(): with patch.object(interaction, 'display', record_display): @interact(a=5) def foo(a): pass nt.assert_equal(len(displayed), 1) w = displayed[0].children[0] check_widget(w, cls=widgets.IntSlider, value=5, ) @nt.with_setup(clear_display) def test_interact_instancemethod(): class Foo(object): def show(self, x): print(x) f = Foo() with patch.object(interaction, 'display', record_display): g = interact(f.show, x=(1,10)) nt.assert_equal(len(displayed), 1) w = displayed[0].children[0] check_widget(w, cls=widgets.IntSlider, value=5, ) @nt.with_setup(clear_display) def test_decorator_no_call(): with patch.object(interaction, 'display', record_display): @interact def foo(a='default'): pass nt.assert_equal(len(displayed), 1) w = displayed[0].children[0] check_widget(w, cls=widgets.Text, value='default', ) @nt.with_setup(clear_display) def test_call_interact(): def foo(a='default'): pass with patch.object(interaction, 'display', record_display): ifoo = interact(foo) nt.assert_equal(len(displayed), 1) w = displayed[0].children[0] check_widget(w, cls=widgets.Text, value='default', ) @nt.with_setup(clear_display) def test_call_interact_on_trait_changed_none_return(): def foo(a='default'): pass with patch.object(interaction, 'display', record_display): ifoo = interact(foo) nt.assert_equal(len(displayed), 1) w = displayed[0].children[0] check_widget(w, cls=widgets.Text, value='default', ) with patch.object(interaction, 'display', record_display): w.value = 'called' nt.assert_equal(len(displayed), 1) @nt.with_setup(clear_display) def test_call_interact_kwargs(): def foo(a='default'): pass with patch.object(interaction, 'display', record_display): ifoo = interact(foo, a=10) nt.assert_equal(len(displayed), 1) w = displayed[0].children[0] check_widget(w, cls=widgets.IntSlider, value=10, ) @nt.with_setup(clear_display) def test_call_decorated_on_trait_change(): """test calling @interact decorated functions""" d = {} with patch.object(interaction, 'display', record_display): @interact def foo(a='default'): d['a'] = a return a nt.assert_equal(len(displayed), 1) w = displayed[0].children[0] check_widget(w, cls=widgets.Text, value='default', ) # test calling the function directly a = foo('hello') nt.assert_equal(a, 'hello') nt.assert_equal(d['a'], 'hello') # test that setting trait values calls the function with patch.object(interaction, 'display', record_display): w.value = 'called' nt.assert_equal(d['a'], 'called') nt.assert_equal(len(displayed), 2) nt.assert_equal(w.value, displayed[-1]) @nt.with_setup(clear_display) def test_call_decorated_kwargs_on_trait_change(): """test calling @interact(foo=bar) decorated functions""" d = {} with patch.object(interaction, 'display', record_display): @interact(a='kwarg') def foo(a='default'): d['a'] = a return a nt.assert_equal(len(displayed), 1) w = displayed[0].children[0] check_widget(w, cls=widgets.Text, value='kwarg', ) # test calling the function directly a = foo('hello') nt.assert_equal(a, 'hello') nt.assert_equal(d['a'], 'hello') # test that setting trait values calls the function with patch.object(interaction, 'display', record_display): w.value = 'called' nt.assert_equal(d['a'], 'called') nt.assert_equal(len(displayed), 2) nt.assert_equal(w.value, displayed[-1]) def test_fixed(): c = interactive(f, a=widgets.fixed(5), b='text') nt.assert_equal(len(c.children), 1) w = c.children[0] check_widget(w, cls=widgets.Text, value='text', description='b', ) def test_default_description(): c = interactive(f, b='text') w = c.children[0] check_widget(w, cls=widgets.Text, value='text', description='b', ) def test_custom_description(): d = {} def record_kwargs(**kwargs): d.clear() d.update(kwargs) c = interactive(record_kwargs, b=widgets.Text(value='text', description='foo')) w = c.children[0] check_widget(w, cls=widgets.Text, value='text', description='foo', ) w.value = 'different text' nt.assert_equal(d, {'b': 'different text'}) def test_interact_manual_button(): c = interactive(f, __manual=True) w = c.children[0] check_widget(w, cls=widgets.Button) def test_interact_manual_nocall(): callcount = 0 def calltest(testarg): callcount += 1 c = interactive(calltest, testarg=5, __manual=True) c.children[0].value = 10 nt.assert_equal(callcount, 0) def test_int_range_logic(): irsw = widgets.IntRangeSlider w = irsw(value=(2, 4), min=0, max=6) check_widget(w, cls=irsw, value=(2, 4), min=0, max=6) w.upper = 3 w.max = 3 check_widget(w, cls=irsw, value=(2, 3), min=0, max=3) w.min = 0 w.max = 6 w.lower = 2 w.upper = 4 check_widget(w, cls=irsw, value=(2, 4), min=0, max=6) w.value = (0, 1) #lower non-overlapping range check_widget(w, cls=irsw, value=(0, 1), min=0, max=6) w.value = (5, 6) #upper non-overlapping range check_widget(w, cls=irsw, value=(5, 6), min=0, max=6) w.lower = 2 check_widget(w, cls=irsw, value=(2, 6), min=0, max=6) with nt.assert_raises(TraitError): w.min = 7 with nt.assert_raises(TraitError): w.max = -1 w = irsw(min=2, max=3, value=(2, 3)) check_widget(w, min=2, max=3, value=(2, 3)) w = irsw(min=100, max=200, value=(125, 175)) check_widget(w, value=(125, 175)) with nt.assert_raises(TraitError): irsw(min=2, max=1) def test_float_range_logic(): frsw = widgets.FloatRangeSlider w = frsw(value=(.2, .4), min=0., max=.6) check_widget(w, cls=frsw, value=(.2, .4), min=0., max=.6) w.min = 0. w.max = .6 w.lower = .2 w.upper = .4 check_widget(w, cls=frsw, value=(.2, .4), min=0., max=.6) w.value = (0., .1) #lower non-overlapping range check_widget(w, cls=frsw, value=(0., .1), min=0., max=.6) w.value = (.5, .6) #upper non-overlapping range check_widget(w, cls=frsw, value=(.5, .6), min=0., max=.6) w.lower = .2 check_widget(w, cls=frsw, value=(.2, .6), min=0., max=.6) with nt.assert_raises(TraitError): w.min = .7 with nt.assert_raises(TraitError): w.max = -.1 w = frsw(min=2, max=3, value=(2.2, 2.5)) check_widget(w, min=2, max=3) with nt.assert_raises(TraitError): frsw(min=.2, max=.1) def test_multiple_selection(): smw = widgets.SelectMultiple # degenerate multiple select w = smw() check_widget(w, value=tuple()) # don't accept random other value when no options with nt.assert_raises(TraitError): w.value = (2,) check_widget(w, value=tuple()) # basic multiple select w = smw(options=[(1, 1)], value=[1]) check_widget(w, cls=smw, value=(1,), options=[(1, 1)]) # don't accept random other value with nt.assert_raises(TraitError): w.value = w.value + (2,) check_widget(w, value=(1,)) # change options w.options = w.options + [(2, 2)] check_widget(w, options=[(1, 1), (2,2)]) # change value w.value = w.value + (2,) check_widget(w, value=(1, 2)) # dict style w.options = {1: 1} check_widget(w, options={1: 1}) # updating with nt.assert_raises(TraitError): w.value = (2,) check_widget(w, options={1: 1}) def test_interact_noinspect(): a = u'hello' c = interactive(print, a=a) w = c.children[0] check_widget(w, cls=widgets.Text, description='a', value=a, ) PKH3M^*ipywidgets-5.0.0.dist-info/DESCRIPTION.rst.. image:: https://img.shields.io/pypi/v/ipywidgets.svg :target: https://pypi.python.org/pypi/ipywidgets/ :alt: Version Number .. image:: https://img.shields.io/pypi/dm/ipywidgets.svg :target: https://pypi.python.org/pypi/ipywidgets/ :alt: Number of PyPI downloads Interactive HTML Widgets ======================== Interactive HTML widgets for Jupyter notebooks and the IPython kernel. Usage ===== .. code-block:: python from ipywidgets import IntSlider IntSlider() PKHFVUU(ipywidgets-5.0.0.dist-info/metadata.json{"classifiers": ["Intended Audience :: Developers", "Intended Audience :: System Administrators", "Intended Audience :: Science/Research", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3"], "extensions": {"python.details": {"contacts": [{"email": "ipython-dev@scipy.org", "name": "IPython Development Team", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "http://ipython.org"}}}, "extras": ["test"], "generator": "bdist_wheel (0.26.0)", "keywords": ["Interactive", "Interpreter", "Shell", "Web"], "license": "BSD", "metadata_version": "2.0", "name": "ipywidgets", "platform": "Linux", "run_requires": [{"requires": ["ipykernel (>=4.2.2)", "ipython (>=4.0.0)", "traitlets (>=4.2.0)", "widgetsnbextension (>=1.0.0b5)"]}, {"extra": "test", "requires": ["nose"]}, {"environment": "python_version==\"2.7\"", "extra": "test", "requires": ["mock"]}], "summary": "IPython HTML widgets for Jupyter", "version": "5.0.0"}PKH\Q (ipywidgets-5.0.0.dist-info/top_level.txtipywidgets PKHndnn ipywidgets-5.0.0.dist-info/WHEELWheel-Version: 1.0 Generator: bdist_wheel (0.26.0) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any PKH%#ipywidgets-5.0.0.dist-info/METADATAMetadata-Version: 2.0 Name: ipywidgets Version: 5.0.0 Summary: IPython HTML widgets for Jupyter Home-page: http://ipython.org Author: IPython Development Team Author-email: ipython-dev@scipy.org License: BSD Keywords: Interactive,Interpreter,Shell,Web Platform: Linux Platform: Mac OS X Platform: Windows Classifier: Intended Audience :: Developers Classifier: Intended Audience :: System Administrators Classifier: Intended Audience :: Science/Research Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Requires-Dist: ipykernel (>=4.2.2) Requires-Dist: ipython (>=4.0.0) Requires-Dist: traitlets (>=4.2.0) Requires-Dist: widgetsnbextension (>=1.0.0b5) Provides-Extra: test Requires-Dist: nose; extra == 'test' Provides-Extra: test Requires-Dist: mock; python_version=="2.7" and extra == 'test' .. image:: https://img.shields.io/pypi/v/ipywidgets.svg :target: https://pypi.python.org/pypi/ipywidgets/ :alt: Version Number .. image:: https://img.shields.io/pypi/dm/ipywidgets.svg :target: https://pypi.python.org/pypi/ipywidgets/ :alt: Number of PyPI downloads Interactive HTML Widgets ======================== Interactive HTML widgets for Jupyter notebooks and the IPython kernel. Usage ===== .. code-block:: python from ipywidgets import IntSlider IntSlider() PKH]-T T !ipywidgets-5.0.0.dist-info/RECORDipywidgets/__init__.py,sha256=qiy6ay2_MdttTxJm4G2cMfktsvYQXnyi3UoxJs_2nGs,2219 ipywidgets/_version.py,sha256=HZSChrQ9Jn6Xq47qAy1YUcQQTaqCQGMfxhQaPwcwnXw,104 ipywidgets/widgets/__init__.py,sha256=2Fm6oxmPF5F5dXwvQfSqffV1ATucWyG2T3Lwgjc2mBU,1063 ipywidgets/widgets/domwidget.py,sha256=-KNbsqW-C9uvfm3-DdpCoiuTT9tjTx982N2S1oviG9w,4696 ipywidgets/widgets/eventful.py,sha256=UpCymf3vfqEMy7V9MPv-t5zvmt5Yiv0T4RSieBd4oz0,12072 ipywidgets/widgets/interaction.py,sha256=nmMu5nfsxEnSqXm0UG8MPESurv_KLQTIE-t3rH8UVEM,14474 ipywidgets/widgets/trait_types.py,sha256=xbgYbej2OcM69jCpBSKrAZvSZCTW7FLrzQA4yDEYIRg,3908 ipywidgets/widgets/widget.py,sha256=2pxgntaLmVvUpI72PBWjFnmSF3FMAfbPoqCJ9AJxzg8,18091 ipywidgets/widgets/widget_bool.py,sha256=oJ3CwWYkhGq7uPRkpa59lJj5Wf_j4fA0BKzHWcn7IwU,2746 ipywidgets/widgets/widget_box.py,sha256=T4-4GEI413i3vU1ZwYl2_scfcs3pMw8dhkQtClKi-II,4442 ipywidgets/widgets/widget_button.py,sha256=OjC8RNSsodEUnOuSxhAud6hqfiVgCwaOLhIoXXOsVxg,2508 ipywidgets/widgets/widget_color.py,sha256=xRG1IpBESX2NiBRsPtcC-8CJzndR-3qCXa8uOY6zxB4,716 ipywidgets/widgets/widget_controller.py,sha256=mtGr6kMgXbgwPaIpSpuezU4PsHukoZoRhpbMWOVQWik,2216 ipywidgets/widgets/widget_float.py,sha256=EB-sGHjSnYEAnRkk0Px-1EAPmRH9U-cSteF_XKUXGf0,9470 ipywidgets/widgets/widget_image.py,sha256=OWCOg9zxQGrbnoH0TRQ34H8lIZHOFiFhjOb4EtwQQdM,1233 ipywidgets/widgets/widget_int.py,sha256=Ulz8Dwa8nLFKvNvuhhckDQss4CFpxBSUemFgE2aBM5k,8780 ipywidgets/widgets/widget_layout.py,sha256=wbzieMRIRKSFlWnb2179I1rwSQCVBjqGc1WY0O0BhIU,1739 ipywidgets/widgets/widget_link.py,sha256=30vlfamQf_ZWXQoGlF4m0iTF14j9bFRlgq7mmJvxMVI,3283 ipywidgets/widgets/widget_output.py,sha256=-PYamkU1rQhYA50Z2oa3nDzlYegQEQT-jZiT9nqnlx4,2891 ipywidgets/widgets/widget_selection.py,sha256=jbyYJlt2X3f7W0opf0o0Agpitljx8XiK6DsqMpigsJQ,7963 ipywidgets/widgets/widget_selectioncontainer.py,sha256=2fgtjo-gomOy81hz69EOKx6BTphcIHkKGN1ZHUK7Zjg,1746 ipywidgets/widgets/widget_string.py,sha256=UJnlIZqbFTC3d80Jb9TbwVQVd4LuVyji2muSKS3FkuY,3236 ipywidgets/widgets/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 ipywidgets/widgets/tests/test_interaction.py,sha256=3noE2P97uFqBfTDTLbe-D3UhyYP-o9TpTKReKz6JU5M,17434 ipywidgets/widgets/tests/test_link.py,sha256=SnXu68g57nf_WLKd6I7YllPLOQlpH_gLPEaVGkVXWHY,1058 ipywidgets/widgets/tests/test_traits.py,sha256=LMi57vzRlAW6lEWV1Kp6qufpMYiOUGYWVLa3b_zTmfs,2204 ipywidgets-5.0.0.dist-info/DESCRIPTION.rst,sha256=wz9gaMZt75nWppdqvjMy5H6fN0RSiqdDpNEBPOOoVJg,494 ipywidgets-5.0.0.dist-info/METADATA,sha256=HK4Sk7FTBSgLfAi-9y5NoLPgtwxQb4uumriSjblOjWg,1482 ipywidgets-5.0.0.dist-info/RECORD,, ipywidgets-5.0.0.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 ipywidgets-5.0.0.dist-info/metadata.json,sha256=WLHg-hoT0BRZItWbpJP1QulJU5U5E5IvzbnqZ0Zpui4,1109 ipywidgets-5.0.0.dist-info/top_level.txt,sha256=Q6IYzaNK-b3ZCOEt1514fjWEXOfh-WAjCWZTcObuHkg,11 PKH}ipywidgets/__init__.pyPKH'[V hhipywidgets/_version.pyPK\H;qK K #{ ipywidgets/widgets/widget_output.pyPKH/"ipywidgets/widgets/widget_color.pyPKHj#"ipywidgets/widgets/widget_image.pyPKZH˓z(/(/$ipywidgets/widgets/eventful.pyPK\H\dօ/Lipywidgets/widgets/widget_selectioncontainer.pyPK'Hb?&Sipywidgets/widgets/widget_selection.pyPKnH XXsipywidgets/widgets/domwidget.pyPKH'ipywidgets/widgets/widget_controller.pyPKH]$$"ipywidgets/widgets/widget_float.pyPKHc''Ƴipywidgets/widgets/__init__.pyPKH}MFF)ipywidgets/widgets/widget.pyPKHL%#ipywidgets/widgets/widget_layout.pyPKZHD9"88!ipywidgets/widgets/interaction.pyPKZHxDD!>ipywidgets/widgets/trait_types.pyPKHWZZ fNipywidgets/widgets/widget_box.pyPKH #_ipywidgets/widgets/widget_string.pyPKH<'x !lipywidgets/widgets/widget_bool.pyPKHup< #wipywidgets/widgets/widget_button.pyPKHo{ !ipywidgets/widgets/widget_link.pyPKHZL"L" ipywidgets/widgets/widget_int.pyPKZH{`""%ipywidgets/widgets/tests/test_link.pyPKZHqҸ'ipywidgets/widgets/tests/test_traits.pyPKZH$˾ipywidgets/widgets/tests/__init__.pyPK\HSDD, ipywidgets/widgets/tests/test_interaction.pyPKH3M^*qipywidgets-5.0.0.dist-info/DESCRIPTION.rstPKHFVUU(ipywidgets-5.0.0.dist-info/metadata.jsonPKH\Q (B ipywidgets-5.0.0.dist-info/top_level.txtPKHndnn ipywidgets-5.0.0.dist-info/WHEELPKH%#? ipywidgets-5.0.0.dist-info/METADATAPKH]-T T !Jipywidgets-5.0.0.dist-info/RECORDPK