From a89239a391c4843101a28919ec7c00bff453e503 Mon Sep 17 00:00:00 2001 From: VanshAgarwal24036 <148854295+VanshAgarwal24036@users.noreply.github.com> Date: Tue, 20 Jan 2026 17:35:42 +0530 Subject: [PATCH] gh-144050: Fix stat.filemode pure Python file type detection (GH-144059) (cherry picked from commit fe629262c0db7aa18bad8bf3ac524acd8695739b) Co-authored-by: VanshAgarwal24036 <148854295+VanshAgarwal24036@users.noreply.github.com> --- Lib/stat.py | 11 ++++++++--- Lib/test/test_stat.py | 5 +++++ .../2026-01-20-16-35-55.gh-issue-144050.0kKFbF.rst | 2 ++ 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-20-16-35-55.gh-issue-144050.0kKFbF.rst diff --git a/Lib/stat.py b/Lib/stat.py index 1b4ed1ebc940ef..81f694329bf4ff 100644 --- a/Lib/stat.py +++ b/Lib/stat.py @@ -166,9 +166,14 @@ def filemode(mode): perm = [] for index, table in enumerate(_filemode_table): for bit, char in table: - if mode & bit == bit: - perm.append(char) - break + if index == 0: + if S_IFMT(mode) == bit: + perm.append(char) + break + else: + if mode & bit == bit: + perm.append(char) + break else: if index == 0: # Unknown filetype diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py index 5fd25d5012c425..a83f7d076f027e 100644 --- a/Lib/test/test_stat.py +++ b/Lib/test/test_stat.py @@ -163,6 +163,11 @@ def test_mode(self): self.statmod.S_IFREG) self.assertEqual(self.statmod.S_IMODE(st_mode), 0o666) + def test_filemode_does_not_misclassify_random_bits(self): + # gh-144050 regression test + self.assertEqual(self.statmod.filemode(0o77777)[0], "?") + self.assertEqual(self.statmod.filemode(0o177777)[0], "?") + @os_helper.skip_unless_working_chmod def test_directory(self): os.mkdir(TESTFN) diff --git a/Misc/NEWS.d/next/Library/2026-01-20-16-35-55.gh-issue-144050.0kKFbF.rst b/Misc/NEWS.d/next/Library/2026-01-20-16-35-55.gh-issue-144050.0kKFbF.rst new file mode 100644 index 00000000000000..dfc062d023c8f1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-20-16-35-55.gh-issue-144050.0kKFbF.rst @@ -0,0 +1,2 @@ +Fix :func:`stat.filemode` in the pure-Python implementation to avoid misclassifying +invalid mode values as block devices.