[3.8] bpo-39390 shutil: fix argument types for ignore callback (GH-18122)

This commit is contained in:
mbarkhau 2020-01-27 23:46:29 +00:00 committed by Giampaolo Rodola
parent 7b57b15bd8
commit cf9d005547
4 changed files with 52 additions and 1 deletions

View File

@ -2216,3 +2216,10 @@ because of the behavior of the socket option ``SO_REUSEADDR`` in UDP. For more
details, see the documentation for ``loop.create_datagram_endpoint()``.
(Contributed by Kyle Stanley, Antoine Pitrou, and Yury Selivanov in
:issue:`37228`.)
Notable changes in Python 3.8.2
===============================
Fixed a regression with the ``ignore`` callback of :func:`shutil.copytree`.
The argument types are now str and List[str] again.
(Contributed by Manuel Barkhau and Giampaolo Rodola in :issue:`39390`.)

View File

@ -442,7 +442,7 @@ def ignore_patterns(*patterns):
def _copytree(entries, src, dst, symlinks, ignore, copy_function,
ignore_dangling_symlinks, dirs_exist_ok=False):
if ignore is not None:
ignored_names = ignore(src, {x.name for x in entries})
ignored_names = ignore(os.fspath(src), [x.name for x in entries])
else:
ignored_names = set()

View File

@ -880,6 +880,48 @@ class TestShutil(unittest.TestCase):
shutil.rmtree(src_dir)
shutil.rmtree(os.path.dirname(dst_dir))
def test_copytree_arg_types_of_ignore(self):
join = os.path.join
exists = os.path.exists
tmp_dir = self.mkdtemp()
src_dir = join(tmp_dir, "source")
os.mkdir(join(src_dir))
os.mkdir(join(src_dir, 'test_dir'))
os.mkdir(os.path.join(src_dir, 'test_dir', 'subdir'))
write_file((src_dir, 'test_dir', 'subdir', 'test.txt'), '456')
invokations = []
def _ignore(src, names):
invokations.append(src)
self.assertIsInstance(src, str)
self.assertIsInstance(names, list)
self.assertEqual(len(names), len(set(names)))
for name in names:
self.assertIsInstance(name, str)
return []
dst_dir = join(self.mkdtemp(), 'destination')
shutil.copytree(src_dir, dst_dir, ignore=_ignore)
self.assertTrue(exists(join(dst_dir, 'test_dir', 'subdir',
'test.txt')))
dst_dir = join(self.mkdtemp(), 'destination')
shutil.copytree(pathlib.Path(src_dir), dst_dir, ignore=_ignore)
self.assertTrue(exists(join(dst_dir, 'test_dir', 'subdir',
'test.txt')))
dst_dir = join(self.mkdtemp(), 'destination')
src_dir_entry = list(os.scandir(tmp_dir))[0]
self.assertIsInstance(src_dir_entry, os.DirEntry)
shutil.copytree(src_dir_entry, dst_dir, ignore=_ignore)
self.assertTrue(exists(join(dst_dir, 'test_dir', 'subdir',
'test.txt')))
self.assertEqual(len(invokations), 9)
def test_copytree_retains_permissions(self):
tmp_dir = tempfile.mkdtemp()
src_dir = os.path.join(tmp_dir, 'source')

View File

@ -0,0 +1,2 @@
Fixed a regression with the `ignore` callback of :func:`shutil.copytree`.
The argument types are now str and List[str] again.