fix: symlink to directory "has older modification time" than target (#3782) #3784
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds a Snakemake workflow that creates Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
tests/test_github_issue3687/Snakefile (1)
18-27: Consider ensuring parent directory exists.The code creates a symlink at
dir2/D, but the parent directorydir2is not explicitly created. While Snakemake may handle parent directory creation for outputs automatically, consider adding explicit parent creation for robustness:run: + Path(str(output)).parent.mkdir(parents=True, exist_ok=True) Path(str(output)).symlink_to(f'../{input}')Alternatively, verify that Snakemake's test framework handles this automatically.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
tests/test_github_issue3687/Snakefile(1 hunks)tests/test_github_issue3687/expected-results/dir2/D(1 hunks)
🔇 Additional comments (4)
tests/test_github_issue3687/expected-results/dir2/D (1)
1-1: LGTM! Expected symlink target is correct.The expected symlink target
../dir1/Dcorrectly matches what the Snakefile produces in thelink_to_Drule (line 27).tests/test_github_issue3687/Snakefile (3)
3-5: LGTM! Standard target rule.The
allrule correctly specifies the final workflow target.
1-27: Please paste the content of GitHub issue #3687 so I can confirm that this test setup accurately reproduces the reported behavior.
8-15: Ensure directory output is created before touch.Path.touch()doesn’t create parent directories—confirm that Snakemake’sdirectory('dir1/D')output is instantiated before therunblock or explicitly callPath(output.file).parent.mkdir(parents=True, exist_ok=True)beforetouch().
|
You need to add the test to |
|
@fgvieira : I'm looking at the |
|
Is it sufficent to just do the following? |
|
Yes, add that code to trigger the test and, if you have output, also include them in the test under an |
|
The test is being triggered now, but there seems to be something wrong. 😄 |
Yeah... I don't think there is a fix out yet for the bug that this tests. I added this test case at the behest of @johanneskoester: |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/snakemake/io/__init__.py (1)
587-599: Preserve the originalstat()failure via exception chaining.These branches now add useful context, but they still discard the original
FileNotFoundError/PermissionError, which makes symlink-vs-target failures harder to diagnose. Please capture the exception andraise WorkflowError(...) from ehere.♻️ Proposed change
- except FileNotFoundError: + except FileNotFoundError as e: if self.is_storage: return Mtime(storage=mtime_in_storage) raise WorkflowError( f"Unable to obtain modification time of file {file} although it existed before. " "It could be that a concurrent process has deleted it while Snakemake " "was running." - ) - except PermissionError: + ) from e + except PermissionError as e: raise WorkflowError( f"Unable to obtain modification time of file {file} because of missing " "read permissions." - ) + ) from eBased on learnings: "In the snakemake codebase, use exception chaining (raise NewError(...) from original) to preserve the original exception context when re-raising or wrapping exceptions in Python files."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/snakemake/io/__init__.py` around lines 587 - 599, The except handlers that wrap FileNotFoundError and PermissionError should preserve the original exception via exception chaining: capture the original exception (e) in both except blocks and re-raise WorkflowError(...) using "raise WorkflowError(... ) from e" so the original stat() failure context is kept; update the FileNotFoundError handler (the branch that returns Mtime(storage=mtime_in_storage) when self.is_storage, otherwise raises WorkflowError about modification time of file variable file) and the PermissionError handler (which raises WorkflowError about missing read permissions) to use "from e" when re-raising.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/snakemake/io/__init__.py`:
- Around line 587-599: The except handlers that wrap FileNotFoundError and
PermissionError should preserve the original exception via exception chaining:
capture the original exception (e) in both except blocks and re-raise
WorkflowError(...) using "raise WorkflowError(... ) from e" so the original
stat() failure context is kept; update the FileNotFoundError handler (the branch
that returns Mtime(storage=mtime_in_storage) when self.is_storage, otherwise
raises WorkflowError about modification time of file variable file) and the
PermissionError handler (which raises WorkflowError about missing read
permissions) to use "from e" when re-raising.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a90cdcd7-ddfb-4d61-adbd-7225fa885cc9
📒 Files selected for processing (2)
src/snakemake/io/__init__.pytests/tests.py
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/tests.py
|
Waiting for a second test case here by @Hocnonsense to test whether the fix in snakemake/snakemake-interface-storage-plugins#87 sufficiently addressed the issue. |
|
The second test case is added and passed after |
🤖 I have created a release *beep* *boop* --- ## [9.22.0](v9.21.1...v9.22.0) (2026-06-01) ### Features * add semantic helper functions choose_file/choose_folder/choose_tmp and allow all semantic helper functions to be used when parsing resources ([#3820](#3820)) ([d3c2386](d3c2386)) * add temp to default pathvars ([#4108](#4108)) ([917fb11](917fb11)) * add workflow info to log ([#4079](#4079)) ([e40e15b](e40e15b)) * support python 3.14 ([#3739](#3739)) ([7e3be0c](7e3be0c)) ### Bug Fixes * Adapt for dataclasses._MISSING_TYPE replaced with sentinel in Python 3.15 ([#4211](#4211)) ([b7fb8df](b7fb8df)) * ensure that storage is not actually retrieved with --touch ([#4212](#4212)) ([2726cae](2726cae)) * symlink to directory "has older modification time" than target ([#3782](#3782)) ([#3784](#3784)) ([41903d8](41903d8)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
This is a test case for the problem described in #3687.
QC
docs/) is updated to reflect the changes or this is not necessary (e.g. if the change does neither modify the language nor the behavior or functionalities of Snakemake).Summary by CodeRabbit
Tests
Bug Fixes