mirror of https://github.com/python/cpython.git
bpo-38523: ignore_dangling_symlinks does not apply recursively (GH-22937)
(cherry picked from commit 5ff81da6d3
)
Co-authored-by: Zackery Spytz <zspytz@gmail.com>
This commit is contained in:
parent
ea2316a220
commit
eb0e942ca8
|
@ -487,12 +487,13 @@ def _copytree(entries, src, dst, symlinks, ignore, copy_function,
|
||||||
# otherwise let the copy occur. copy2 will raise an error
|
# otherwise let the copy occur. copy2 will raise an error
|
||||||
if srcentry.is_dir():
|
if srcentry.is_dir():
|
||||||
copytree(srcobj, dstname, symlinks, ignore,
|
copytree(srcobj, dstname, symlinks, ignore,
|
||||||
copy_function, dirs_exist_ok=dirs_exist_ok)
|
copy_function, ignore_dangling_symlinks,
|
||||||
|
dirs_exist_ok)
|
||||||
else:
|
else:
|
||||||
copy_function(srcobj, dstname)
|
copy_function(srcobj, dstname)
|
||||||
elif srcentry.is_dir():
|
elif srcentry.is_dir():
|
||||||
copytree(srcobj, dstname, symlinks, ignore, copy_function,
|
copytree(srcobj, dstname, symlinks, ignore, copy_function,
|
||||||
dirs_exist_ok=dirs_exist_ok)
|
ignore_dangling_symlinks, dirs_exist_ok)
|
||||||
else:
|
else:
|
||||||
# Will raise a SpecialFileError for unsupported file types
|
# Will raise a SpecialFileError for unsupported file types
|
||||||
copy_function(srcobj, dstname)
|
copy_function(srcobj, dstname)
|
||||||
|
|
|
@ -731,18 +731,25 @@ def _copy(src, dst):
|
||||||
|
|
||||||
@os_helper.skip_unless_symlink
|
@os_helper.skip_unless_symlink
|
||||||
def test_copytree_dangling_symlinks(self):
|
def test_copytree_dangling_symlinks(self):
|
||||||
# a dangling symlink raises an error at the end
|
|
||||||
src_dir = self.mkdtemp()
|
src_dir = self.mkdtemp()
|
||||||
|
valid_file = os.path.join(src_dir, 'test.txt')
|
||||||
|
write_file(valid_file, 'abc')
|
||||||
|
dir_a = os.path.join(src_dir, 'dir_a')
|
||||||
|
os.mkdir(dir_a)
|
||||||
|
for d in src_dir, dir_a:
|
||||||
|
os.symlink('IDONTEXIST', os.path.join(d, 'broken'))
|
||||||
|
os.symlink(valid_file, os.path.join(d, 'valid'))
|
||||||
|
|
||||||
|
# A dangling symlink should raise an error.
|
||||||
dst_dir = os.path.join(self.mkdtemp(), 'destination')
|
dst_dir = os.path.join(self.mkdtemp(), 'destination')
|
||||||
os.symlink('IDONTEXIST', os.path.join(src_dir, 'test.txt'))
|
|
||||||
os.mkdir(os.path.join(src_dir, 'test_dir'))
|
|
||||||
write_file((src_dir, 'test_dir', 'test.txt'), '456')
|
|
||||||
self.assertRaises(Error, shutil.copytree, src_dir, dst_dir)
|
self.assertRaises(Error, shutil.copytree, src_dir, dst_dir)
|
||||||
|
|
||||||
# a dangling symlink is ignored with the proper flag
|
# Dangling symlinks should be ignored with the proper flag.
|
||||||
dst_dir = os.path.join(self.mkdtemp(), 'destination2')
|
dst_dir = os.path.join(self.mkdtemp(), 'destination2')
|
||||||
shutil.copytree(src_dir, dst_dir, ignore_dangling_symlinks=True)
|
shutil.copytree(src_dir, dst_dir, ignore_dangling_symlinks=True)
|
||||||
self.assertNotIn('test.txt', os.listdir(dst_dir))
|
for root, dirs, files in os.walk(dst_dir):
|
||||||
|
self.assertNotIn('broken', files)
|
||||||
|
self.assertIn('valid', files)
|
||||||
|
|
||||||
# a dangling symlink is copied if symlinks=True
|
# a dangling symlink is copied if symlinks=True
|
||||||
dst_dir = os.path.join(self.mkdtemp(), 'destination3')
|
dst_dir = os.path.join(self.mkdtemp(), 'destination3')
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
:func:`shutil.copytree` now applies the *ignore_dangling_symlinks* argument
|
||||||
|
recursively.
|
Loading…
Reference in New Issue