@@ -1058,6 +1058,57 @@ def test_copytree_dangling_symlinks(self):
10581058        shutil .copytree (src_dir , dst_dir , symlinks = True )
10591059        self .assertIn ('test.txt' , os .listdir (dst_dir ))
10601060
1061+     @os_helper .skip_unless_symlink  
1062+     def  test_copytree_dangling_links_to_links (self ):
1063+         src_dir  =  self .mkdtemp ()
1064+         create_file (os .path .join (src_dir , 'c' ), 'abc' )
1065+         os .symlink ('IDONTEXIST' , os .path .join (src_dir , 'foo' ))
1066+         os .symlink (os .path .join (src_dir , 'foo' ), os .path .join (src_dir , 'broken' ))
1067+ 
1068+         # A dangling symlink should raise an error. 
1069+         dst_dir  =  os .path .join (self .mkdtemp (), 'destination' )
1070+         self .assertRaises (Error , shutil .copytree , src_dir , dst_dir )
1071+         self .assertEqual (['c' ], os .listdir (dst_dir ))
1072+ 
1073+         # Dangling symlinks should be ignored with the proper flag. 
1074+         dst_dir  =  os .path .join (self .mkdtemp (), 'destination2' )
1075+         shutil .copytree (src_dir , dst_dir , ignore_dangling_symlinks = True )
1076+         self .assertEqual (['c' ], os .listdir (dst_dir ))
1077+ 
1078+         # a dangling symlink is copied if symlinks=True 
1079+         dst_dir  =  os .path .join (self .mkdtemp (), 'destination3' )
1080+         shutil .copytree (src_dir , dst_dir , symlinks = True )
1081+         self .assertEqual ({'broken' , 'c' , 'foo' }, set (os .listdir (dst_dir )))
1082+ 
1083+     @os_helper .skip_unless_symlink  
1084+     def  test_copytree_circular_symlinks (self ):
1085+         src_dir  =  self .mkdtemp ()
1086+         os .symlink ('a' , os .path .join (src_dir , 'b' ))
1087+         os .symlink ('b' , os .path .join (src_dir , 'a' ))
1088+         create_file (os .path .join (src_dir , 'c' ), 'abc' )
1089+ 
1090+         # A circular symlink should raise an error if symlinks=False and 
1091+         # ignore_dangling_symlinks=False 
1092+         dst_dir  =  os .path .join (self .mkdtemp (), 'destination' )
1093+         with  self .assertRaises (Error ):
1094+             shutil .copytree (src_dir , dst_dir , symlinks = False ,
1095+                             ignore_dangling_symlinks = False )
1096+         self .assertEqual (['c' ], os .listdir (dst_dir ))
1097+ 
1098+         # ...however it should work if ignore_dangling_symlinks=True... 
1099+         dst_dir  =  os .path .join (self .mkdtemp (), 'destination' )
1100+         shutil .copytree (src_dir , dst_dir , symlinks = False ,
1101+                         ignore_dangling_symlinks = True )
1102+         self .assertEqual (['c' ], os .listdir (dst_dir ))
1103+ 
1104+         # ...and of course if symlinks=True 
1105+         for  ignore  in  (True , False ):
1106+             dst_dir  =  os .path .join (self .mkdtemp (), 'destination' )
1107+             with  self .subTest (ignore_dangling_symlinks = ignore ):
1108+                 shutil .copytree (src_dir , dst_dir , symlinks = True ,
1109+                                 ignore_dangling_symlinks = ignore )
1110+                 self .assertEqual ({'a' , 'b' , 'c' }, set (os .listdir (dst_dir )))
1111+ 
10611112    @os_helper .skip_unless_symlink  
10621113    def  test_copytree_symlink_dir (self ):
10631114        src_dir  =  self .mkdtemp ()
0 commit comments