Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract out the notion of a traitlet instance type that can be initialized with a dict #1253

Merged
merged 2 commits into from
Apr 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions ipywidgets/widgets/domwidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,16 @@

from traitlets import Unicode, Bool, Tuple, default
from .widget import Widget, widget_serialization
from .trait_types import Color
from .widget_layout import Layout, LayoutTraitType
from .trait_types import Color, InstanceDict
from .widget_layout import Layout


class DOMWidget(Widget):
"""Widget that can be inserted into the DOM"""

_model_name = Unicode('DOMWidgetModel').tag(sync=True)
_dom_classes = Tuple(help="CSS classes applied to widget DOM element").tag(sync=True)
layout = LayoutTraitType().tag(sync=True, **widget_serialization)

@default('layout')
def _default_layout(self):
return Layout()
layout = InstanceDict(Layout).tag(sync=True, **widget_serialization)

def add_class(self, className):
"""
Expand Down
17 changes: 17 additions & 0 deletions ipywidgets/widgets/trait_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,20 @@ def datetime_from_json(js, manager):
'from_json': datetime_from_json,
'to_json': datetime_to_json
}

class InstanceDict(traitlets.Instance):
"""An instance trait which coerces a dict to an instance.
This lets the instance be specified as a dict, which is used to initialize the instance.
Also, we default to a trivial instance, even if args and kwargs is not specified."""

def validate(self, obj, value):
if isinstance(value, dict):
return super(InstanceDict, self).validate(obj, self.klass(**value))
else:
return super(InstanceDict, self).validate(obj, value)

def make_dynamic_default(self):
return self.klass(*(self.default_args or ()),
**(self.default_kwargs or {}))
8 changes: 2 additions & 6 deletions ipywidgets/widgets/widget_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from .widget import CallbackDispatcher, register, widget_serialization
from .widget_core import CoreWidget
from .widget_style import Style
from .trait_types import Color
from .trait_types import Color, InstanceDict

from traitlets import Unicode, Bool, CaselessStrEnum, Instance, validate, default
import warnings
Expand Down Expand Up @@ -55,11 +55,7 @@ class Button(DOMWidget, CoreWidget):
values=['primary', 'success', 'info', 'warning', 'danger', ''], default_value='',
help="""Use a predefined styling for the button.""").tag(sync=True)

style = Instance(ButtonStyle).tag(sync=True, **widget_serialization)

@default('style')
def _default_style(self):
return ButtonStyle()
style = InstanceDict(ButtonStyle).tag(sync=True, **widget_serialization)

def __init__(self, **kwargs):
super(Button, self).__init__(**kwargs)
Expand Down
35 changes: 11 additions & 24 deletions ipywidgets/widgets/widget_float.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

from traitlets import (
Instance, Unicode, CFloat, Bool, CaselessStrEnum, Tuple, TraitError, validate, default
)
from .domwidget import LabeledWidget
from .trait_types import InstanceDict
from .valuewidget import ValueWidget
from .widget import register, widget_serialization
from .widget_core import CoreWidget
from .trait_types import Color
from .widget_int import ProgressStyle
from traitlets import (
Instance, Unicode, CFloat, Bool, Int, CaselessStrEnum, Tuple, TraitError, validate, default
)
from .widget_int import ProgressStyle, SliderStyle


class _Float(LabeledWidget, ValueWidget, CoreWidget):
Expand Down Expand Up @@ -75,8 +75,6 @@ class FloatText(_Float):
value displayed
description : str
description displayed next to the text box
color : str Unicode color code (eg. '#C13535')
color of the value displayed
"""
_view_name = Unicode('FloatTextView').tag(sync=True)
_model_name = Unicode('FloatTextModel').tag(sync=True)
Expand All @@ -98,8 +96,6 @@ class BoundedFloatText(_BoundedFloat):
maximal value of the range of possible values displayed
description : str
description displayed next to the textbox
color : str Unicode color code (eg. '#C13535')
color of the value displayed
"""
_view_name = Unicode('FloatTextView').tag(sync=True)
_model_name = Unicode('FloatTextModel').tag(sync=True)
Expand Down Expand Up @@ -129,10 +125,6 @@ class FloatSlider(_BoundedFloat):
default is '.2f', specifier for the format function used to represent
slider value for human consumption, modeled after Python 3's format
specification mini-language (PEP 3101).
slider_color : str Unicode color code (eg. '#C13535')
color of the slider
color : str Unicode color code (eg. '#C13535')
color of the value displayed (if readout == True)
"""
_view_name = Unicode('FloatSliderView').tag(sync=True)
_model_name = Unicode('FloatSliderModel').tag(sync=True)
Expand All @@ -141,9 +133,10 @@ class FloatSlider(_BoundedFloat):
_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)
readout_format = Unicode('.2f', help="Format for the readout").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)

style = InstanceDict(SliderStyle).tag(sync=True, **widget_serialization)


@register
class FloatProgress(_BoundedFloat):
Expand Down Expand Up @@ -177,11 +170,7 @@ class FloatProgress(_BoundedFloat):
default_value='', allow_none=True,
help="Use a predefined styling for the progess bar.").tag(sync=True)

style = Instance(ProgressStyle).tag(sync=True, **widget_serialization)

@default('style')
def _default_style(self):
return ProgressStyle()
style = InstanceDict(ProgressStyle).tag(sync=True, **widget_serialization)


class _FloatRange(_Float):
Expand Down Expand Up @@ -270,16 +259,14 @@ class FloatRangeSlider(_BoundedFloatRange):
default is '.2f', specifier for the format function used to represent
slider value for human consumption, modeled after Python 3's format
specification mini-language (PEP 3101).
slider_color : str Unicode color code (eg. '#C13535')
color of the slider
color : str Unicode color code (eg. '#C13535')
color of the value displayed (if readout == True)
"""
_view_name = Unicode('FloatSliderView').tag(sync=True)
_model_name = Unicode('FloatSliderModel').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)
readout_format = Unicode('.2f', help="Format for the readout").tag(sync=True)
continuous_update = Bool(True, help="Update the value of the widget as the user is sliding the slider.").tag(sync=True)

style = InstanceDict(SliderStyle).tag(sync=True, **widget_serialization)
16 changes: 4 additions & 12 deletions ipywidgets/widgets/widget_int.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from .widget_core import CoreWidget
from .widget_style import Style
from traitlets import Instance
from .trait_types import Color
from .trait_types import Color, InstanceDict
from traitlets import (
Unicode, CInt, Bool, CaselessStrEnum, Tuple, TraitError, default, validate
)
Expand Down Expand Up @@ -164,11 +164,7 @@ class IntSlider(_BoundedInt):
readout_format = Unicode('d', help="Format for the readout").tag(sync=True)
continuous_update = Bool(True, help="Update the value of the widget as the user is holding the slider.").tag(sync=True)

style = Instance(SliderStyle).tag(sync=True, **widget_serialization)

@default('style')
def _default_style(self):
return SliderStyle()
style = InstanceDict(SliderStyle).tag(sync=True, **widget_serialization)


@register
Expand All @@ -192,11 +188,7 @@ class IntProgress(_BoundedInt):
values=['success', 'info', 'warning', 'danger', ''], default_value='',
help="""Use a predefined styling for the progess bar.""").tag(sync=True)

style = Instance(ProgressStyle).tag(sync=True, **widget_serialization)

@default('style')
def _default_style(self):
return ProgressStyle()
style = InstanceDict(ProgressStyle).tag(sync=True, **widget_serialization)


class _IntRange(_Int):
Expand Down Expand Up @@ -280,8 +272,8 @@ class IntRangeSlider(_BoundedIntRange):
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)
style = InstanceDict(SliderStyle).tag(sync=True, **widget_serialization)


@register
Expand Down
2 changes: 1 addition & 1 deletion ipywidgets/widgets/widget_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ class LayoutTraitType(Instance):

def validate(self, obj, value):
if isinstance(value, dict):
return super(LayoutTraitType, self).validate(obj, Layout(**value))
return super(LayoutTraitType, self).validate(obj, self.klass(**value))
else:
return super(LayoutTraitType, self).validate(obj, value)