Skip to content

Commit 5405950

Browse files
authored
Merge pull request #3061 from effigies/fix/results_file
FIX: Minimize scope for directory changes while loading results file
2 parents 085767c + 39806c6 commit 5405950

File tree

1 file changed

+36
-24
lines changed

1 file changed

+36
-24
lines changed

nipype/utils/filemanip.py

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -699,37 +699,49 @@ def loadpkl(infile):
699699
infile = Path(infile)
700700
fmlogger.debug('Loading pkl: %s', infile)
701701
pklopen = gzip.open if infile.suffix == '.pklz' else open
702+
703+
with SoftFileLock('%s.lock' % infile):
704+
with pklopen(str(infile), 'rb') as pkl_file:
705+
pkl_contents = pkl_file.read()
706+
702707
pkl_metadata = None
703708

709+
# Look if pkl file contains version metadata
710+
idx = pkl_contents.find(b'\n')
711+
if idx >= 0:
712+
try:
713+
pkl_metadata = json.loads(pkl_contents[:idx])
714+
except (UnicodeDecodeError, json.JSONDecodeError):
715+
# Could not get version info
716+
pass
717+
else:
718+
# On success, skip JSON metadata
719+
pkl_contents = pkl_contents[idx + 1:]
720+
721+
# Pickle files may contain relative paths that must be resolved relative
722+
# to the working directory, so use indirectory while attempting to load
704723
unpkl = None
705-
with indirectory(infile.parent):
706-
with SoftFileLock('%s.lock' % infile.name):
707-
with pklopen(infile.name, 'rb') as pkl_file:
708-
try: # Look if pkl file contains version file
709-
pkl_metadata_line = pkl_file.readline()
710-
pkl_metadata = json.loads(pkl_metadata_line)
711-
except (UnicodeDecodeError, json.JSONDecodeError):
712-
# Could not get version info
713-
pkl_file.seek(0)
714-
try:
715-
unpkl = pickle.load(pkl_file)
716-
except UnicodeDecodeError:
717-
# Was this pickle created with Python 2.x?
718-
unpkl = pickle.load(pkl_file, fix_imports=True, encoding='utf-8')
719-
fmlogger.info('Successfully loaded pkl in compatibility mode.')
720-
# Unpickling problems
721-
except Exception as e:
722-
if pkl_metadata and 'version' in pkl_metadata:
723-
from nipype import __version__ as version
724-
if pkl_metadata['version'] != version:
725-
fmlogger.error("""\
724+
try:
725+
with indirectory(infile.parent):
726+
unpkl = pickle.loads(pkl_contents)
727+
except UnicodeDecodeError:
728+
# Was this pickle created with Python 2.x?
729+
with indirectory(infile.parent):
730+
unpkl = pickle.loads(pkl_contents, fix_imports=True, encoding='utf-8')
731+
fmlogger.info('Successfully loaded pkl in compatibility mode.')
732+
# Unpickling problems
733+
except Exception as e:
734+
if pkl_metadata and 'version' in pkl_metadata:
735+
from nipype import __version__ as version
736+
if pkl_metadata['version'] != version:
737+
fmlogger.error("""\
726738
Attempted to open a results file generated by Nipype version %s, \
727739
with an incompatible Nipype version (%s)""", pkl_metadata['version'], version)
728-
raise e
729-
fmlogger.warning("""\
740+
raise e
741+
fmlogger.warning("""\
730742
No metadata was found in the pkl file. Make sure you are currently using \
731743
the same Nipype version from the generated pkl.""")
732-
raise e
744+
raise e
733745

734746
if unpkl is None:
735747
raise ValueError('Loading %s resulted in None.' % infile)

0 commit comments

Comments
 (0)