[Python-checkins] [3.8] bpo-39390 shutil: fix argument types for ignore callback (GH-18122)
Giampaolo Rodola
webhook-mailer at python.org
Mon Jan 27 18:46:34 EST 2020
https://github.com/python/cpython/commit/cf9d00554715febf21cf94950da4f42723b80498
commit: cf9d00554715febf21cf94950da4f42723b80498
branch: 3.8
author: mbarkhau <mbarkhau at gmail.com>
committer: Giampaolo Rodola <g.rodola at gmail.com>
date: 2020-01-28T00:46:29+01:00
summary:
[3.8] bpo-39390 shutil: fix argument types for ignore callback (GH-18122)
files:
A Misc/NEWS.d/next/Library/2020-01-23-21-34-29.bpo-39390.D2tSXk.rst
M Doc/whatsnew/3.8.rst
M Lib/shutil.py
M Lib/test/test_shutil.py
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 7bc91a9fc19bf..007e3228f9ae6 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -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`.)
diff --git a/Lib/shutil.py b/Lib/shutil.py
index 755ce392e6d9a..cde7b860050a2 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -442,7 +442,7 @@ def _ignore_patterns(path, names):
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()
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index 286e333a8aa9c..bcb7e498e198e 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -880,6 +880,48 @@ def _filter(src, names):
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')
diff --git a/Misc/NEWS.d/next/Library/2020-01-23-21-34-29.bpo-39390.D2tSXk.rst b/Misc/NEWS.d/next/Library/2020-01-23-21-34-29.bpo-39390.D2tSXk.rst
new file mode 100644
index 0000000000000..ffa961ea4cd22
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-01-23-21-34-29.bpo-39390.D2tSXk.rst
@@ -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.
More information about the Python-checkins
mailing list