-
-
Notifications
You must be signed in to change notification settings - Fork 208
Description
Since Matplotlib's folks are starting to write traitlet-based APIs, we probably need to think of a roadmap for the future of the library if it is to be more widely adopted by the Scipy community.
There are some improvements that we could easily make without splitting traitlets in two different repos:
1. Deprecate trait attribute declaration with TraitType types instead of TraitType instances
class Foo(HasTraits):
bar = Int # deprecated
baz = Int() # ok
alpha = List(trait=Int) # deprecated
alpha = List(trait=Int()) # ok(Implemented in #51 and #55 - merged)
2. Like in Atom, separate the metadata from the keyword arguments in TraitType's constructor.
x = Int(allow_none=True, sync=True) # deprecated
x = Int(allow_none=True).tag(sync=True) # ok(Implemented in #53 - merged)
3. A replacement for the cumbersome on_trait_change in the future, with a more convenient signature and a simpler name.
-
We now use
observe/unobservemethod instead of using aremove=True/Falseargument withon_trait_change. -
observe takes 1 positional argument (the handler), and two keyword arguments,
namesandtype. -
The callbacks take a single
changedictionary argument, containing{ 'owner': the HasTraits instance, 'old': the old trait attribute value, 'new': the new trait attribute value, 'name': the name of the changing attribute, } -
A new
@observedecorator to register methods as trait change handlers.
(Implemented in #61 - merged)
4. Deprecate the custom cross-validation magic methods _*bar*_validate to the benefit of a @validate('bar') decorator.
(Implemented in #73 - merged)
5. Since the base trait type now inherits from BaseDescriptor and other descriptors are defined to work well with HasTraits, we could make the following changes:
- rename MetaHasTraits into MetaHasDescriptors and deprecate the old name.
- introduce a base class to HasTraits called HasDescriptors.
(Implemented in #70 - merged)
6. Deprecate the default-value initializer magic methods _*bar*_default to the benefit of a @default('bar') decorator.
(Implemented in #114 - merged)
7. What is the best place for a repository of extra trait types for common types in the scipy stack such as ` numpy arrays, pandas/xray data structures, and their (binary) serialization functions for widgets (or other clients of comms) and ipyparallel?
It would make sense to propose a reference implementation of those, otherwise we will see multiple competing implementation emerge in different projects.
Besides, it is unlikely that such things would be accepted in core Pandas and numpy as of now...
(Scipy Trait Types Incubator Proposal)
8. Would it make sense to have a once version of on_trait_change (now observe)?
(There seems to be mixed opinions on this. Deferred.)
9. A common pattern when observing an object is the following:
foo.observe(do_something) # register to future change notifications.
do_something() # act on the current value right away.maybe we could facilitate this by adding a boolean argument to observe, stating whether to also run the callback right-away or not.
This would especially be useful when registering observer with the decorator syntax.
10. One thing that we had in mind in the long-run for widgets is having finer-grained events for containers, such as List and Dict. The ability to create other descriptors than trait types, possibly outside of the traitlets repository could enable experiments in this directions, like an integration of @jdfreder 's eventful dicts and lists.
One idea that could be in the scope of traitlets though is to add an attribute to the change dictionary indicating the type of notification that is being sent.
{
'owner': the HasTraits instance,
'old': the old trait attribute value,
'new': the new trait attribute value,
'name': the name of the changing attribute,
'type': the type of notification being sent,
}The last attribute could be used to define notification types corresponding to operational transforms.
Then, the @observe decorator would then have a 'type' keyword argument, (defaulting to None), to filter by notification type.
class Foo(HasTraits):
bar = Int()
baz = EventfulList()
@observe('bar') # Filter to only observe trait changes
def handler_bar(self, change):
pass
@observe('baz ', type='element_change') # Register to element change notifications for `baz`
def handler_baz(self, change):
pass
@observe('bar', 'baz', type=All) # register to all notification types for `bar` and `baz`
def handler_all(self, change):
passThe only thing to do to enable this possibility would be to add a type item in the dictionary and have the current implementation of observe filter on the notification type.
(Implemented in #83 - merged)