[Python-checkins] bpo-35652: shutil.copytree(copy_function=...) erroneously pass DirEntry instead of path str (GH-11997)

Giampaolo Rodola webhook-mailer at python.org
Tue Feb 26 06:04:48 EST 2019


https://github.com/python/cpython/commit/c606a9cbd48f69d3f4a09204c781dda9864218b7
commit: c606a9cbd48f69d3f4a09204c781dda9864218b7
branch: master
author: Giampaolo Rodola <g.rodola at gmail.com>
committer: GitHub <noreply at github.com>
date: 2019-02-26T12:04:41+01:00
summary:

bpo-35652: shutil.copytree(copy_function=...) erroneously pass DirEntry instead of path str (GH-11997)

files:
A Misc/NEWS.d/next/Library/2019-02-26-11-34-44.bpo-35652.6KRJu_.rst
M Lib/shutil.py
M Lib/test/test_shutil.py

diff --git a/Lib/shutil.py b/Lib/shutil.py
index 1f98a348d7e6..9b50c2a9833a 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -472,7 +472,7 @@ def _copytree(entries, src, dst, symlinks, ignore, copy_function,
                          dirs_exist_ok=dirs_exist_ok)
             else:
                 # Will raise a SpecialFileError for unsupported file types
-                copy_function(srcentry, dstname)
+                copy_function(srcobj, dstname)
         # catch the Error from the recursive copytree so that we can
         # continue with other files
         except Error as err:
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index ceafaeda1dc2..678a190bcf5e 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -859,6 +859,24 @@ def test_copytree_winerror(self, mock_patch):
         with self.assertRaises(shutil.Error):
             shutil.copytree(src_dir, dst_dir)
 
+    def test_copytree_custom_copy_function(self):
+        # See: https://bugs.python.org/issue35648
+        def custom_cpfun(a, b):
+            flag.append(None)
+            self.assertIsInstance(a, str)
+            self.assertIsInstance(b, str)
+            self.assertEqual(a, os.path.join(src, 'foo'))
+            self.assertEqual(b, os.path.join(dst, 'foo'))
+
+        flag = []
+        src = tempfile.mkdtemp()
+        dst = tempfile.mktemp()
+        self.addCleanup(shutil.rmtree, src)
+        with open(os.path.join(src, 'foo'), 'w') as f:
+            f.close()
+        shutil.copytree(src, dst, copy_function=custom_cpfun)
+        self.assertEqual(len(flag), 1)
+
     @unittest.skipIf(os.name == 'nt', 'temporarily disabled on Windows')
     @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
     def test_dont_copy_file_onto_link_to_itself(self):
diff --git a/Misc/NEWS.d/next/Library/2019-02-26-11-34-44.bpo-35652.6KRJu_.rst b/Misc/NEWS.d/next/Library/2019-02-26-11-34-44.bpo-35652.6KRJu_.rst
new file mode 100644
index 000000000000..c247e1706a33
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-02-26-11-34-44.bpo-35652.6KRJu_.rst
@@ -0,0 +1,2 @@
+shutil.copytree(copy_function=...) erroneously pass DirEntry instead of a
+path string.



More information about the Python-checkins mailing list