Skip to content

gh-156210: Fix shutil.copytree() detection of dangling relative symlinks - #156214

Open
lpyu001 wants to merge 1 commit into
python:mainfrom
lpyu001:shutil
Open

gh-156210: Fix shutil.copytree() detection of dangling relative symlinks#156214
lpyu001 wants to merge 1 commit into
python:mainfrom
lpyu001:shutil

Conversation

@lpyu001

@lpyu001 lpyu001 commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

shutil.copytree() used the raw result of os.readlink() to determine whether a symbolic link was dangling when ignore_dangling_symlinks=True. Relative targets were therefore checked against the current working directory instead of the link's parent directory.

This could cause valid relative symbolic links to be skipped, or dangling links to be copied when the current working directory contained a matching path.

The check now uses the source link path, allowing the target to be resolved from the correct directory. Regression tests cover both cases.

@lpyu001
lpyu001 requested a review from giampaolo as a code owner August 22, 2026 03:12
@lpyu001 lpyu001 changed the title gh-156210: Fix shutil.copytree() detection of dangling relative symlinks gh-156210: Fix shutil.copytree() detection of dangling relative symlinks Aug 22, 2026

@picnixz picnixz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is correct. Please explain why you used srcname instead of linkto. AFAICT, the problem is linkto is the incorrect file (because readlink() resolves according to PWD and not to src).

Otherwise, I wonder whether this is deliberate and instead should be documented.

Comment thread Lib/shutil.py
else:
# ignore dangling symlink if the flag is on
if not os.path.exists(linkto) and ignore_dangling_symlinks:
if not os.path.exists(srcname) and ignore_dangling_symlinks:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is correct though? srcname is the the symlink file. However, we want to resolve the relative symlink with respect to src, that is, we read the symlink content and then check if the file exists. The problem is therefore not here but rather the computation of "linkto". Instead, we should readlink(srcname) by interpreting srcname's content as relative to the src rather than PWD.

@bedevere-app

bedevere-app Bot commented Aug 22, 2026

Copy link
Copy Markdown

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants