@@ -935,6 +935,122 @@ def test_utime(self):
935935 posix .utime (os_helper .TESTFN , (int (now ), int (now )))
936936 posix .utime (os_helper .TESTFN , (now , now ))
937937
938+ def check_chmod (self , chmod_func , target , ** kwargs ):
939+ mode = os .stat (target ).st_mode
940+ try :
941+ new_mode = mode & ~ (stat .S_IWOTH | stat .S_IWGRP | stat .S_IWUSR )
942+ chmod_func (target , new_mode , ** kwargs )
943+ self .assertEqual (os .stat (target ).st_mode , new_mode )
944+ if stat .S_ISREG (mode ):
945+ try :
946+ with open (target , 'wb+' ):
947+ pass
948+ except PermissionError :
949+ pass
950+ new_mode = mode | (stat .S_IWOTH | stat .S_IWGRP | stat .S_IWUSR )
951+ chmod_func (target , new_mode , ** kwargs )
952+ self .assertEqual (os .stat (target ).st_mode , new_mode )
953+ if stat .S_ISREG (mode ):
954+ with open (target , 'wb+' ):
955+ pass
956+ finally :
957+ posix .chmod (target , mode )
958+
959+ def test_chmod_file (self ):
960+ self .check_chmod (posix .chmod , os_helper .TESTFN )
961+
962+ def tempdir (self ):
963+ target = os_helper .TESTFN + 'd'
964+ posix .mkdir (target )
965+ self .addCleanup (posix .rmdir , target )
966+ return target
967+
968+ def test_chmod_dir (self ):
969+ target = self .tempdir ()
970+ self .check_chmod (posix .chmod , target )
971+
972+ @unittest .skipUnless (hasattr (posix , 'lchmod' ), 'test needs os.lchmod()' )
973+ def test_lchmod_file (self ):
974+ self .check_chmod (posix .lchmod , os_helper .TESTFN )
975+ self .check_chmod (posix .chmod , os_helper .TESTFN , follow_symlinks = False )
976+
977+ @unittest .skipUnless (hasattr (posix , 'lchmod' ), 'test needs os.lchmod()' )
978+ def test_lchmod_dir (self ):
979+ target = self .tempdir ()
980+ self .check_chmod (posix .lchmod , target )
981+ self .check_chmod (posix .chmod , target , follow_symlinks = False )
982+
983+ def check_chmod_link (self , chmod_func , target , link , ** kwargs ):
984+ target_mode = os .stat (target ).st_mode
985+ link_mode = os .lstat (link ).st_mode
986+ try :
987+ new_mode = target_mode & ~ (stat .S_IWOTH | stat .S_IWGRP | stat .S_IWUSR )
988+ chmod_func (link , new_mode , ** kwargs )
989+ self .assertEqual (os .stat (target ).st_mode , new_mode )
990+ self .assertEqual (os .lstat (link ).st_mode , link_mode )
991+ new_mode = target_mode | (stat .S_IWOTH | stat .S_IWGRP | stat .S_IWUSR )
992+ chmod_func (link , new_mode , ** kwargs )
993+ self .assertEqual (os .stat (target ).st_mode , new_mode )
994+ self .assertEqual (os .lstat (link ).st_mode , link_mode )
995+ finally :
996+ posix .chmod (target , target_mode )
997+
998+ def check_lchmod_link (self , chmod_func , target , link , ** kwargs ):
999+ target_mode = os .stat (target ).st_mode
1000+ link_mode = os .lstat (link ).st_mode
1001+ new_mode = link_mode & ~ (stat .S_IWOTH | stat .S_IWGRP | stat .S_IWUSR )
1002+ chmod_func (link , new_mode , ** kwargs )
1003+ self .assertEqual (os .stat (target ).st_mode , target_mode )
1004+ self .assertEqual (os .lstat (link ).st_mode , new_mode )
1005+ new_mode = link_mode | (stat .S_IWOTH | stat .S_IWGRP | stat .S_IWUSR )
1006+ chmod_func (link , new_mode , ** kwargs )
1007+ self .assertEqual (os .stat (target ).st_mode , target_mode )
1008+ self .assertEqual (os .lstat (link ).st_mode , new_mode )
1009+
1010+ @os_helper .skip_unless_symlink
1011+ def test_chmod_file_symlink (self ):
1012+ target = os_helper .TESTFN
1013+ link = os_helper .TESTFN + '-link'
1014+ os .symlink (target , link )
1015+ self .addCleanup (posix .unlink , link )
1016+ if os .name == 'nt' :
1017+ self .check_lchmod_link (posix .chmod , target , link )
1018+ else :
1019+ self .check_chmod_link (posix .chmod , target , link )
1020+ self .check_chmod_link (posix .chmod , target , link , follow_symlinks = True )
1021+
1022+ @os_helper .skip_unless_symlink
1023+ def test_chmod_dir_symlink (self ):
1024+ target = self .tempdir ()
1025+ link = os_helper .TESTFN + '-link'
1026+ os .symlink (target , link , target_is_directory = True )
1027+ self .addCleanup (posix .unlink , link )
1028+ if os .name == 'nt' :
1029+ self .check_lchmod_link (posix .chmod , target , link )
1030+ else :
1031+ self .check_chmod_link (posix .chmod , target , link )
1032+ self .check_chmod_link (posix .chmod , target , link , follow_symlinks = True )
1033+
1034+ @unittest .skipUnless (hasattr (posix , 'lchmod' ), 'test needs os.lchmod()' )
1035+ @os_helper .skip_unless_symlink
1036+ def test_lchmod_file_symlink (self ):
1037+ target = os_helper .TESTFN
1038+ link = os_helper .TESTFN + '-link'
1039+ os .symlink (target , link )
1040+ self .addCleanup (posix .unlink , link )
1041+ self .check_lchmod_link (posix .chmod , target , link , follow_symlinks = False )
1042+ self .check_lchmod_link (posix .lchmod , target , link )
1043+
1044+ @unittest .skipUnless (hasattr (posix , 'lchmod' ), 'test needs os.lchmod()' )
1045+ @os_helper .skip_unless_symlink
1046+ def test_lchmod_dir_symlink (self ):
1047+ target = self .tempdir ()
1048+ link = os_helper .TESTFN + '-link'
1049+ os .symlink (target , link )
1050+ self .addCleanup (posix .unlink , link )
1051+ self .check_lchmod_link (posix .chmod , target , link , follow_symlinks = False )
1052+ self .check_lchmod_link (posix .lchmod , target , link )
1053+
9381054 def _test_chflags_regular_file (self , chflags_func , target_file , ** kwargs ):
9391055 st = os .stat (target_file )
9401056 self .assertTrue (hasattr (st , 'st_flags' ))
0 commit comments