Skip to content

traits vs. traitlets vs. any other idea #1402

Open
@oesteban

Description

@oesteban

I am stuck with this problem in #1371. Particularly, in that PR I am facing the decision of 1) use more features of traits, making this dependency stronger; 2) make the move to traitlets for good; 3) consider any option somebody else can provide.

IMHO, traits/traitlets are the way to go. They solve nicely the problem of defining the inputs and outputs of the interfaces. They are intuitive (from the user point of view) and creating nipype interfaces has been proven relatively easy. So, if there is a poll on this (keep traits vs. moving to something else), I'd stick with the traits.

Then, the question of traits vs. traitlets. In my opinion, we are underexploiting some features of traits:

  • Features of both traits and traitlets we do not use:
    • Events: trait(let)s are observable and using callbacks would ease our lives a lot. Some scarce uses have been done. But, generally, only for simple tasks like validating a field or even shadowing existing features of traits like synchronization.
    • Synchronization: trait(let)s allow keeping traits synchronized
  • Features only in traits that we do not use:
    • Defining interfaces (somebody said interfaces?)
    • Mapped traits: these are convenient traits in constructs like this, in which you can append an underscore to the trait name to get the mapped name (in this case using interface.inputs.output_type_ would give you the current extension value, instead of the actual value of the trait.
    • Deferring and adaptation: I do not know why we would need this yet.

What we would get using these features:

  • For instance, the implementation of the IdentityInterface would be trivial: when creating the input and output fields, we would just need to synchronize them (using link in traitlets or sync in traits). Synchronization can be directed (i.e. from intputs to outputs only) in both trait(let)s
  • Something that interacts with @satra 's advances on the new workflow design: connections between interfaces (should) could be also implemented very easily with synchronization.
    • This would also make unnecessary some pieces of code that are making the interfaced workflow very tricky to implement. The logic under these _propagate_... functions is a bit cluttered and I have the impression that we just cover the mimimum set of situations.
    • Keeping the workflow synchronized with traits would remove this task from ourselves, and the pipeline engine will have two responsibilities: ordering the tasks and run them in that order. Which is a lot simpler.
    • Using traits.Interface makes the base code of interfaces a lot more readable and simple. In [WIP] Major refactor (nipype-1.5 ?) #1371, I proposed that interfaces, inputs and outputs are traits.Interfaces.

I am probably forgetting a lot of stuff, but I hope this is more than enough to make an informed decision. What are your thoughts?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions