[IO] Fix rootcp --replace flag not working with recursive copy#20344
[IO] Fix rootcp --replace flag not working with recursive copy#20344ahmedbilal9 wants to merge 9 commits intoroot-project:masterfrom
Conversation
|
Thank you very much for your PR! Could you fix the Python syntax errors? Thanks. |
674d1cb to
4c59740
Compare
|
The CI failures appear to be unrelated to my changes. The build is failing with: Error: roofit/hs3/src/RooJSONFactoryWSTool.cxx:260:1: error: '{anonymous}::Var::Var' defined but not used [-Werror=unused-function] This error is in C++ RooFit code, while my changes only modify main/python/cmdLineUtils.py. The Python linting checks (ruff) pass successfully. Could a maintainer please advise if this is a known issue or if I should rebase on the latest master? |
Test Results 21 files 21 suites 3d 19h 12m 22s ⏱️ For more details on these failures, see this check. Results for commit 9d29b5b. ♻️ This comment has been updated with latest results. |
|
Hi @bellenot, I've fixed the Python linting errors as requested. The However, the CI is failing with an error in RooFit code that appears unrelated to my changes: Could you advise if:
Thank you for your guidance! |
|
Hi @ahmedbilal9 I see failures like: And not the one with RooFit |
Hi @bellenot, Thank you for clarifying! I see now - the failures are in the roottest-main-SimpleRootmv tests, not the RooFit code. I'll investigate these test failures:
Could you point me to where I can find the detailed CI logs for these tests, or should I look at the full CI output? I want to understand what specific behavior is failing so I can fix it properly. Thank you! |
|
|
Summary
Local checks
Scope
|
|
Hi @guitargeek, I hope you’re doing well. I wanted to follow up on my pull request #20344 ([IO] Fix rootcp --replace flag not working with recursive copy) which I opened recently. Summary of the change:
Status:
Could you please let me know if there is anything else you need from me to move this forward (additional tests, rebase, or further adjustments)? I’d be happy to add a minimal roottest if that would help. Thanks for your time and review, |
7854805 to
8e23b75
Compare
When copying non-tree objects recursively, the --replace flag was checking for 'setName' instead of the actual object name that would be written. This caused objects to be written with new cycles instead of replacing existing ones. The fix determines the actual name (setName if provided, otherwise objectName) and uses that for the replacement check. Fixes root-project#7052
114b21d to
f387a14
Compare
|
I'd like to mention that this PR may become not mergeable as-is if this gets merged (or anyway will be de facto undone if it's merged before it), since the linked PR completely removes It is still a useful reference to make sure that the C++ version of rootcp doesn't have the same issue, so it's by no means wasted work. Edit: also, it's probably still gonna benefit |
This test verifies that the --replace flag works correctly when copying objects recursively. It ensures objects are replaced (cycle 1) rather than creating new cycles when re-copying with --replace -r. This test will help ensure the C++ implementation doesn't have the same issue when rootcp.py is replaced.
Thanks for the feedback! I've added a test in roottest/main/CMakeLists.txt that verifies the --replace flag works correctly with recursive copies. The test ensures objects are replaced (cycle 1) rather than creating duplicate cycles when using --replace -r. This should help verify the C++ implementation doesn't have the same bug when rootcp.py is replaced. Let me know if you'd like any adjustments to the test! |
|
@ahmedbilal9 your latest commit does not compile. Please test all your changes locally before pushing them. |
| ######################################################################### | ||
|
|
||
| ############################# ROOMV TESTS ############################ | ||
| ROOTTEST_ADD_TEST(SimpleRootmv1PrepareInput | ||
| COMMAND ${PY_TOOLS_PREFIX}/rootcp${pyext} --recreate -r test.root move1.root | ||
| FIXTURES_SETUP main-SimpleRootmv1PrepareInput-fixture) |
There was a problem hiding this comment.
Question: was there a reason to remove this?
Was this Copilot again?
|
Hi @ferdymercury, I've pushed the fixes - added the missing SimpleRootmv1PrepareInput fixture and the section header. Sorry about that, it was a mistake when I was reorganizing the tests. I wanted to mention that I'm really passionate about this work. I'm currently preparing for the CERN Summer Student Program and CERN Openlab applications, and contributing to ROOT has been such a great learning experience for me. I'm still a student, so I do take help from my seniors and sometimes use Copilot when I get stuck. I've been working really hard on this - honestly spent way too many late nights on it! The mistakes were genuinely unintentional, I was just trying to clean things up and missed those dependencies. Thanks for taking the time to review and guide me through this. I really appreciate your patience, and I'm learning a lot from your feedback. |
Co-authored-by: ferdymercury <ferdymercury@users.noreply.github.com>
|
Hi @ferdymercury, I've fixed the duplicate test issue in commit a65caee. The SimpleRootmv1PrepareInput test is now only at line 396 as you suggested, and I've removed the duplicate that was at line 433-438. Sorry for the confusion earlier - I should have been more careful when manually applying your suggestion. I've verified the structure is correct now. What should I do next to move this PR forward? |
| ######################################################################### | ||
|
|
||
| ############################# ROOMV TESTS ############################ | ||
| ############################# ROOTMV TESTS ############################ |
There was a problem hiding this comment.
It might be a good opportunity to fix also the other typos:
search for "TESTS ##" throughout the file
and add the T after ROO when missing.
There was a problem hiding this comment.
I agree, but please do so in a separate commit or in a separate PR, whichever you prefer.
vepadulano
left a comment
There was a problem hiding this comment.
Thanks! Some comments before running the CI
| ROOTTEST_ADD_TEST(RootcpReplaceRecursive | ||
| COMMAND ${PY_TOOLS_PREFIX}/rootcp${pyext} --replace -r copy_replace_recursive.root:tof copy_replace_recursive.root:tof | ||
| FIXTURES_REQUIRED main-RootcpReplaceRecursivePrepareInput-fixture |
There was a problem hiding this comment.
This test verifies that the --replace flag works correctly for in-place recursive copies. It copies from copy_replace_recursive.root:tof to the same location to ensure objects are replaced without creating new cycles (;2, ;3, etc.). The RootcpReplaceRecursiveCheckOutput test then verifies only cycle ;1 exists for each object, confirming replacement worked as intended.
| ######################################################################### | ||
|
|
||
| ############################# ROOMV TESTS ############################ | ||
| ############################# ROOTMV TESTS ############################ |
There was a problem hiding this comment.
I agree, but please do so in a separate commit or in a separate PR, whichever you prefer.
main/python/cmdLineUtils.py
Outdated
| retcodeTemp = deleteObject(destFile, destPathSplit + [actualName]) | ||
| if retcodeTemp: | ||
| retcode += retcodeTemp | ||
| obj.Delete() |
There was a problem hiding this comment.
Something not super clear to me: we call deleteObject, then we also call obj.Delete conditionally, why the apparently double delete?
There was a problem hiding this comment.
deleteObject() returns 0 on success and non-zero on failure. When deletion fails (retcodeTemp != 0), we track the error by adding to retcode, then call obj.Delete() to clean up the ROOT object in memory that we read earlier, and skip writing since we cannot replace an object that failed to delete. The obj.Delete() is for memory cleanup, not related to the file deletion.
…KDIR->ROOTMKDIR, ROOCP->ROOTCP
Fixes #7052
Changes or fixes:
The --replace flag was not being checked when copying regular objects (non-tree, non-collection) in recursive mode. This caused objects to be written with new cycles instead of replacing existing ones.
Added replaceOption check in the else block of copyRootObjectRecursive() to delete existing objects before writing replacements.
Checklist: