@@ -1574,6 +1574,47 @@ def test_copyfile_socket(self):
15741574 self .assertRaisesRegex (shutil .SpecialFileError , 'is a socket' ,
15751575 shutil .copyfile , __file__ , sock_path )
15761576
1577+ def _check_copyfile_symlink_to_special_file (self , target ):
1578+ tmp_dir = self .mkdtemp ()
1579+ src = os .path .join (tmp_dir , 'src' )
1580+ dst = os .path .join (tmp_dir , 'dst' )
1581+ os .symlink (target , src )
1582+
1583+ shutil .copyfile (src , dst , follow_symlinks = False )
1584+
1585+ self .assertTrue (os .path .islink (dst ))
1586+ self .assertEqual (os .readlink (dst ), target )
1587+
1588+ @os_helper .skip_unless_symlink
1589+ @unittest .skipUnless (os .path .exists ('/dev/null' ), 'requires /dev/null' )
1590+ def test_copyfile_symlink_to_character_device (self ):
1591+ self ._check_copyfile_symlink_to_special_file ('/dev/null' )
1592+
1593+ @os_helper .skip_unless_symlink
1594+ @unittest .skipUnless (hasattr (os , "mkfifo" ), 'requires os.mkfifo()' )
1595+ @unittest .skipIf (sys .platform == "vxworks" ,
1596+ "fifo requires special path on VxWorks" )
1597+ def test_copyfile_symlink_to_named_pipe (self ):
1598+ fifo_path = os .path .join (self .mkdtemp (), 'fifo' )
1599+ try :
1600+ os .mkfifo (fifo_path )
1601+ except PermissionError as e :
1602+ self .skipTest ('os.mkfifo(): %s' % e )
1603+ self ._check_copyfile_symlink_to_special_file (fifo_path )
1604+
1605+ @os_helper .skip_unless_symlink
1606+ @socket_helper .skip_unless_bind_unix_socket
1607+ def test_copyfile_symlink_to_socket (self ):
1608+ sock_path = os .path .join (self .mkdtemp (), 'sock' )
1609+ sock = socket .socket (socket .AF_UNIX , socket .SOCK_STREAM )
1610+ self .addCleanup (sock .close )
1611+ try :
1612+ socket_helper .bind_unix_socket (sock , sock_path )
1613+ except OSError as e :
1614+ self .skipTest (f'cannot bind AF_UNIX socket: { e } ' )
1615+ self .addCleanup (os_helper .unlink , sock_path )
1616+ self ._check_copyfile_symlink_to_special_file (sock_path )
1617+
15771618 @unittest .skipUnless (os .path .exists ('/dev/null' ), 'requires /dev/null' )
15781619 def test_copyfile_character_device (self ):
15791620 self .assertRaisesRegex (shutil .SpecialFileError , 'is a character device' ,
0 commit comments