[Python-checkins] cpython (merge 3.5 -> default): Issue #21697: shutil.copytree() now correctly handles symbolic links that point

berker.peksag python-checkins at python.org
Sat Jul 25 13:56:16 CEST 2015


https://hg.python.org/cpython/rev/8f65be73eb3a
changeset:   97064:8f65be73eb3a
parent:      97061:9b17df697a3c
parent:      97063:31f4041b9286
user:        Berker Peksag <berker.peksag at gmail.com>
date:        Sat Jul 25 14:55:32 2015 +0300
summary:
  Issue #21697: shutil.copytree() now correctly handles symbolic links that point to directories.

Patch by Eduardo Seabra and Thomas Kluyver.

files:
  Lib/shutil.py           |   6 +++++-
  Lib/test/test_shutil.py |  20 ++++++++++++++++++++
  Misc/NEWS               |   3 +++
  3 files changed, 28 insertions(+), 1 deletions(-)


diff --git a/Lib/shutil.py b/Lib/shutil.py
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -327,7 +327,11 @@
                     if not os.path.exists(linkto) and ignore_dangling_symlinks:
                         continue
                     # otherwise let the copy occurs. copy2 will raise an error
-                    copy_function(srcname, dstname)
+                    if os.path.isdir(srcname):
+                        copytree(srcname, dstname, symlinks, ignore,
+                                 copy_function)
+                    else:
+                        copy_function(srcname, dstname)
             elif os.path.isdir(srcname):
                 copytree(srcname, dstname, symlinks, ignore, copy_function)
             else:
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -901,6 +901,26 @@
         shutil.copytree(src_dir, dst_dir, symlinks=True)
         self.assertIn('test.txt', os.listdir(dst_dir))
 
+    @support.skip_unless_symlink
+    def test_copytree_symlink_dir(self):
+        src_dir = self.mkdtemp()
+        dst_dir = os.path.join(self.mkdtemp(), 'destination')
+        os.mkdir(os.path.join(src_dir, 'real_dir'))
+        with open(os.path.join(src_dir, 'real_dir', 'test.txt'), 'w'):
+            pass
+        os.symlink(os.path.join(src_dir, 'real_dir'),
+                   os.path.join(src_dir, 'link_to_dir'),
+                   target_is_directory=True)
+
+        shutil.copytree(src_dir, dst_dir, symlinks=False)
+        self.assertFalse(os.path.islink(os.path.join(dst_dir, 'link_to_dir')))
+        self.assertIn('test.txt', os.listdir(os.path.join(dst_dir, 'link_to_dir')))
+
+        dst_dir = os.path.join(self.mkdtemp(), 'destination2')
+        shutil.copytree(src_dir, dst_dir, symlinks=True)
+        self.assertTrue(os.path.islink(os.path.join(dst_dir, 'link_to_dir')))
+        self.assertIn('test.txt', os.listdir(os.path.join(dst_dir, 'link_to_dir')))
+
     def _copy_file(self, method):
         fname = 'test.txt'
         tmpdir = self.mkdtemp()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -57,6 +57,9 @@
 Library
 -------
 
+- Issue #21697: shutil.copytree() now correctly handles symbolic links that
+  point to directories.  Patch by Eduardo Seabra and Thomas Kluyver.
+
 - Issue #14373: Fixed segmentation fault when gc.collect() is called during
   constructing lru_cache (C implementation).
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list