8000 gh-108638: Fix stat.filemode() when _stat is missing by vstinner · Pull Request #108639 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-108638: Fix stat.filemode() when _stat is missing #108639

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
gh-108638: Fix stat.filemode() when _stat is missing
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
commit ce5c938b6b467b0802c8b88aefde6be33c073f86
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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if index == 0:
if not perm:

And you can remove index.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, feel free to write a follow-up PR if you want, sadly you reviewed the change just after it got merged automatically. I have not preference between enumerate() + if index == 0 and not perm.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_stat.filemode() and stat.filemode() implementations are very different. I tried to write a minimum fix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, so there is a _stat.filemode()? I noticed that the Python implementation always use constants defined in Python, even if they are overwritten by _stat later. I was not sure whether this is good or bad. On one hand, the original use case was for tar files, which can came from other systems. On other hand, it should work with local files.

# 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