Repository: nipy/nipype

Issue:
Update to 1.0.1-dev broke master
Seems like building docs fails for one workflow (`nipype/workflows/smri/ants/ANTSBuildTemplate.py`). 

Apparently, the `ignore_exception` input should be dropped in favor of the new class attribute in interfaces. Before 1.0.0, nipype would only show a warning, but now after the version bump to 1.0.1-dev it raises an error (#2403).

We need to fix a couple of things:
  - [ ] Make sure no legacy code remains setting `interface.inputs.ignore_exception`
  - [ ] Make sure interfaces no longer support `ignore_exception` and `terminal_output` as inputs. In particular, double check with the `Function` interface.

https://circleci.com/gh/nipy/nipype/3178
https://circleci.com/gh/nipy/nipype/3176
https://circleci.com/gh/nipy/nipype/3172

```
Exception occurred in traits notification handler.
Please check the log file for details.
Exception occurred in traits notification handler for object: 
AffineTransformList = <undefined>
function_str = def MakeListsOfTransformLists(warpTransformList, AffineTransformList):
    return list(map(list, list(zip(warpTransformList, AffineTransformList))))

ignore_exception = True
warpTransformList = <undefined>
, trait: ignore_exception, old value: False, new value: True
Traceback (most recent call last):
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/traits/trait_notifiers.py", line 519, in _dispatch_change_event
    self.dispatch( handler, *args )
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/traits/trait_notifiers.py", line 482, in dispatch
    handler( *args )
  File "/src/nipype/nipype/interfaces/base/specs.py", line 140, in _deprecated_warn
    raise TraitError(msg)
traits.trait_errors.TraitError: Input ignore_exception in interface Function is deprecated. Will be removed or raise an error as of release 1.0.0 

180126-21:20:31,898 traits ERROR:
	 Exception occurred in traits notification handler for object: 
AffineTransformList = <undefined>
function_str = def MakeListsOfTransformLists(warpTransformList, AffineTransformList):
    return list(map(list, list(zip(warpTransformList, AffineTransformList))))

ignore_exception = True
warpTransformList = <undefined>
, trait: ignore_exception, old value: False, new value: True
Traceback (most recent call last):
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/traits/trait_notifiers.py", line 519, in _dispatch_change_event
    self.dispatch( handler, *args )
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/traits/trait_notifiers.py", line 482, in dispatch
    handler( *args )
  File "/src/nipype/nipype/interfaces/base/specs.py", line 140, in _deprecated_warn
    raise TraitError(msg)

traits.trait_errors.TraitError: Input ignore_exception in interface Function is deprecated. Will be removed or raise an error as of release 1.0.0 
Exception occurred in traits notification handler for object: 
averageAffineTranform = <undefined>
function_str = def MakeTransformListWithGradientWarps(averageAffineTranform,
                                       gradientStepWarp):
    return [
        averageAffineTranform, gradientStepWarp, gradientStepWarp,
        gradientStepWarp, gradientStepWarp
    ]

gradientStepWarp = <undefined>
ignore_exception = True
, trait: ignore_exception, old value: False, new value: True
Traceback (most recent call last):
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/traits/trait_notifiers.py", line 519, in_dispatch_change_event
    self.dispatch( handler, *args )
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/traits/trait_notifiers.py", line 482, in dispatch
    handler( *args )
  File "/src/nipype/nipype/interfaces/base/specs.py", line 140, in _deprecated_warn
    raise TraitError(msg)
traits.trait_errors.TraitError: Input ignore_exception in interface Function is deprecated. Will be removed or raise an error as of release 1.0.0 

180126-21:20:31,924 traits ERROR:
	 Exception occurred in traits notification handler for object: 
averageAffineTranform = <undefined>
function_str = def MakeTransformListWithGradientWarps(averageAffineTranform,
                                       gradientStepWarp):
    return [
        averageAffineTranform, gradientStepWarp, gradientStepWarp,
        gradientStepWarp, gradientStepWarp
    ]

gradientStepWarp = <undefined>
ignore_exception = True
, trait: ignore_exception, old value: False, new value: True
Traceback (most recent call last):
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/traits/trait_notifiers.py", line 519, in _dispatch_change_event
    self.dispatch( handler, *args )
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/traits/trait_notifiers.py", line 482, in dispatch
    handler( *args )
  File "/src/nipype/nipype/interfaces/base/specs.py", line 140, in _deprecated_warn
    raise TraitError(msg)

traits.trait_errors.TraitError: Input ignore_exception in interface Function is deprecated. Will be removed or raise an error as of release 1.0.0 
```


Discussion:
@oesteban - sorry, please ignore my comment in the other PR. you are correct that these should be moved to class level attributes.

Resolving patch:
diff --git a/nipype/interfaces/base/core.py b/nipype/interfaces/base/core.py
--- a/nipype/interfaces/base/core.py
+++ b/nipype/interfaces/base/core.py
@@ -170,12 +170,14 @@ class BaseInterface(Interface):
     references_ = []
     resource_monitor = True  # Enabled for this interface IFF enabled in the config
 
-    def __init__(self, from_file=None, resource_monitor=None, **inputs):
+    def __init__(self, from_file=None, resource_monitor=None,
+                 ignore_exception=False, **inputs):
         if not self.input_spec:
             raise Exception(
                 'No input_spec in class: %s' % self.__class__.__name__)
 
         self.inputs = self.input_spec(**inputs)
+        self.ignore_exception = ignore_exception
 
         if resource_monitor is not None:
             self.resource_monitor = resource_monitor
@@ -470,7 +472,6 @@ def run(self, cwd=None, **inputs):
         os.chdir(cwd)  # Change to the interface wd
 
         enable_rm = config.resource_monitor and self.resource_monitor
-        force_raise = not getattr(self.inputs, 'ignore_exception', False)
         self.inputs.trait_set(**inputs)
         self._check_mandatory_inputs()
         self._check_version_requirements(self.inputs)
@@ -530,7 +531,7 @@ def run(self, cwd=None, **inputs):
             runtime.traceback_args = ('\n'.join(
                 ['%s' % arg for arg in exc_args]), )
 
-            if force_raise:
+            if not self.ignore_exception:
                 raise
         finally:
             # This needs to be done always
diff --git a/nipype/workflows/smri/ants/ANTSBuildTemplate.py b/nipype/workflows/smri/ants/ANTSBuildTemplate.py
--- a/nipype/workflows/smri/ants/ANTSBuildTemplate.py
+++ b/nipype/workflows/smri/ants/ANTSBuildTemplate.py
@@ -183,7 +183,7 @@ def ANTSTemplateBuildSingleIterationWF(iterationPhasePrefix=''):
             output_names=['out']),
         run_without_submitting=True,
         name='MakeTransformsLists')
