Issue #21697: shutil.copytree() now correctly handles symbolic links that point to directories.

Patch by Eduardo Seabra and Thomas Kluyver.
This commit is contained in:
Berker Peksag 2015-07-25 14:55:32 +03:00
commit 882667203c
3 changed files with 28 additions and 1 deletions

View File

@ -327,7 +327,11 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
if not os.path.exists(linkto) and ignore_dangling_symlinks: if not os.path.exists(linkto) and ignore_dangling_symlinks:
continue continue
# otherwise let the copy occurs. copy2 will raise an error # 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): elif os.path.isdir(srcname):
copytree(srcname, dstname, symlinks, ignore, copy_function) copytree(srcname, dstname, symlinks, ignore, copy_function)
else: else:

View File

@ -901,6 +901,26 @@ class TestShutil(unittest.TestCase):
shutil.copytree(src_dir, dst_dir, symlinks=True) shutil.copytree(src_dir, dst_dir, symlinks=True)
self.assertIn('test.txt', os.listdir(dst_dir)) 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): def _copy_file(self, method):
fname = 'test.txt' fname = 'test.txt'
tmpdir = self.mkdtemp() tmpdir = self.mkdtemp()

View File

@ -57,6 +57,9 @@ Core and Builtins
Library 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 - Issue #14373: Fixed segmentation fault when gc.collect() is called during
constructing lru_cache (C implementation). constructing lru_cache (C implementation).