|
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