-    MakeTransformsLists.inputs.ignore_exception = True
+    MakeTransformsLists.interface.ignore_exception = True
     TemplateBuildSingleIterationWF.connect(
         BeginANTS, 'warp_transform', MakeTransformsLists, 'warpTransformList')
     TemplateBuildSingleIterationWF.connect(BeginANTS, 'affine_transform',
@@ -263,7 +263,7 @@ def ANTSTemplateBuildSingleIterationWF(iterationPhasePrefix=''):
             output_names=['TransformListWithGradientWarps']),
         run_without_submitting=True,
         name='MakeTransformListWithGradientWarps')
-    ApplyInvAverageAndFourTimesGradientStepWarpImage.inputs.ignore_exception = True
+    ApplyInvAverageAndFourTimesGradientStepWarpImage.interface.ignore_exception = True
 
     TemplateBuildSingleIterationWF.connect(
         AvgAffineTransform, 'affine_transform',
diff --git a/nipype/workflows/smri/ants/antsRegistrationBuildTemplate.py b/nipype/workflows/smri/ants/antsRegistrationBuildTemplate.py
--- a/nipype/workflows/smri/ants/antsRegistrationBuildTemplate.py
+++ b/nipype/workflows/smri/ants/antsRegistrationBuildTemplate.py
@@ -360,7 +360,7 @@ def antsRegistrationTemplateBuildSingleIterationWF(iterationPhasePrefix=''):
             output_names=['TransformListWithGradientWarps']),
         run_without_submitting=True,
         name='99_MakeTransformListWithGradientWarps')
-    ApplyInvAverageAndFourTimesGradientStepWarpImage.inputs.ignore_exception = True
+    ApplyInvAverageAndFourTimesGradientStepWarpImage.interface.ignore_exception = True
 
     TemplateBuildSingleIterationWF.connect(
         AvgAffineTransform, 'affine_transform',


Test patch: