class JS: parent = event.prop(parent) @event.connect('parent') def on_parent(self, *events): parent = events[-1].new_value parent_id = 'None' if parent is None else parent._id print('parent of %s changed to %s in JS' % (self._id, parent_id))
class Node(app.Model): parent = event.prop(parent) @event.connect('parent') def on_parent(self, *events): parent = events[-1].new_value parent_id = 'None' if parent is None else parent._id print('parent of %s changed to %s in Py' % (self._id, parent_id)) class Both: # cannot define parent prop here; it would result in an infinite loop @event.prop def children(self, new_children=()): old_children = self.children if not old_children: # Can be None during initialization old_children = [] for child in old_children: if child not in new_children: child.parent = None for child in new_children: if child not in old_children: child.parent = self return tuple(new_children) class JS: parent = event.prop(parent) @event.connect('parent') def on_parent(self, *events): parent = events[-1].new_value parent_id = 'None' if parent is None else parent._id print('parent of %s changed to %s in JS' % (self._id, parent_id))
def test_property(): class MyObject(event.HasEvents): @event.prop def foo(self, v=1.2): return float(v) @event.prop def bar(self, v=1.3): return float(v) m = MyObject() assert m.foo == 1.2 assert m.bar == 1.3 m = MyObject(foo=3) assert m.foo == 3.0 m.foo = 5.1 m.bar = 5.1 assert m.foo == 5.1 assert m.bar == 5.1 m.foo = '9.3' assert m.foo == 9.3 m = MyObject(foo=3) assert m.foo == 3.0 # Hacky, but works def foo(): pass x = event.prop(foo) assert 'foo' in repr(x) spam = lambda x:None x = event.prop(spam) assert '<lambda>' in repr(x) # fails with raises(ValueError): m.foo = 'bla' with raises(ValueError): MyObject(foo='bla') with raises(TypeError): m._set_prop(3, 3) # Property name must be a string with raises(AttributeError): m._set_prop('spam', 3) # MyObject has not spam property with raises(AttributeError): MyObject(spam='bla') # MyObject has not spam property with raises(TypeError): event.prop(3) # prop decorator needs callable with raises(AttributeError): del m.foo # cannot delete a property class MyObject2(event.HasEvents): @event.prop def foo(self, v): return float(v) #with raises(RuntimeError): # MyObject2() # no default value for foo ob = MyObject2() assert ob.foo is None