textual
textual copied to clipboard
Decorator madness
Decorators for watch, compute, and validate. Works like this:
class MyWidget(Widget):
count = reactive(0)
double_count = reactive(0)
@count.watch
def count_changed(self, new_count:int):
...
@count.validate
def _max_ten(self, value:int) -> int:
return min(10, value)
@double_count.compute
def _double(self) -> int:
return self.count * 2
With this change, how would we override what a watcher does in a widget subclass?
If I have a count
reactive declared in a widget which has a watcher defined, then I subclass that and I want my own watcher, how would I achieve this? In the child class, @count.watch
doesn't work because count
is not defined.
For example, this fails to run because NameError: name 'count' is not defined
class Parent(Widget):
count: Reactive[int] = reactive(0, init=False)
@count.watch
def _count_parent(self, new_value: int) -> None:
print("parent watcher")
class Child(Parent):
@count.watch
def _count_parent(self, new_value: int) -> None:
print("child watcher")
@Parent.count.watch
doesn't work because of the "only a single method may be decorated with watch".
Even if that's solved, there's still a bit of a developer experience issue that @davep mentioned, whereby we no longer know what the parent watch method is called without going looking for it.
Going to park this for now. @darrenburns 's observation re inheritance may kill this idea entirely.