@@ -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,36 @@ 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 )
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 (_na_outputs )
467+ if na_names :
468+ # XXX Change to TypeError in Nipype 2.0
469+ raise KeyError ("""\
470+ Output trait(s) %s not available in version %s of interface %s.\
471+ """ % (', ' .join (na_names ), self .version , self .__class__ .__name__ ))
472+
473+ for key in aggregate_names : # Final aggregation
474+ val = predicted_outputs [key ]
475+ try :
476+ setattr (outputs , key , val )
477+ except TraitError as error :
478+ if 'an existing' in getattr (error , 'info' , 'default' ):
479+ msg = "No such file or directory for output '%s' of a %s interface" % \
480+ (key , self .__class__ .__name__ )
481+ raise FileNotFoundError (val , message = msg )
482+ raise error
481483 return outputs
482484
483485 @property
0 commit comments