-
Notifications
You must be signed in to change notification settings - Fork 533
[MAINT] Reorganize nipype.interfaces.base #2303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
It'd be great to consider this one ASAP before it gets stale @satra - I asked Dorota and Mathias for reviews, but your big-picture opinion would be greatly appreciated :) |
@oesteban - completely missed the request... Will check in the morning and see if I have any comments. |
@djarecka sure, no rush! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to go through my old traitlets pr and see which concerns were valid also for traits. I made some comments to your changes, but some of them are related to part you're not changing:
-
is anyone using
MpiCommandLine
? couldn't find any examples innipype
https://github.com/oesteban/nipype/blob/ref/interface-base/nipype/interfaces/base/core.py#L1145 -
_check_version_requirements
does not check the max_version, this block has wrong indentation: https://github.com/oesteban/nipype/blob/ref/interface-base/nipype/interfaces/base/core.py#L403 -
I was a bit confused about
BaseFile
andFile
, etc., do we really need both? Also I believe that we're assuming thatBaseUnicode
uses the fast validator (https://github.com/oesteban/nipype/blob/ref/interface-base/nipype/interfaces/base/traits_extension.py#L98), but from traits documentation I understood thatUnicode
(notBaseUnicode
) uses the C-level fast validator (http://docs.enthought.com/traits/traits_api_reference/trait_types.html?highlight=baseunicode#traits.trait_types.BaseUnicode. Am I missing something?
""" | ||
_ = traits.Disallow | ||
|
||
|
||
class Interface(object): | ||
"""This is an abstract definition for Interface objects. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a general question that I had at some point, since we try to build an abstract class here, have you ever had discussion about abc
class? Never used it, but it seems to be the package to write an abstract class in python
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Back in a day, I proposed something similar: https://github.com/oesteban/nipype/blob/fe4578b4461ee8aee63c86eaf47de5ac4985fae6/nipype/interfaces/base/interfaces.py#L62-L101
In this case, using the abstract interfaces that you build using traits.api.Interface
and those @provides
decorators.
**{'%s' % name: Undefined, | ||
'%s' % trait_spec.new_name: new}) | ||
|
||
def _hash_infile(self, adict, key): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we're not using it anywhere
nipype/interfaces/base/specs.py
Outdated
""" | ||
|
||
dict_withhash = [] | ||
dict_nofilename = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dict_withhash
and dict_nofilename
are lists, should we slightly change the names?
sorted_dict = to_str(sorted(dict_nofilename.items())) | ||
return dict_withhash, md5(sorted_dict.encode()).hexdigest() | ||
|
||
def __pretty__(self, p, cycle): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this method still working? is it for this package: http://ipython.readthedocs.io/en/stable/api/generated/IPython.lib.pretty.html#extending ?
they suggest _repr_pretty_
'which is already set') % (name, trait_name) | ||
raise IOError(msg) | ||
|
||
def _requires_warn(self, obj, name, old, new): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couldn't find any place where we're using it
@@ -334,3 +352,117 @@ def has_metadata(trait, metadata, value=None, recursive=True): | |||
count += has_metadata(handler, metadata, recursive) | |||
|
|||
return count > 0 | |||
|
|||
|
|||
class MultiPath(traits.List): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
after @satra suggestions i've started calling it MultiObject
self.set_value(object, name, value) | ||
|
||
|
||
class InputMultiPath(MultiPath): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this class don't have any new method so i was wondering if we can decrease number of classes, e.g. leave InputMultiPath
and OutputMultiPath
return '{}'.format(self.value) | ||
|
||
|
||
class Bunch(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should try to refine and simplify this class' usage. perhaps replace it with hastraits
in a refactor. this was one of the first classes we created in nipype to simplify interactive usage even before traits was added!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, this would be great to add in @djarecka's issue.
so = Status() | ||
wf = pe.Workflow(name='test', base_dir=tmpdir.strpath) | ||
wf = pe.Workflow(name='test') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps base_dir
should be set to local wd. in this case the working directory will be in some other tmp directory
setup.py
Outdated
@@ -106,7 +106,7 @@ def main(): | |||
pjoin('workflows', 'data', '*'), | |||
pjoin('pipeline', 'engine', 'report_template.html'), | |||
pjoin('external', 'd3.js'), | |||
pjoin('interfaces', 'script_templates', '*'), | |||
pjoin('script_templates', '*'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since the script_templates are all fsl model related, perhaps this can be moved into interfaces/fsl/model/script_templates
@oesteban - overall looks great! |
Thanks! @mgxd may you do the honors? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm - minor comments
as the `inputs` to another node when interfaces are used in | ||
the pipeline. | ||
runtime : Bunch | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extra line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed 👍
from .. import (get_custom_path, RegAladin, RegF3D) | ||
|
||
|
||
def no_nifty_tool(cmd=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe define in tests/utils.py
and import in each test?
nipype/utils/filemanip.py
Outdated
""" | ||
|
||
if pathext is None: | ||
pathext = os.environ.get("PATHEXT", "").split(os.pathsep) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
os.getenv cleaner?
@oesteban - shouldn't many of the base tests move into the base directory as well? |
Working on it |
this PR will require a huge |
@oesteban - changes look good to me. thanks for the effort. |
when updating the autotests make sure to add init.py to the new test folders. |
This PR intends to 1) split
nipype/nipype/interfaces/base.py
in a more digestible python submodule; 2) remove miscellaneous/utility functions and place them in modules where they are more visible or they fit better. After all, nipype code should be more readable after these changes;3) completely isolate the
traits_extension
module, so users are now expected to usebase.traits
for all traits in nipype. That would also help the transition towards traits or alternatives.This PR does not intend to change any functionality. The idea is making it easier to transition code of Nipype Interfaces from 1.0 to 2.0. Also, it will be very appreciated in a "detachable" nipype
CommandLine
I'm working on (therun
member will still work exactly the same, but you can juststart
an interface and let it run in the background while you keep using your ipython shell, for instance).New module structure
This should not be merged before releasing 0.14.0.
List of changes:
nipype.interfaces.base._exists_in_path
->nipype.utils.filemanip.which
. Additionally, this function has been modified to rely onshutil.which
on python >= 3.3. This function does not returnbool, str
anymore, to make it more similar toshutil.which
. If a command is not found in PATH, it returnsNone
(vs.False, None
in the former version). Uses of the old_exists_in_path
have been revised for this change.nipype.interfaces.base._canonicalize_env
->nipype.utils.filemanip.canonicalize_env
.nipype.interfaces.base.get_depencencies
->nipype.utils.filemanip.get_dependencies
.OutputMultiPath
,InputMultiPath
, etc) and some monkeypatches to tratis into the newtraits_extension
submodule.BaseTraitedSpec
,TraitedSpec
,DynamicTraitedSpec
, etc) into anipype.interfaces.base.specs
module.nipype.interfaces.base.load_template
tonipype.interfaces.fsl.model
which was the only module that relied on it. A stub for backwards compatibility with a deprecation warning has been left in place. I also moved thescript_templates
folder to a (IMHO) better location under the top folder. Also, the templates are now accessed using thepackage_resources
module.support
with utilities to the base interfaces (theBunch
,InterfaceResult
, etc.).nifty-
interfaces to use theversion_from_command
property of nipype interfaces (instead of re-implementing the same thing).