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