Skip to content

Commit 2e98dad

Browse files
committed
FIX: Disallow returning None in pipeline.utils.load_resultfile
Prevents #3009 and #3014 from happening - although this might not solve those issues, this patch will help find their origin by making ``load_resultfile`` more strict (and letting it raise exceptions). The try .. except structure is moved to the only place is was being used within the Node code.
1 parent 0470641 commit 2e98dad

File tree

2 files changed

+44
-52
lines changed

2 files changed

+44
-52
lines changed

nipype/pipeline/engine/nodes.py

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ def interface(self):
195195
def result(self):
196196
"""Get result from result file (do not hold it in memory)"""
197197
return _load_resultfile(
198-
op.join(self.output_dir(), 'result_%s.pklz' % self.name))[0]
198+
op.join(self.output_dir(), 'result_%s.pklz' % self.name))
199199

200200
@property
201201
def inputs(self):
@@ -518,7 +518,7 @@ def _get_inputs(self):
518518
logger.debug('input: %s', key)
519519
results_file = info[0]
520520
logger.debug('results file: %s', results_file)
521-
outputs = _load_resultfile(results_file)[0].outputs
521+
outputs = _load_resultfile(results_file).outputs
522522
if outputs is None:
523523
raise RuntimeError("""\
524524
Error populating the input "%s" of node "%s": the results file of the source node \
@@ -565,34 +565,42 @@ def _run_interface(self, execute=True, updatehash=False):
565565

566566
def _load_results(self):
567567
cwd = self.output_dir()
568-
result, aggregate, attribute_error = _load_resultfile(
569-
op.join(cwd, 'result_%s.pklz' % self.name))
568+
569+
try:
570+
result = _load_resultfile(
571+
op.join(cwd, 'result_%s.pklz' % self.name))
572+
except (traits.TraitError, EOFError):
573+
logger.debug(
574+
'Error populating inputs/outputs, (re)aggregating results...')
575+
except (AttributeError, ImportError) as err:
576+
logger.debug('attribute error: %s probably using '
577+
'different trait pickled file', str(err))
578+
old_inputs = loadpkl(op.join(cwd, '_inputs.pklz'))
579+
self.inputs.trait_set(**old_inputs)
580+
else:
581+
return result
582+
570583
# try aggregating first
571-
if aggregate:
572-
logger.debug('aggregating results')
573-
if attribute_error:
574-
old_inputs = loadpkl(op.join(cwd, '_inputs.pklz'))
575-
self.inputs.trait_set(**old_inputs)
576-
if not isinstance(self, MapNode):
577-
self._copyfiles_to_wd(linksonly=True)
578-
aggouts = self._interface.aggregate_outputs(
579-
needed_outputs=self.needed_outputs)
580-
runtime = Bunch(
581-
cwd=cwd,
582-
returncode=0,
583-
environ=dict(os.environ),
584-
hostname=socket.gethostname())
585-
result = InterfaceResult(
586-
interface=self._interface.__class__,
587-
runtime=runtime,
588-
inputs=self._interface.inputs.get_traitsfree(),
589-
outputs=aggouts)
590-
_save_resultfile(
591-
result, cwd, self.name,
592-
rebase=str2bool(self.config['execution']['use_relative_paths']))
593-
else:
594-
logger.debug('aggregating mapnode results')
595-
result = self._run_interface()
584+
if not isinstance(self, MapNode):
585+
self._copyfiles_to_wd(linksonly=True)
586+
aggouts = self._interface.aggregate_outputs(
587+
needed_outputs=self.needed_outputs)
588+
runtime = Bunch(
589+
cwd=cwd,
590+
returncode=0,
591+
environ=dict(os.environ),
592+
hostname=socket.gethostname())
593+
result = InterfaceResult(
594+
interface=self._interface.__class__,
595+
runtime=runtime,
596+
inputs=self._interface.inputs.get_traitsfree(),
597+
outputs=aggouts)
598+
_save_resultfile(
599+
result, cwd, self.name,
600+
rebase=str2bool(self.config['execution']['use_relative_paths']))
601+
else:
602+
logger.debug('aggregating mapnode results')
603+
result = self._run_interface()
596604
return result
597605

598606
def _run_command(self, execute, copyfiles=True):

nipype/pipeline/engine/utils.py

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@
3838
write_rst_header,
3939
write_rst_dict,
4040
write_rst_list,
41+
FileNotFoundError,
4142
)
4243
from ...utils.misc import str2bool
4344
from ...utils.functions import create_function_from_source
4445
from ...interfaces.base.traits_extension import (
45-
rebase_path_traits, resolve_path_traits, OutputMultiPath, isdefined, Undefined, traits)
46+
rebase_path_traits, resolve_path_traits, OutputMultiPath, isdefined, Undefined)
4647
from ...interfaces.base.support import Bunch, InterfaceResult
4748
from ...interfaces.base import CommandLine
4849
from ...interfaces.utility import IdentityInterface
@@ -281,38 +282,22 @@ def load_resultfile(results_file, resolve=True):
281282
Returns
282283
-------
283284
result : InterfaceResult structure
284-
aggregate : boolean indicating whether node should aggregate_outputs
285-
attribute error : boolean indicating whether there was some mismatch in
286-
versions of traits used to store result and hence node needs to
287-
rerun
288285
289286
"""
290287
results_file = Path(results_file)
291-
aggregate = True
292-
result = None
293-
attribute_error = False
294288

295289
if not results_file.exists():
296-
return result, aggregate, attribute_error
290+
raise FileNotFoundError(results_file)
297291

298292
with indirectory(str(results_file.parent)):
299-
try:
300-
result = loadpkl(results_file)
301-
except (traits.TraitError, EOFError):
302-
logger.debug(
303-
'some file does not exist. hence trait cannot be set')
304-
except (AttributeError, ImportError) as err:
305-
attribute_error = True
306-
logger.debug('attribute error: %s probably using '
307-
'different trait pickled file', str(err))
308-
else:
309-
aggregate = False
293+
result = loadpkl(results_file)
310294

311295
if resolve and result.outputs:
312296
try:
313297
outputs = result.outputs.get()
314298
except TypeError: # This is a Bunch
315-
return result, aggregate, attribute_error
299+
logger.debug('Outputs object of loaded result %s is a Bunch.', results_file)
300+
return result
316301

317302
logger.debug('Resolving paths in outputs loaded from results file.')
318303
for trait_name, old in list(outputs.items()):
@@ -323,8 +308,7 @@ def load_resultfile(results_file, resolve=True):
323308
value = resolve_path_traits(result.outputs.trait(trait_name), old,
324309
results_file.parent)
325310
setattr(result.outputs, trait_name, value)
326-
327-
return result, aggregate, attribute_error
311+
return result
328312

329313

330314
def strip_temp(files, wd):

0 commit comments

Comments
 (0)