From 87d37e3541f6cc0fe4c5189d5ea65fc59f54b3a0 Mon Sep 17 00:00:00 2001 From: barneygale Date: Fri, 21 Feb 2025 21:14:51 +0000 Subject: [PATCH 1/2] GH-125413: pathlib ABCs: use caching `path.info.exists()` when globbing Call `ReadablePath.info.exists()` rather than `ReadablePath.exists()` when globbing so that we use (or populate) the `info` cache. --- Lib/glob.py | 4 +++- Lib/test/test_pathlib/test_pathlib_abc.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/glob.py b/Lib/glob.py index cd8859e63318f3..d1a6dddeeb1610 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -533,7 +533,9 @@ class _PathGlobber(_GlobberBase): """Provides shell-style pattern matching and globbing for pathlib paths. """ - lexists = operator.methodcaller('exists', follow_symlinks=False) + @staticmethod + def lexists(path): + return path.info.exists(follow_symlinks=False) @staticmethod def scandir(path): diff --git a/Lib/test/test_pathlib/test_pathlib_abc.py b/Lib/test/test_pathlib/test_pathlib_abc.py index ee4c2b59fb9a39..68fe3521410f25 100644 --- a/Lib/test/test_pathlib/test_pathlib_abc.py +++ b/Lib/test/test_pathlib/test_pathlib_abc.py @@ -1107,7 +1107,7 @@ def test_glob_posix(self): p = P(self.base) q = p / "FILEa" given = set(p.glob("FILEa")) - expect = {q} if q.exists() else set() + expect = {q} if q.info.exists() else set() self.assertEqual(given, expect) self.assertEqual(set(p.glob("FILEa*")), set()) From 72c034b3fd2c3bf101827c3f9c65ece643ac7897 Mon Sep 17 00:00:00 2001 From: barneygale Date: Fri, 21 Feb 2025 22:09:01 +0000 Subject: [PATCH 2/2] Fix needless try/except around `is_dir()` while we're here --- Lib/pathlib/_abc.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py index 115e120572d9f1..4106d478822084 100644 --- a/Lib/pathlib/_abc.py +++ b/Lib/pathlib/_abc.py @@ -316,14 +316,11 @@ def walk(self, top_down=True, on_error=None, follow_symlinks=False): paths.append((path, dirnames, filenames)) try: for child in path.iterdir(): - try: - if child.info.is_dir(follow_symlinks=follow_symlinks): - if not top_down: - paths.append(child) - dirnames.append(child.name) - else: - filenames.append(child.name) - except OSError: + if child.info.is_dir(follow_symlinks=follow_symlinks): + if not top_down: + paths.append(child) + dirnames.append(child.name) + else: filenames.append(child.name) except OSError as error: if on_error is not None: