##// END OF EJS Templates
fix bug in stale profile clean up for clusters...
fix bug in stale profile clean up for clusters "clusters" tab of my notebook wasn't rendering, so checked the log, found the stack trace: ``` [...] File "/usr/local/lib/python3.4/site-packages/ipython-3.0.0-py3.4.egg/IPython/html/services/clusters/handlers.py", line 21, in get self.finish(json.dumps(self.cluster_manager.list_profiles())) File "/usr/local/lib/python3.4/site-packages/ipython-3.0.0-py3.4.egg/IPython/html/services/clusters/clustermanager.py", line 77, in list_profiles self.update_profiles() File "/usr/local/lib/python3.4/site-packages/ipython-3.0.0-py3.4.egg/IPython/html/services/clusters/clustermanager.py", line 74, in update_profiles self.profiles.pop(stale) TypeError: unhashable type: 'set' ``` looks like a pretty straightforward mistake

File last commit:

r21208:e65db1aa
r21236:10a376e0
Show More
widget_link.py
108 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.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()
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()
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)