diff -r 66a3dc613627 Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py Sun Jul 28 02:57:02 2013 +0200 +++ b/Lib/test/test_shutil.py Sun Jul 28 20:40:03 2013 -0400 @@ -727,6 +727,31 @@ shutil.rmtree(src_dir) shutil.rmtree(os.path.dirname(dst_dir)) + def test_copytree_retains_permissions(self): + src_dir = tempfile.mkdtemp() + dst_dir = os.path.join(tempfile.mkdtemp(), 'destination') + self.addCleanup(shutil.rmtree, src_dir) + self.addCleanup(shutil.rmtree, os.path.dirname(dst_dir)) + + os.chmod(src_dir, 0o777) + write_file((src_dir, 'permissive.txt'), '123') + os.chmod(os.path.join(src_dir, 'permissive.txt'), 0o777) + write_file((src_dir, 'restrictive.txt'), '456') + os.chmod(os.path.join(src_dir, 'restrictive.txt'), 0o600) + restrictive_subdir = tempfile.mkdtemp(dir=src_dir) + os.chmod(restrictive_subdir, 0o600) + + shutil.copytree(src_dir, dst_dir) + self.assertEquals(os.stat(src_dir).st_mode, os.stat(dst_dir).st_mode) + self.assertEquals(os.stat(os.path.join(src_dir, 'permissive.txt')).st_mode, + os.stat(os.path.join(dst_dir, 'permissive.txt')).st_mode) + self.assertEquals(os.stat(os.path.join(src_dir, 'restrictive.txt')).st_mode, + os.stat(os.path.join(dst_dir, 'restrictive.txt')).st_mode) + restrictive_subdir_dst = os.path.join(dst_dir, + os.path.split(restrictive_subdir)[1]) + self.assertEquals(os.stat(restrictive_subdir).st_mode, + os.stat(restrictive_subdir_dst).st_mode) + @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') def test_dont_copy_file_onto_link_to_itself(self): # Temporarily disable test on Windows.