Repository: nipy/nipype

Issue:
UnboundLocalError: local variable 'module_name' referenced before assignment
### Summary
Discovered for myself `nipypecli` and decided to give it a try while composing cmdline invocation just following the errors it was spitting out at me and stopping when error didn't give a hint what I could have specified incorrectly:

```
$> nipypecli convert boutiques -m nipype.interfaces.ants.registration -i ANTS -o test
Traceback (most recent call last):
  File "/usr/bin/nipypecli", line 11, in <module>
    load_entry_point('nipype==1.0.1', 'console_scripts', 'nipypecli')()
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/nipype/scripts/cli.py", line 254, in boutiques
    verbose, ignore_template_numbers)
  File "/usr/lib/python2.7/dist-packages/nipype/utils/nipype2boutiques.py", line 56, in generate_boutiques_descriptor
    'command-line'] = "nipype_cmd " + module_name + " " + interface_name + " "
UnboundLocalError: local variable 'module_name' referenced before assignment
```



Discussion:

Resolving patch:
diff --git a/nipype/utils/nipype2boutiques.py b/nipype/utils/nipype2boutiques.py
--- a/nipype/utils/nipype2boutiques.py
+++ b/nipype/utils/nipype2boutiques.py
@@ -2,7 +2,7 @@
 from __future__ import (print_function, division, unicode_literals,
                         absolute_import)
 
-from builtins import str, open
+from builtins import str, open, bytes
 # This tool exports a Nipype interface in the Boutiques (https://github.com/boutiques) JSON format.
 # Boutiques tools can be imported in CBRAIN (https://github.com/aces/cbrain) among other platforms.
 #
@@ -40,10 +40,12 @@ def generate_boutiques_descriptor(
         raise Exception("Undefined module.")
 
     # Retrieves Nipype interface
-    if isinstance(module, str):
+    if isinstance(module, (str, bytes)):
         import_module(module)
         module_name = str(module)
         module = sys.modules[module]
+    else:
+        module_name = str(module.__name__)
 
     interface = getattr(module, interface_name)()
     inputs = interface.input_spec()
@@ -249,7 +251,7 @@ def create_tempfile():
     Creates a temp file and returns its name.
     '''
     fileTemp = tempfile.NamedTemporaryFile(delete=False)
-    fileTemp.write("hello")
+    fileTemp.write(b"hello")
     fileTemp.close()
     return fileTemp.name
 
@@ -283,6 +285,8 @@ def must_generate_value(name, type, ignored_template_inputs, spec_info, spec,
     # Best guess to detect string restrictions...
     if "' or '" in spec_info:
         return False
+    if spec.default or spec.default_value():
+        return False
     if not ignored_template_inputs:
         return True
     return not (name in ignored_template_inputs)


Test patch:
diff --git a/nipype/utils/tests/test_nipype2boutiques.py b/nipype/utils/tests/test_nipype2boutiques.py
new file mode 100644
--- /dev/null
+++ b/nipype/utils/tests/test_nipype2boutiques.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
+# vi: set ft=python sts=4 ts=4 sw=4 et:
+from future import standard_library
+standard_library.install_aliases()
+
+from ..nipype2boutiques import generate_boutiques_descriptor
+
+
+def test_generate():
+    generate_boutiques_descriptor(module='nipype.interfaces.ants.registration',
+                                  interface_name='ANTS',
+                                  ignored_template_inputs=(),
+                                  docker_image=None,
+                                  docker_index=None,
+                                  verbose=False,
+                                  ignore_template_numbers=False)