Skip to content

Commit

Permalink
pythongh-108638: Fix stat.filemode() when _stat is missing
Browse files Browse the repository at this point in the history
Change the pure Python implementation of stat.filemode() for unknown
file type: use "?", as done by the _stat.filemode().

test_stat skips TestFilemodeCStat if the _stat extension is missing.
  • Loading branch information
vstinner committed Aug 29, 2023
1 parent f8be2e2 commit 74062c3
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
10 changes: 8 additions & 2 deletions Lib/stat.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ def S_ISWHT(mode):


_filemode_table = (
# File type chars according to:
# http://en.wikibooks.org/wiki/C_Programming/POSIX_Reference/sys/stat.h
((S_IFLNK, "l"),
(S_IFSOCK, "s"), # Must appear before IFREG and IFDIR as IFSOCK == IFREG | IFDIR
(S_IFREG, "-"),
Expand Down Expand Up @@ -156,13 +158,17 @@ def S_ISWHT(mode):
def filemode(mode):
"""Convert a file's mode to a string of the form '-rwxrwxrwx'."""
perm = []
for table in _filemode_table:
for index, table in enumerate(_filemode_table):
for bit, char in table:
if mode & bit == bit:
perm.append(char)
break
else:
perm.append("-")
if index == 0:
# Unknown filetype
perm.append("?")
else:
perm.append("-")
return "".join(perm)


Expand Down
6 changes: 5 additions & 1 deletion Lib/test/test_stat.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,11 @@ def test_mode(self):
st_mode, modestr = self.get_mode()
self.assertEqual(modestr, '-rwx------')
self.assertS_IS("REG", st_mode)
self.assertEqual(self.statmod.S_IMODE(st_mode),
imode = self.statmod.S_IMODE(st_mode)
self.assertEqual(imode,
self.statmod.S_IRWXU)
self.assertEqual(self.statmod.filemode(imode),
'?rwx------')

os.chmod(TESTFN, 0o070)
st_mode, modestr = self.get_mode()
Expand Down Expand Up @@ -238,6 +241,7 @@ def test_file_attribute_constants(self):
self.assertEqual(value, modvalue, key)


@unittest.skipIf(c_stat is None, 'need _stat extension')
class TestFilemodeCStat(TestFilemode, unittest.TestCase):
statmod = c_stat

Expand Down

0 comments on commit 74062c3

Please sign in to comment.