-
Notifications
You must be signed in to change notification settings - Fork 533
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Workflow crashing with file not found due to strange nipype.pipeline.engine.utils.modify_path behavior #2944
Comments
For added context, running the provided script produces the following error:
Further, this was introduced in #2325, due to the saving/loading of the resultfile. I suspect the fact that we're losing trait information is the problem. Still trying to work through whether the correct response is the fix proposed in #2945. |
I'm not sure this is a problem of nipype - although I acknowledge there could be potential file name collisions conducive to this problem and we may want to keep track of existing files in the results file. I'll wait on the original fMRIPrep issue to understand the problem. |
I'm pretty sure this is a nipype issue and not an fmriprep issue. The above example does not rely on fmriprep, and definitely results in undesirable behavior. I agree with @effigies that the main issue is loss of type information, and trying to recover that information, so #2945 is probably not an ideal solution. |
I can only imagine two situations where this is an issue:
For that reason, I think we should first replicate and identify the error condition in fMRIPrep and then decide whether it is worth tracking file traits. WDYT @satra? |
The example script I posted doesn't satisfy either criteria, but still causes an issue. To cause this issue all that is required is:
|
Gotcha, I hadn't realized of number 2. Well, I guess then #2945 should address this issue. |
One question I have is why we're modifying paths in the resultfile. |
It is a buggy filter to convert paths to relative (before storing) and then back to absolute (after loading). |
Sure, but why? |
I would imagine (and that was there before my refactor) that it is to make the result file work even if you move the work directory somewhere else. For a single run (no reuse), I agree it doesn't make much sense. @satra may have a better understanding of this. |
@oesteban and @effigies - this should be controlled through a config option: https://github.com/nipy/nipype/blob/master/nipype/utils/config.py#L65 but it sounds like the option is not being implemented properly. the default is |
I think that's being handled inside nipype/nipype/pipeline/engine/utils.py Lines 490 to 496 in 1eeabd3
The problem is that we're identifying paths as strings that exist on the filesystem relative to some directory (either CWD or node-WD), which can sometimes be true for |
@effigies - in other situations we check the traits metadata to determine if this is a string vs a file. ( |
Yes, but this is operating on a dict, without trait information. I'm working on a strategy to pass in traits as type hints.
Could you clarify? Are you suggesting to use |
@effigies - i simply meant altering the traits_extension File class to either return a string or a pathlib object depending on the traits metadata. |
I've looked at the traits stuff, and have decided I don't really know how to start. Just noting this, in case somebody else has time to play with traits. |
Having a look right this minute |
@satra the new trait would return pathlike if |
@oesteban - the metadata already exists, so the validate function in the |
i would start with updating the |
Sorry, I was very unclear. Please check the draft PR above - I was actually modifying |
@satra, the metadata name is |
the metadata name is |
Building a solution to nipy#2944, starting from a refactor of ``aggregate_outputs`` to be robuster and perform the referrencing when requested via the new arguiment ``rebase_cwd``.
Two new methods ``resolve_path_traits`` and ``rebase_path_traits`` are being included. They take trait instances from a spec (selected via ``spec.trait('traitname')``, the value and a base path. These two functions will be usefull to progress towards nipy#2944.
Two new methods ``resolve_path_traits`` and ``rebase_path_traits`` are being included. They take trait instances from a spec (selected via ``spec.trait('traitname')``, the value and a base path. These two functions will be usefull to progress towards nipy#2944.
Two new methods ``resolve_path_traits`` and ``rebase_path_traits`` are being included. They take trait instances from a spec (selected via ``spec.trait('traitname')``, the value and a base path. These two functions will be usefull to progress towards nipy#2944.
Two new methods ``resolve_path_traits`` and ``rebase_path_traits`` are being included. They take trait instances from a spec (selected via ``spec.trait('traitname')``, the value and a base path. These two functions will be usefull to progress towards nipy#2944.
Two new methods ``resolve_path_traits`` and ``rebase_path_traits`` are being included. They take trait instances from a spec (selected via ``spec.trait('traitname')``, the value and a base path. These two functions will be usefull to progress towards nipy#2944.
Once we figure out the problem of ``OutputMultiObject``, we could go ahead and set fix nipy#2944, fix nipreps/fmriprep#1674, close nipy#2945.
It seems that nipy#2944 has uncovered a rats-nest hidden in the engine. In resolving that issue, I found out that a great deal of boilerplate was set in place when loading/saving results to deal with ``OutputMulti{Object,Path}`` traits. The reason being that these traits flatten single-element-list values. This PR fixes the pickling behavior of traited specs containing these types of traits. Additionally, this PR also avoids the ``modify_paths`` function that was causing problems originally in nipy#2944. Therefore, this PR effectively make results files static, meaning: caching if the ``base_dir`` of the workflow is changed will not work anymore. I plan to re-insert this feature (results file mobility) with nipy#2971. This PR is just to split that one in more digestible bits. All the boilerplate mentioned above has been cleaned up.
Once we figure out the problem of ``OutputMultiObject``, we could go ahead and set fix nipy#2944, fix nipreps/fmriprep#1674, close nipy#2945.
Once we figure out the problem of ``OutputMultiObject``, we could go ahead and set fix nipy#2944, fix nipreps/fmriprep#1674, close nipy#2945.
Once we figure out the problem of ``OutputMultiObject``, we could go ahead and set fix nipy#2944, fix nipreps/fmriprep#1674, close nipy#2945.
Summary
When getting the node results, the
modify_path
function will mistakenly identify some outputs as files, causing the run to fail.Actual behavior
Workflow crashes with a file not found error due to output being mistakenly identified as a file. This occurs when the output is a string (or bytes? untested), and a file with the same name exists in the current working directory.
Expected behavior
modify_path
does not identify the object as a file.How to replicate the behavior
See below
Script/Workflow details
The following script will fail if there is a file named "22" in the directory from which it is called.
Please put URL to code or code here (if not too long).
Platform details:
Execution environment
The text was updated successfully, but these errors were encountered: