Source code for ipywidgets.widgets.widget_link

# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""Link and DirectionalLink classes.

Propagate changes between widgets on the javascript side.
"""

from .widget import Widget, register, widget_serialization
from .widget_core import CoreWidget

from traitlets import Unicode, Tuple, Instance, TraitError


[docs]class WidgetTraitTuple(Tuple): """Traitlet for validating a single (Widget, 'trait_name') pair""" info_text = "A (Widget, 'trait_name') pair"
[docs] def __init__(self, **kwargs): super().__init__(Instance(Widget), Unicode(), **kwargs) if "default_value" not in kwargs and not kwargs.get("allow_none", False): # This is to keep consistent behavior for spec generation between traitlets 4 and 5 # Having a default empty container is explicitly not allowed in traitlets 5 when # there are traits specified (as the default value will be invalid), but we do it # anyway as there is no empty "default" that makes sense. self.default_args = ()
def validate_elements(self, obj, value): value = super().validate_elements(obj, value) widget, trait_name = value trait = widget.traits().get(trait_name) trait_repr = "{}.{}".format(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.metadata.get('sync'): raise TypeError("%s cannot be synced" % trait_repr) return value