Skip to content

Commit 251362e

Browse files
committed
MAINT: Refactor aggregate_outputs for readability
1 parent 3454c9a commit 251362e

File tree

1 file changed

+30
-29
lines changed

1 file changed

+30
-29
lines changed

nipype/interfaces/base/core.py

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,10 @@ def _check_requires(self, spec, name, value):
204204
]
205205
if any(values) and isdefined(value):
206206
if len(values) > 1:
207-
fmt = ("%s requires values for inputs %s because '%s' is set. "
207+
fmt = ("%s requires values for inputs %s because '%s' is set. "
208208
"For a list of required inputs, see %s.help()")
209209
else:
210-
fmt = ("%s requires a value for input %s because '%s' is set. "
210+
fmt = ("%s requires a value for input %s because '%s' is set. "
211211
"For a list of required inputs, see %s.help()")
212212
msg = fmt % (self.__class__.__name__,
213213
', '.join("'%s'" % req for req in spec.requires),
@@ -450,34 +450,35 @@ def _list_outputs(self):
450450
return None
451451

452452
def aggregate_outputs(self, runtime=None, needed_outputs=None):
453-
""" Collate expected outputs and check for existence
454-
"""
455-
456-
predicted_outputs = self._list_outputs()
457-
outputs = self._outputs()
458-
if predicted_outputs:
459-
_unavailable_outputs = []
460-
if outputs:
461-
_unavailable_outputs = \
462-
self._check_version_requirements(self._outputs())
463-
for key, val in list(predicted_outputs.items()):
464-
if needed_outputs and key not in needed_outputs:
465-
continue
466-
if key in _unavailable_outputs:
467-
raise KeyError(('Output trait %s not available in version '
468-
'%s of interface %s. Please inform '
469-
'developers.') % (key, self.version,
470-
self.__class__.__name__))
471-
try:
472-
setattr(outputs, key, val)
473-
except TraitError as error:
474-
if getattr(error, 'info',
475-
'default').startswith('an existing'):
476-
msg = ("File/Directory '%s' not found for %s output "
477-
"'%s'." % (val, self.__class__.__name__, key))
478-
raise FileNotFoundError(msg)
479-
raise error
453+
"""Collate expected outputs and apply output traits validation."""
454+
outputs = self._outputs() # Generate an empty output spec object
455+
predicted_outputs = self._list_outputs() # Predictions from _list_outputs
456+
if not predicted_outputs:
457+
return outputs
480458

459+
# Precalculate the list of output trait names that should be aggregated
460+
aggregate_names = set(predicted_outputs.keys())
461+
if needed_outputs is not None:
462+
aggregate_names = set(needed_outputs).intersection(aggregate_names)
463+
464+
if aggregate_names: # Make sure outputs are compatible
465+
_na_outputs = self._check_version_requirements(outputs)
466+
na_names = aggregate_names.intersection(set(_na_outputs))
467+
if na_names:
468+
raise TypeError("""\
469+
Output trait(s) %s not available in version %s of interface %s.\
470+
""" % (', '.join(na_names), self.version, self.__class__.__name__))
471+
472+
for key in aggregate_names: # Final aggregation
473+
val = predicted_outputs[key]
474+
try:
475+
setattr(outputs, key, val)
476+
except TraitError as error:
477+
if 'an existing' in getattr(error, 'info', 'default'):
478+
msg = "No such file or directory for output '%s' of a %s interface" % \
479+
(key, self.__class__.__name__)
480+
raise FileNotFoundError(val, message=msg)
481+
raise error
481482
return outputs
482483

483484
@property

0 commit comments

Comments
 (0)