##// END OF EJS Templates
skip permission -> 403 test on Windows...
skip permission -> 403 test on Windows The test actually passes on my VM (Win 7), but not on Jenkins (Server 2012). I haven't figured out how to identify the subset of Windows systems where it won't work, but since the problem appears to be in the test, not the tested code, skipping on Windows seems the right way to go.

File last commit:

r20230:403a37ac
r20575:7211fc10
Show More
widget_link.py
111 lines | 3.5 KiB | text/x-python | PythonLexer
"""Link and DirectionalLink classes.
Propagate changes between widgets on the javascript side
"""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
from .widget import Widget
from IPython.testing.skipdoctest import skip_doctest
from IPython.utils.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
class Link(Widget):
"""Link Widget
one trait:
widgets, a list of (widget, 'trait_name') tuples which should be linked in the frontend.
"""
_model_name = Unicode('LinkModel', sync=True)
widgets = List(WidgetTraitTuple, sync=True)
def __init__(self, widgets, **kwargs):
if len(widgets) < 2:
raise TypeError("Require at least two widgets to link")
kwargs['widgets'] = widgets
super(Link, self).__init__(**kwargs)
# for compatibility with traitlet links
def unlink(self):
self.close()
@skip_doctest
def jslink(*args):
"""Link traits from different widgets together on the frontend so they remain in sync.
Parameters
----------
*args : two or more (Widget, 'trait_name') tuples that should be kept in sync.
Examples
--------
>>> c = link((widget1, 'value'), (widget2, 'value'), (widget3, 'value'))
"""
return Link(widgets=args)
class DirectionalLink(Widget):
"""A directional link
source: a (Widget, 'trait_name') tuple for the source trait
targets: one or more (Widget, 'trait_name') tuples that should be updated
when the source trait changes.
"""
_model_name = Unicode('DirectionalLinkModel', sync=True)
targets = List(WidgetTraitTuple, sync=True)
source = WidgetTraitTuple(sync=True)
# Does not quite behave like other widgets but reproduces
# the behavior of IPython.utils.traitlets.directional_link
def __init__(self, source, targets, **kwargs):
if len(targets) < 1:
raise TypeError("Require at least two widgets to link")
kwargs['source'] = source
kwargs['targets'] = targets
super(DirectionalLink, self).__init__(**kwargs)
# for compatibility with traitlet links
def unlink(self):
self.close()
@skip_doctest
def jsdlink(source, *targets):
"""Link the trait of a source widget with traits of target widgets in the frontend.
Parameters
----------
source : a (Widget, 'trait_name') tuple for the source trait
*targets : one or more (Widget, 'trait_name') tuples that should be updated
when the source trait changes.
Examples
--------
>>> c = dlink((src_widget, 'value'), (tgt_widget1, 'value'), (tgt_widget2, 'value'))
"""
return DirectionalLink(source=source, targets=targets)