22import os
33import socket
44import sys
5- from test .support import os_helper
6- from test .support import socket_helper
5+ from test .support import is_apple , os_helper , socket_helper
76from test .support .import_helper import import_fresh_module
87from test .support .os_helper import TESTFN
98
@@ -15,8 +14,10 @@ class TestFilemode:
1514 statmod = None
1615
1716 file_flags = {'SF_APPEND' , 'SF_ARCHIVED' , 'SF_IMMUTABLE' , 'SF_NOUNLINK' ,
18- 'SF_SNAPSHOT' , 'UF_APPEND' , 'UF_COMPRESSED' , 'UF_HIDDEN' ,
19- 'UF_IMMUTABLE' , 'UF_NODUMP' , 'UF_NOUNLINK' , 'UF_OPAQUE' }
17+ 'SF_SNAPSHOT' , 'SF_SETTABLE' , 'SF_RESTRICTED' , 'SF_FIRMLINK' ,
18+ 'SF_DATALESS' , 'UF_APPEND' , 'UF_COMPRESSED' , 'UF_HIDDEN' ,
19+ 'UF_IMMUTABLE' , 'UF_NODUMP' , 'UF_NOUNLINK' , 'UF_OPAQUE' ,
20+ 'UF_SETTABLE' , 'UF_TRACKED' , 'UF_DATAVAULT' }
2021
2122 formats = {'S_IFBLK' , 'S_IFCHR' , 'S_IFDIR' , 'S_IFIFO' , 'S_IFLNK' ,
2223 'S_IFREG' , 'S_IFSOCK' , 'S_IFDOOR' , 'S_IFPORT' , 'S_IFWHT' }
@@ -113,6 +114,7 @@ def assertS_IS(self, name, mode):
113114 else :
114115 self .assertFalse (func (mode ))
115116
117+ @os_helper .skip_unless_working_chmod
116118 def test_mode (self ):
117119 with open (TESTFN , 'w' ):
118120 pass
@@ -121,8 +123,11 @@ def test_mode(self):
121123 st_mode , modestr = self .get_mode ()
122124 self .assertEqual (modestr , '-rwx------' )
123125 self .assertS_IS ("REG" , st_mode )
124- self .assertEqual (self .statmod .S_IMODE (st_mode ),
126+ imode = self .statmod .S_IMODE (st_mode )
127+ self .assertEqual (imode ,
125128 self .statmod .S_IRWXU )
129+ self .assertEqual (self .statmod .filemode (imode ),
130+ '?rwx------' )
126131
127132 os .chmod (TESTFN , 0o070 )
128133 st_mode , modestr = self .get_mode ()
@@ -144,13 +149,21 @@ def test_mode(self):
144149 self .assertEqual (modestr , '-r--r--r--' )
145150 self .assertEqual (self .statmod .S_IMODE (st_mode ), 0o444 )
146151 else :
152+ os .chmod (TESTFN , 0o500 )
153+ st_mode , modestr = self .get_mode ()
154+ self .assertEqual (modestr [:3 ], '-r-' )
155+ self .assertS_IS ("REG" , st_mode )
156+ self .assertEqual (self .statmod .S_IMODE (st_mode ), 0o444 )
157+
147158 os .chmod (TESTFN , 0o700 )
148159 st_mode , modestr = self .get_mode ()
149160 self .assertEqual (modestr [:3 ], '-rw' )
150161 self .assertS_IS ("REG" , st_mode )
151162 self .assertEqual (self .statmod .S_IFMT (st_mode ),
152163 self .statmod .S_IFREG )
164+ self .assertEqual (self .statmod .S_IMODE (st_mode ), 0o666 )
153165
166+ @os_helper .skip_unless_working_chmod
154167 def test_directory (self ):
155168 os .mkdir (TESTFN )
156169 os .chmod (TESTFN , 0o700 )
@@ -161,7 +174,7 @@ def test_directory(self):
161174 else :
162175 self .assertEqual (modestr [0 ], 'd' )
163176
164- @unittest . skipUnless ( hasattr ( os , 'symlink' ), 'os.symlink not available' )
177+ @os_helper . skip_unless_symlink
165178 def test_link (self ):
166179 try :
167180 os .symlink (os .getcwd (), TESTFN )
@@ -227,6 +240,18 @@ def test_module_attributes(self):
227240 self .assertTrue (callable (func ))
228241 self .assertEqual (func (0 ), 0 )
229242
243+ def test_flags_consistent (self ):
244+ self .assertFalse (self .statmod .UF_SETTABLE & self .statmod .SF_SETTABLE )
245+
246+ for flag in self .file_flags :
247+ if flag .startswith ("UF" ):
248+ self .assertTrue (getattr (self .statmod , flag ) & self .statmod .UF_SETTABLE , f"{ flag } not in UF_SETTABLE" )
249+ elif is_apple and self .statmod is c_stat and flag == 'SF_DATALESS' :
250+ self .assertTrue (self .statmod .SF_DATALESS & self .statmod .SF_SYNTHETIC , "SF_DATALESS not in SF_SYNTHETIC" )
251+ self .assertFalse (self .statmod .SF_DATALESS & self .statmod .SF_SETTABLE , "SF_DATALESS in SF_SETTABLE" )
252+ else :
253+ self .assertTrue (getattr (self .statmod , flag ) & self .statmod .SF_SETTABLE , f"{ flag } notin SF_SETTABLE" )
254+
230255 @unittest .skipUnless (sys .platform == "win32" ,
231256 "FILE_ATTRIBUTE_* constants are Win32 specific" )
232257 def test_file_attribute_constants (self ):
@@ -235,7 +260,68 @@ def test_file_attribute_constants(self):
235260 modvalue = getattr (self .statmod , key )
236261 self .assertEqual (value , modvalue , key )
237262
263+ @unittest .skipUnless (sys .platform == "darwin" , "macOS system check" )
264+ def test_macosx_attribute_values (self ):
265+ self .assertEqual (self .statmod .UF_SETTABLE , 0x0000ffff )
266+ self .assertEqual (self .statmod .UF_NODUMP , 0x00000001 )
267+ self .assertEqual (self .statmod .UF_IMMUTABLE , 0x00000002 )
268+ self .assertEqual (self .statmod .UF_APPEND , 0x00000004 )
269+ self .assertEqual (self .statmod .UF_OPAQUE , 0x00000008 )
270+ self .assertEqual (self .statmod .UF_COMPRESSED , 0x00000020 )
271+ self .assertEqual (self .statmod .UF_TRACKED , 0x00000040 )
272+ self .assertEqual (self .statmod .UF_DATAVAULT , 0x00000080 )
273+ self .assertEqual (self .statmod .UF_HIDDEN , 0x00008000 )
274+
275+ if self .statmod is c_stat :
276+ self .assertEqual (self .statmod .SF_SUPPORTED , 0x009f0000 )
277+ self .assertEqual (self .statmod .SF_SETTABLE , 0x3fff0000 )
278+ self .assertEqual (self .statmod .SF_SYNTHETIC , 0xc0000000 )
279+ else :
280+ self .assertEqual (self .statmod .SF_SETTABLE , 0xffff0000 )
281+ self .assertEqual (self .statmod .SF_ARCHIVED , 0x00010000 )
282+ self .assertEqual (self .statmod .SF_IMMUTABLE , 0x00020000 )
283+ self .assertEqual (self .statmod .SF_APPEND , 0x00040000 )
284+ self .assertEqual (self .statmod .SF_RESTRICTED , 0x00080000 )
285+ self .assertEqual (self .statmod .SF_NOUNLINK , 0x00100000 )
286+ self .assertEqual (self .statmod .SF_FIRMLINK , 0x00800000 )
287+ self .assertEqual (self .statmod .SF_DATALESS , 0x40000000 )
288+
289+ self .assertFalse (isinstance (self .statmod .S_IFMT , int ))
290+ self .assertEqual (self .statmod .S_IFIFO , 0o010000 )
291+ self .assertEqual (self .statmod .S_IFCHR , 0o020000 )
292+ self .assertEqual (self .statmod .S_IFDIR , 0o040000 )
293+ self .assertEqual (self .statmod .S_IFBLK , 0o060000 )
294+ self .assertEqual (self .statmod .S_IFREG , 0o100000 )
295+ self .assertEqual (self .statmod .S_IFLNK , 0o120000 )
296+ self .assertEqual (self .statmod .S_IFSOCK , 0o140000 )
297+
298+ if self .statmod is c_stat :
299+ self .assertEqual (self .statmod .S_IFWHT , 0o160000 )
300+
301+ self .assertEqual (self .statmod .S_IRWXU , 0o000700 )
302+ self .assertEqual (self .statmod .S_IRUSR , 0o000400 )
303+ self .assertEqual (self .statmod .S_IWUSR , 0o000200 )
304+ self .assertEqual (self .statmod .S_IXUSR , 0o000100 )
305+ self .assertEqual (self .statmod .S_IRWXG , 0o000070 )
306+ self .assertEqual (self .statmod .S_IRGRP , 0o000040 )
307+ self .assertEqual (self .statmod .S_IWGRP , 0o000020 )
308+ self .assertEqual (self .statmod .S_IXGRP , 0o000010 )
309+ self .assertEqual (self .statmod .S_IRWXO , 0o000007 )
310+ self .assertEqual (self .statmod .S_IROTH , 0o000004 )
311+ self .assertEqual (self .statmod .S_IWOTH , 0o000002 )
312+ self .assertEqual (self .statmod .S_IXOTH , 0o000001 )
313+ self .assertEqual (self .statmod .S_ISUID , 0o004000 )
314+ self .assertEqual (self .statmod .S_ISGID , 0o002000 )
315+ self .assertEqual (self .statmod .S_ISVTX , 0o001000 )
316+
317+ self .assertFalse (hasattr (self .statmod , "S_ISTXT" ))
318+ self .assertEqual (self .statmod .S_IREAD , self .statmod .S_IRUSR )
319+ self .assertEqual (self .statmod .S_IWRITE , self .statmod .S_IWUSR )
320+ self .assertEqual (self .statmod .S_IEXEC , self .statmod .S_IXUSR )
321+
322+
238323
324+ @unittest .skipIf (c_stat is None , 'need _stat extension' )
239325class TestFilemodeCStat (TestFilemode , unittest .TestCase ):
240326 statmod = c_stat
241327
0 commit comments