Repository: nipy/nipype

Issue:
BaseInterface.help() doesn't distinguish between arguments of type T and List(T)
Here's an example.  In this case, `input_image` is a `File()`, while `transforms` is an `InputMultiPath(File())`.  

``` python
In [21]: ants.ApplyTransforms.help()
Wraps command **antsApplyTransforms**
...
    [Mandatory]
    input_image: (an existing file name)
        image to apply transformation to (generally a coregistered
        functional)
...
    transforms: (an existing file name)
...
```

It looks like this is happening in `nipype.interfaces.base.BaseInterface._get_trait_desc`, which tries to set each input to `None` and then harvests a description of what it _should_ have been set to from the ensuing exception's `info` attribute.  Unfortunately, this happens:

``` python
In [1]: import nipype.interfaces.ants as ants

In [2]: import pdb

In [3]: pdb.run('ants.ApplyTransforms.help()')
> <string>(1)<module>()
(Pdb) b nipype/interfaces/base:740, name in ('input_image', 'transforms')
Breakpoint 1 at /home/schwabacher/.local/lib/python2.6/site-packages/nipype/interfaces/base.py:740
(Pdb) c
> /home/schwabacher/.local/lib/python2.6/site-packages/nipype/interfaces/base.py(740)_get_trait_desc()
-> def_val = ''
(Pdb) p excp
TraitError("The 'input_image' trait of an ApplyTransformsInputSpec instance must be an existing file name, but a value of None <type 'NoneType'> was specified.",)
(Pdb) p excp.info
'an existing file name'
(Pdb) c
> /home/schwabacher/.local/lib/python2.6/site-packages/nipype/interfaces/base.py(740)_get_trait_desc()
-> def_val = ''
(Pdb) p excp
TraitError("Each element of the 'transforms' trait of an ApplyTransformsInputSpec instance must be an existing file name, but a value of None <type 'NoneType'> was specified.",)
(Pdb) p excp.info
'an existing file name'
```

(The breakpoint is set at [line 763 of current master](https://github.com/nipy/nipype/blob/551904589359d6c50ea47280b788cc94ed5ae733/nipype/interfaces/base.py#L763))

I'm not sure how best to handle this, since I'm not optimistic about finding the perfect snippet of text in the traits package, but I hope it doesn't get forgotten in #755.



Discussion:

Resolving patch:
diff --git a/nipype/interfaces/base.py b/nipype/interfaces/base.py
--- a/nipype/interfaces/base.py
+++ b/nipype/interfaces/base.py
@@ -757,17 +757,12 @@ def _get_trait_desc(self, inputs, name, spec):
 
         manhelpstr = ['\t%s' % name]
 
-        try:
-            setattr(inputs, name, None)
-        except TraitError as excp:
-            def_val = ''
-            if getattr(spec, 'usedefault'):
-                def_arg = getattr(spec, 'default_value')()[1]
-                def_val = ', nipype default value: %s' % str(def_arg)
-            line = "(%s%s)" % (excp.info, def_val)
-            manhelpstr = wrap(line, 70,
-                              initial_indent=manhelpstr[0]+': ',
-                              subsequent_indent='\t\t ')
+        type_info = spec.full_info(inputs, name, None) 
+        default = ', nipype default value: %s' % spec.default_value()[1]
+        line = "(%s%s)" % (type_info, default if spec.usedefault else '')
+        manhelpstr = wrap(line, 70, 
+                          initial_indent=manhelpstr[0]+': ',
+                          subsequent_indent='\t\t ')
 
         if desc:
             for line in desc.split('\n'):


Test patch: