@@ -204,10 +204,10 @@ def _check_requires(self, spec, name, value):
204
204
]
205
205
if any (values ) and isdefined (value ):
206
206
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. "
208
208
"For a list of required inputs, see %s.help()" )
209
209
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. "
211
211
"For a list of required inputs, see %s.help()" )
212
212
msg = fmt % (self .__class__ .__name__ ,
213
213
', ' .join ("'%s'" % req for req in spec .requires ),
@@ -450,34 +450,36 @@ def _list_outputs(self):
450
450
return None
451
451
452
452
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
480
458
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
481
483
return outputs
482
484
483
485
@property
0 commit comments