This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: shutil.copytree() handles symbolic directory incorrectly
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.6, Python 3.4, Python 3.5
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: berker.peksag Nosy List: Björn.Dahlgren, Eduardo.Seabra, berker.peksag, ned.deily, puppet, python-dev, shajunxing, takluyver
Priority: normal Keywords: easy, patch

Created on 2014-06-09 13:19 by shajunxing, last changed 2022-04-11 14:58 by admin. This issue is now closed.

File name Uploaded Description Edit
截图 - 2014年06月09日 - 21时14分13秒.png shajunxing, 2014-06-09 13:19 source code screenshot
issue21697.diff berker.peksag, 2014-06-13 11:22 review
issue21697.diff Eduardo.Seabra, 2014-06-16 20:46 review
shutil_copytree_symlink_dir.patch takluyver, 2015-07-10 21:44 Patch including test review
Messages (9)
msg220088 - (view) Author: Shajunxing (shajunxing) Date: 2014-06-09 13:19
While using shutil.copytree() and the source containing symbolic directory (not symbolic file), an error will be raised. I checked the source code and found an obvlous mistake: shutil.copytree() using os.path.islink() to checker whether the source is a symbolic link, it's okay, but after doing this, os.path.isdir() should be called because a symbolic link may either be a file or a directry, shutil.copytree() just treated all of them as file, and invoke copy_function to copy it, so error happens.

I don't know whether newer versions have fixed this bug, but I googled it and found nothing.
msg220112 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2014-06-09 19:32
Thanks for the report. The bug is still present in the 3.4 and default (what will become the 3.5 release) branches; the 3.3 branch now only accepts security fixes.  2.7 does not fail.  Would you be interested in producing a patch for the problem?
msg220431 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2014-06-13 11:22
Here's a patch. I'm getting the following error without modify Lib/

ERROR: test_copytree_symbolic_directory (test.test_shutil.TestShutil)
Traceback (most recent call last):
  File "/home/berker/projects/cpython-default/Lib/test/", line 650, in test_copytree_symbolic_directory
    shutil.copytree(src_dir, dst_dir)
  File "/home/berker/projects/cpython-default/Lib/", line 342, in copytree
    raise Error(errors)
shutil.Error: [('/tmp/tmpiy30_34s/src/link', '/tmp/tmpiy30_34s/dst/link', "[Errno 21] Is a directory: '/tmp/tmpiy30_34s/src/link'")]
msg220758 - (view) Author: Eduardo Seabra (Eduardo.Seabra) * Date: 2014-06-16 20:46
Berker Peksag, I don't think your patch is okay.
When symlinks is set to true, it should copy the symbolic link of the directory. Your code is calling copytree instead.
I think the following patch is working, no errors on regression tests.
msg224546 - (view) Author: Daniel Eriksson (puppet) * Date: 2014-08-02 10:44
I have tested both patches on CentOS 6.4 and Eduardo Seabra:s patch works correctly with symlinks=True
msg232870 - (view) Author: Björn Dahlgren (Björn.Dahlgren) Date: 2014-12-18 11:12
I ran across this bug too. Applying Eduardo's patch got my package
working under Py 3.4
msg246587 - (view) Author: Thomas Kluyver (takluyver) * Date: 2015-07-10 21:44
Here's my patch (I submitted the duplicate issue). I think it's functionally the same as Eduardo's, but it also adds a test.
msg247347 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015-07-25 11:56
New changeset e807f1d81cb6 by Berker Peksag in branch '3.4':
Issue #21697: shutil.copytree() now correctly handles symbolic links that point to directories.

New changeset 31f4041b9286 by Berker Peksag in branch '3.5':
Issue #21697: shutil.copytree() now correctly handles symbolic links that point to directories.

New changeset 8f65be73eb3a by Berker Peksag in branch 'default':
Issue #21697: shutil.copytree() now correctly handles symbolic links that point to directories.
msg247348 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2015-07-25 11:58
Thanks for the patches and testing!
Date User Action Args
2022-04-11 14:58:04adminsetgithub: 65896
2015-07-25 11:58:17berker.peksagsetstatus: open -> closed
resolution: fixed
messages: + msg247348

stage: patch review -> resolved
2015-07-25 11:56:18python-devsetnosy: + python-dev
messages: + msg247347
2015-07-10 21:44:01takluyversetfiles: + shutil_copytree_symlink_dir.patch

messages: + msg246587
2015-07-10 21:41:41berker.peksaglinkissue24609 superseder
2015-07-10 21:41:32berker.peksagsetassignee: berker.peksag

nosy: + takluyver
versions: + Python 3.6
2014-12-18 11:12:33Björn.Dahlgrensetnosy: + Björn.Dahlgren
messages: + msg232870
2014-08-02 10:44:37puppetsetnosy: + puppet
messages: + msg224546
2014-06-16 20:46:07Eduardo.Seabrasetfiles: + issue21697.diff
nosy: + Eduardo.Seabra
messages: + msg220758

2014-06-13 11:22:21berker.peksagsetfiles: + issue21697.diff

nosy: + berker.peksag
messages: + msg220431

keywords: + patch
stage: needs patch -> patch review
2014-06-09 19:32:29ned.deilysetversions: + Python 3.4, Python 3.5, - Python 3.3
nosy: + ned.deily

messages: + msg220112

keywords: + easy
stage: needs patch
2014-06-09 13:19:19shajunxingcreate