diff -r 8befb15024b5 Lib/shutil.py --- a/Lib/shutil.py Fri Jul 10 22:26:44 2015 +0300 +++ b/Lib/shutil.py Fri Jul 10 16:15:43 2015 -0500 @@ -327,7 +327,11 @@ if not os.path.exists(linkto) and ignore_dangling_symlinks: continue # otherwise let the copy occurs. copy2 will raise an error - copy_function(srcname, dstname) + if os.path.isdir(srcname): + copytree(srcname, dstname, symlinks, ignore, + copy_function) + else: + copy_function(srcname, dstname) elif os.path.isdir(srcname): copytree(srcname, dstname, symlinks, ignore, copy_function) else: diff -r 8befb15024b5 Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py Fri Jul 10 22:26:44 2015 +0300 +++ b/Lib/test/test_shutil.py Fri Jul 10 16:15:43 2015 -0500 @@ -901,6 +901,26 @@ shutil.copytree(src_dir, dst_dir, symlinks=True) self.assertIn('test.txt', os.listdir(dst_dir)) + @support.skip_unless_symlink + def test_copytree_symlink_dir(self): + src_dir = self.mkdtemp() + dst_dir = os.path.join(self.mkdtemp(), 'destination') + os.mkdir(os.path.join(src_dir, 'real_dir')) + with open(os.path.join(src_dir, 'real_dir', 'test.txt'), 'w'): + pass + os.symlink(os.path.join(src_dir, 'real_dir'), + os.path.join(src_dir, 'link_to_dir'), + target_is_directory=True) + shutil.copytree(src_dir, dst_dir, symlinks=False) + + assert not os.path.islink(os.path.join(dst_dir, 'link_to_dir')) + self.assertIn("test.txt", os.listdir(os.path.join(dst_dir, 'link_to_dir'))) + + dst_dir = os.path.join(self.mkdtemp(), 'destination2') + shutil.copytree(src_dir, dst_dir, symlinks=True) + assert os.path.islink(os.path.join(dst_dir, 'link_to_dir')) + self.assertIn("test.txt", os.listdir(os.path.join(dst_dir, 'link_to_dir'))) + def _copy_file(self, method): fname = 'test.txt' tmpdir = self.mkdtemp()