This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Bug in shutil.copytree on Windows
Type: Stage:
Components: Library (Lib) Versions: Python 2.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: loewis, michael.foord
Priority: normal Keywords:

Created on 2006-07-20 13:00 by michael.foord, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (5)
msg29224 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2006-07-20 13:00
The problem is that the call to 'copystat(src, dst)'
was added to the shutil.copytree function, in svn
r38363 probably.  It will fail always on Windows, since
os.utime does not work on directories.

I guess that a patch similar to this one should fix it:

Index: shutil.py
===================================================================
--- shutil.py	(Revision 50710)
+++ shutil.py	(Arbeitskopie)
@@ -127,7 +127,12 @@
         # continue with other files
         except Error, err:
             errors.extend(err.args[0])
-    copystat(src, dst)
+    try:
+        copystat(src, dst)
+    except WindowsError:
+        pass
+    except OSError, err:
+        errors.extend(err.args[0])
     if errors:
         raise Error, errors
msg29225 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2006-07-20 16:14
Logged In: YES 
user_id=21627

Can you also come up with a patch to the test suite?
msg29226 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2006-07-28 14:09
Logged In: YES 
user_id=1123892

The following should work as a test method for shutil.copytree

(Passes on my box against a patched version of shutil)

    def test_copytree_simple(self):
        src_dir = tempfile.mkdtemp()
        dst_dir = os.path.join(tempfile.mkdtemp(),
'destination')
        open(os.path.join(src_dir, 'test.txt'),
'w').write('123')
        os.mkdir(os.path.join(src_dir, 'test_dir'))
        open(os.path.join(src_dir, 'test_dir', 'test.txt'),
'w').write('456')
        #
        def testStat(src, dst):
            st_src = os.stat(src)
            st_dst = os.stat(dst)
            if hasattr(os, 'utime'):
                self.assertEqual((st_src.st_atime,
st_src.st_mtime), (st_dst.st_atime, st_dst.st_mtime))
            if hasattr(os, 'chmod'):
                # Should be equal anyway, should we change
permissions on one of the source files ?
               
self.assertEqual(stat.S_IMODE(st_src.st_mode),
stat.S_IMODE(st_dst.st_mode))
        #
        try:
            shutil.copytree(src_dir, dst_dir)
           
self.assertTrue(os.path.isfile(os.path.join(dst_dir,
'test.txt')))
           
self.assertTrue(os.path.isdir(os.path.join(dst_dir,
'test_dir')))
           
self.assertTrue(os.path.isfile(os.path.join(dst_dir,
'test_dir', 'test.txt')))
            self.assertEqual(open(os.path.join(dst_dir,
'test.txt')).read(), '123')
            self.assertEqual(open(os.path.join(dst_dir,
'test_dir', 'test.txt')).read(), '456')
           
        finally:
            try:
                os.remove(os.path.join(src_dir, 'test.txt'))
                os.remove(os.path.join(dst_dir, 'test.txt'))
                os.remove(os.path.join(src_dir, 'test_dir',
'test.txt'))
                os.remove(os.path.join(dst_dir, 'test_dir',
'test.txt'))
                os.removedirs(src_dir)
                os.removedirs(dst_dir)
            except:
                pass

Can turn the above into a patch tonight if needed.
msg29227 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2006-07-28 14:14
Logged In: YES 
user_id=1123892

Nope - not quite right. Will fix tonight and upload a proper
patch.

Michael
msg29228 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2006-07-30 13:01
Logged In: YES 
user_id=21627

Thanks for the patch. Committed as r50977.
History
Date User Action Args
2022-04-11 14:56:19adminsetgithub: 43701
2006-07-20 13:00:44mjfoordcreate