Repository navigation
Conversation
merge_tree documents that it overwrites existing contents, but a second sync with symlinks=True raises FileExistsError. Remove the destination first so re-merging a tree with links succeeds. Fixes jaraco#263
|
I checked this against base import os
import tempfile
from path import Path
with tempfile.TemporaryDirectory() as temp:
root = Path(temp)
src = root / 'src'
src.mkdir()
Path('missing-target').symlink(src / 'link')
alias = root / 'alias'
src.symlink(alias)
try:
src.merge_tree(alias, symlinks=True)
except OSError as exc:
print(type(exc).__name__)
print(os.path.lexists(src / 'link'))Base prints Self-copy need not become supported; rejecting source/destination directory identity before any mutation would preserve the current failure-without-source-loss behavior. A regression test should cover a directory alias, not just equal path strings. I have not run Windows tests or the project's complete tox matrix; this is a focused Linux reproduction, not a claim that every merge path is affected. AI-assisted investigation and draft; independently reproduced in a second isolated check. |
|
Thanks for catching this. Fixed in 4045346: merge_tree now checks directory identity with samefile before creating the destination or changing any entries, and raises SameFileError for self-copies, including directory symlink aliases. Added four regressions covering direct and aliased destinations with valid and dangling symlinks. All four fail on the previous head and pass with the fix. The 14 merge_tree tests pass, and the full tests plus module doctests pass on macOS with Python 3.10.21 and 3.12.11 (150 passed, 1 skipped each). Formatting and diff checks also pass. The upstream OS/Python CI matrix has not been run locally. |
|
Verified I also ran your exact |
Summary
merge_tree(..., symlinks=True)is documented to overwrite existing destination contents, and regular files already do that viacopy2. Destination symlinks were created withos.symlinkand were not replaced, so a second merge of the same tree (or a merge onto a dest that already has that name as a file/directory) raisedFileExistsError.Replace the destination first, then recreate the link.
Fixes #263
Test plan
tests/test_path.py::TestMergeTree::test_overwrite_existing_symlinkfails on current main (FileExistsError) and passes on this branchTestMergeTreecases still pass (PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest tests/test_path.py::TestMergeTree)tests/suite: 112 passed, 8 skipped