def test_link_broken_at_target(self, A, B): a = A() b = A() dl = dlink((a, "value"), (b, "value"), transform=lambda x: x**2) l = link((a, "value"), (b, "value")) with pytest.raises(t.TraitError): b.value = 2
def test_no_traits(self, A=_A): a = A() class B: value = 3 b = B() with pytest.raises(ValueError): l = dlink((b, "value"), (a, "value"))
def test_connect_same_trait_target_undefined_target_trait( self, A=_A, B=_A): """Verify two traitlets of the same type can be linked together using link.""" a = A() b = B(value=9) # b.value is Undefined # Conenct the two classes. c = dlink((a, 'value'), (b, 'value')) assert b.value == 9 # Change one of the values to make sure they stay in sync. a.value = 5 assert a.value == b.value b.value = 6 assert a.value != b.value del a.value # Reset trait (to Undefined in this case) assert b.value is t.Undefined
def test_unlink_link(self, A, B): """Verify two linked traitlets can be unlinked.""" a = A(value=9) b = B(value=8) # Connect the two classes. c = dlink((a, 'value'), (b, 'value')) a.value = 4 c.unlink() # Change one of the values to make sure they don't stay in sync. a.value = 5 assert a.value != b.value c.link() a.value == b.value a.value += 1 a.value == b.value
def test_link_different(self, A, B): """Verify two traitlets of different types can be linked together using link.""" a = A(value=9) b = B(count=8) # Conenct the two classes. c = dlink((a, 'value'), (b, 'count')) # Make sure the values are the same at the point of linking. assert a.value == b.count # Change one the value of the source and check that it synchronizes the # target. a.value = 5 assert b.count == 5 # Change one the value of the target and check that it has no impact on # the source b.value = 6 assert a.value == 5
def test_tranform(self, A, B): """Test transform link.""" # Create two simple classes with Int traitlets. a = A(value=9) b = B(value=8) # Conenct the two classes. c = dlink((a, 'value'), (b, 'value'), lambda x: 2 * x) # Make sure the values are correct at the point of linking. assert b.value == 2 * a.value # Change one the value of the source and check that it modifies the # target. a.value = 5 assert b.value == 10 # Change one the value of the target and check that it has no impact on # the source b.value = 6 assert a.value == 5
def test_connect_same(self, A, B): """Verify two traitlets of the same type can be linked together using dlink.""" # Create two simple classes with Int traitlets. a = A(value=9) b = B(value=8) # Conenct the two classes. c = dlink((a, 'value'), (b, 'value')) # Make sure the values are the same at the point of linking. assert a.value == b.value # Change one the value of the source and check that it synchronizes the # target. a.value = 5 assert b.value == 5 # Change one the value of the target and check that it has no impact on # the source b.value = 6 assert a.value == 5
def test_connect_same_trait_source_undefined(self, A=_A, B=_B): """Verify two traitlets of the same type can be linked together using link.""" a = A() # a.value is Undefined b = B(value=8) # Conenct the two classes. c = dlink((a, 'value'), (b, 'value')) # Linking doesn't change b.value because a.value is undefined assert b.value == 8 # Change one of the values to make sure they stay in sync. a.value = 5 assert a.value == b.value b.value = 6 assert a.value != b.value del a.value # Reset trait (to Undefined in this case) if has_traitlets(b): # linking sets b.value to 0 if it has traitlets assert b.value == 0 else: assert b.value is t.Undefined
def _get_value_widget(obj, index=None): wdict = {} widget_bounds = _interactive_slider_bounds(obj, index=index) thismin = FloatText( value=widget_bounds['min'], description='min', layout=Layout(flex='0 1 auto', width='auto'), ) thismax = FloatText( value=widget_bounds['max'], description='max', layout=Layout(flex='0 1 auto', width='auto'), ) current_value = obj.value if index is None else obj.value[index] if index is None: current_name = obj.name else: current_name = '{}'.format(index) widget = FloatSlider(value=current_value, min=thismin.value, max=thismax.value, step=widget_bounds['step'], description=current_name, layout=Layout(flex='1 1 auto', width='auto')) def on_min_change(change): if widget.max > change['new']: widget.min = change['new'] widget.step = np.abs(widget.max - widget.min) * 0.001 def on_max_change(change): if widget.min < change['new']: widget.max = change['new'] widget.step = np.abs(widget.max - widget.min) * 0.001 thismin.observe(on_min_change, names='value') thismax.observe(on_max_change, names='value') # We store the link in the widget so that they are not deleted by the # garbage collector thismin._link = dlink((obj, "bmin"), (thismin, "value")) thismax._link = dlink((obj, "bmax"), (thismax, "value")) if index is not None: # value is tuple, expanding def _interactive_tuple_update(value): """Callback function for the widgets, to update the value """ obj.value = obj.value[:index] + (value['new'],) +\ obj.value[index + 1:] widget.observe(_interactive_tuple_update, names='value') else: link((obj, "value"), (widget, "value")) container = HBox((thismin, widget, thismax)) wdict["value"] = widget wdict["min"] = thismin wdict["max"] = thismax return { "widget": container, "wdict": wdict, }