|
25 | 25 |
|
26 | 26 | from ... import logging, config, LooseVersion
|
27 | 27 | from ...utils.filemanip import (
|
| 28 | + indirectory, |
28 | 29 | relpath,
|
29 | 30 | makedirs,
|
30 | 31 | fname_presuffix,
|
|
40 | 41 | )
|
41 | 42 | from ...utils.misc import str2bool
|
42 | 43 | from ...utils.functions import create_function_from_source
|
| 44 | +from ...interfaces.base.traits_extension import rebase_path_traits, resolve_path_traits |
43 | 45 | from ...interfaces.base import (Bunch, CommandLine, isdefined, Undefined,
|
44 | 46 | InterfaceResult, traits)
|
45 | 47 | from ...interfaces.utility import IdentityInterface
|
@@ -226,59 +228,88 @@ def write_report(node, report_type=None, is_mapnode=False):
|
226 | 228 | return
|
227 | 229 |
|
228 | 230 |
|
229 |
| -def save_resultfile(result, cwd, name): |
230 |
| - """Save a result pklz file to ``cwd``""" |
| 231 | +def save_resultfile(result, cwd, name, rebase=True): |
| 232 | + """Save a result pklz file to ``cwd``.""" |
| 233 | + cwd = os.path.abspath(cwd) |
231 | 234 | resultsfile = os.path.join(cwd, 'result_%s.pklz' % name)
|
232 |
| - savepkl(resultsfile, result) |
233 |
| - logger.debug('saved results in %s', resultsfile) |
| 235 | + logger.debug("Saving results file: '%s'", resultsfile) |
234 | 236 |
|
| 237 | + if result.outputs is None: |
| 238 | + logger.warn('Storing result file without outputs') |
| 239 | + savepkl(resultsfile, result) |
| 240 | + return |
235 | 241 |
|
236 |
| -def load_resultfile(path, name): |
| 242 | + try: |
| 243 | + outputs = result.outputs.trait_get() |
| 244 | + except AttributeError: |
| 245 | + logger.debug('Storing non-traited results, skipping rebase of paths') |
| 246 | + savepkl(resultsfile, result) |
| 247 | + return |
| 248 | + |
| 249 | + try: |
| 250 | + with indirectory(cwd): |
| 251 | + # All the magic to fix #2944 resides here: |
| 252 | + for key, val in list(outputs.items()): |
| 253 | + val = rebase_path_traits(result.outputs.trait(key), val, cwd) |
| 254 | + setattr(result.outputs, key, val) |
| 255 | + savepkl(resultsfile, result) |
| 256 | + finally: |
| 257 | + # Reset resolved paths from the outputs dict no matter what |
| 258 | + for key, val in list(outputs.items()): |
| 259 | + setattr(result.outputs, key, val) |
| 260 | + |
| 261 | + |
| 262 | +def load_resultfile(path, name, resolve=True): |
237 | 263 | """
|
238 |
| - Load InterfaceResult file from path |
| 264 | + Load InterfaceResult file from path. |
239 | 265 |
|
240 | 266 | Parameter
|
241 | 267 | ---------
|
242 |
| -
|
243 | 268 | path : base_dir of node
|
244 | 269 | name : name of node
|
245 | 270 |
|
246 | 271 | Returns
|
247 | 272 | -------
|
248 |
| -
|
249 | 273 | result : InterfaceResult structure
|
250 | 274 | aggregate : boolean indicating whether node should aggregate_outputs
|
251 | 275 | attribute error : boolean indicating whether there was some mismatch in
|
252 | 276 | versions of traits used to store result and hence node needs to
|
253 | 277 | rerun
|
| 278 | +
|
254 | 279 | """
|
255 | 280 | aggregate = True
|
256 |
| - resultsoutputfile = os.path.join(path, 'result_%s.pklz' % name) |
257 | 281 | result = None
|
258 | 282 | attribute_error = False
|
259 |
| - if os.path.exists(resultsoutputfile): |
260 |
| - pkl_file = gzip.open(resultsoutputfile, 'rb') |
| 283 | + resultsoutputfile = os.path.join(path, 'result_%s.pklz' % name) |
| 284 | + if not os.path.exists(resultsoutputfile): |
| 285 | + return result, aggregate, attribute_error |
| 286 | + |
| 287 | + with indirectory(path): |
| 288 | + pkl_file = gzip.open('result_%s.pklz' % name, 'rb') |
261 | 289 | try:
|
262 | 290 | result = pickle.load(pkl_file)
|
263 | 291 | except UnicodeDecodeError:
|
264 | 292 | # Was this pickle created with Python 2.x?
|
265 |
| - pickle.load(pkl_file, fix_imports=True, encoding='utf-8') |
266 |
| - logger.warning('Successfully loaded pkl in compatibility mode') |
267 |
| - except (traits.TraitError, AttributeError, ImportError, |
268 |
| - EOFError) as err: |
269 |
| - if isinstance(err, (AttributeError, ImportError)): |
270 |
| - attribute_error = True |
271 |
| - logger.debug('attribute error: %s probably using ' |
272 |
| - 'different trait pickled file', str(err)) |
273 |
| - else: |
274 |
| - logger.debug( |
275 |
| - 'some file does not exist. hence trait cannot be set') |
| 293 | + result = pickle.load(pkl_file, fix_imports=True, encoding='utf-8') |
| 294 | + logger.warning('Successfully loaded pkl in compatibility mode.') |
| 295 | + except (traits.TraitError, EOFError): |
| 296 | + logger.debug( |
| 297 | + 'some file does not exist. hence trait cannot be set') |
| 298 | + except (AttributeError, ImportError) as err: |
| 299 | + attribute_error = True |
| 300 | + logger.debug('attribute error: %s probably using ' |
| 301 | + 'different trait pickled file', str(err)) |
276 | 302 | else:
|
277 | 303 | aggregate = False
|
278 | 304 | finally:
|
279 | 305 | pkl_file.close()
|
280 | 306 |
|
281 |
| - logger.debug('Aggregate: %s', aggregate) |
| 307 | + if resolve and not aggregate: |
| 308 | + logger.debug('Resolving paths in outputs loaded from results file.') |
| 309 | + for trait_name, old_value in list(result.outputs.get().items()): |
| 310 | + value = resolve_path_traits(result.outputs.trait(trait_name), old_value, path) |
| 311 | + setattr(result.outputs, trait_name, value) |
| 312 | + |
282 | 313 | return result, aggregate, attribute_error
|
283 | 314 |
|
284 | 315 |
|
|
0 commit comments