]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-113568: Stop raising auditing events from pathlib ABCs (#113571)
authorBarney Gale <barney.gale@gmail.com>
Fri, 5 Jan 2024 21:41:19 +0000 (21:41 +0000)
committerGitHub <noreply@github.com>
Fri, 5 Jan 2024 21:41:19 +0000 (21:41 +0000)
Raise auditing events in `pathlib.Path.glob()`, `rglob()` and `walk()`,
but not in `pathlib._abc.PathBase` methods. Also move generation of a
deprecation warning into `pathlib.Path` so it gets the right stack level.

Lib/pathlib/__init__.py
Lib/pathlib/_abc.py
Lib/test/test_pathlib/test_pathlib.py
Lib/test/test_pathlib/test_pathlib_abc.py
Misc/NEWS.d/next/Library/2023-12-29-17-30-49.gh-issue-113568.UpWNAI.rst [new file with mode: 0644]

index 79b8b4917f6cc4bea2a20705ba9b7a5ac49b1df1..6a94886040f95d6c8e72bac136d74ab86bdf2560 100644 (file)
@@ -9,6 +9,8 @@ import io
 import ntpath
 import os
 import posixpath
+import sys
+import warnings
 
 try:
     import pwd
@@ -230,7 +232,6 @@ class Path(_abc.PathBase, PurePath):
 
     def __init__(self, *args, **kwargs):
         if kwargs:
-            import warnings
             msg = ("support for supplying keyword arguments to pathlib.PurePath "
                    "is deprecated and scheduled for removal in Python {remove}")
             warnings._deprecated("pathlib.PurePath(**kwargs)", msg, remove=(3, 14))
@@ -309,6 +310,46 @@ class Path(_abc.PathBase, PurePath):
         path._tail_cached = self._tail + [entry.name]
         return path
 
+    def glob(self, pattern, *, case_sensitive=None, follow_symlinks=None):
+        """Iterate over this subtree and yield all existing files (of any
+        kind, including directories) matching the given relative pattern.
+        """
+        sys.audit("pathlib.Path.glob", self, pattern)
+        if pattern.endswith('**'):
+            # GH-70303: '**' only matches directories. Add trailing slash.
+            warnings.warn(
+                "Pattern ending '**' will match files and directories in a "
+                "future Python release. Add a trailing slash to match only "
+                "directories and remove this warning.",
+                FutureWarning, 2)
+            pattern = f'{pattern}/'
+        return _abc.PathBase.glob(
+            self, pattern, case_sensitive=case_sensitive, follow_symlinks=follow_symlinks)
+
+    def rglob(self, pattern, *, case_sensitive=None, follow_symlinks=None):
+        """Recursively yield all existing files (of any kind, including
+        directories) matching the given relative pattern, anywhere in
+        this subtree.
+        """
+        sys.audit("pathlib.Path.rglob", self, pattern)
+        if pattern.endswith('**'):
+            # GH-70303: '**' only matches directories. Add trailing slash.
+            warnings.warn(
+                "Pattern ending '**' will match files and directories in a "
+                "future Python release. Add a trailing slash to match only "
+                "directories and remove this warning.",
+                FutureWarning, 2)
+            pattern = f'{pattern}/'
+        pattern = f'**/{pattern}'
+        return _abc.PathBase.glob(
+            self, pattern, case_sensitive=case_sensitive, follow_symlinks=follow_symlinks)
+
+    def walk(self, top_down=True, on_error=None, follow_symlinks=False):
+        """Walk the directory tree from this directory, similar to os.walk()."""
+        sys.audit("pathlib.Path.walk", self, on_error, follow_symlinks)
+        return _abc.PathBase.walk(
+            self, top_down=top_down, on_error=on_error, follow_symlinks=follow_symlinks)
+
     def absolute(self):
         """Return an absolute version of this path
         No normalization or symlink resolution is performed.
index f75b20a1d5f1e5cda2299d8015dc62f162cecd6a..da8d67f624107a0b5c8afa0862c032cc690f90a5 100644 (file)
@@ -811,18 +811,6 @@ class PathBase(PurePathBase):
         """Iterate over this subtree and yield all existing files (of any
         kind, including directories) matching the given relative pattern.
         """
-        sys.audit("pathlib.Path.glob", self, pattern)
-        return self._glob(pattern, case_sensitive, follow_symlinks)
-
-    def rglob(self, pattern, *, case_sensitive=None, follow_symlinks=None):
-        """Recursively yield all existing files (of any kind, including
-        directories) matching the given relative pattern, anywhere in
-        this subtree.
-        """
-        sys.audit("pathlib.Path.rglob", self, pattern)
-        return self._glob(f'**/{pattern}', case_sensitive, follow_symlinks)
-
-    def _glob(self, pattern, case_sensitive, follow_symlinks):
         path_pattern = self.with_segments(pattern)
         if path_pattern.drive or path_pattern.root:
             raise NotImplementedError("Non-relative patterns are unsupported")
@@ -833,14 +821,6 @@ class PathBase(PurePathBase):
         if pattern[-1] in (self.pathmod.sep, self.pathmod.altsep):
             # GH-65238: pathlib doesn't preserve trailing slash. Add it back.
             pattern_parts.append('')
-        if pattern_parts[-1] == '**':
-            # GH-70303: '**' only matches directories. Add trailing slash.
-            warnings.warn(
-                "Pattern ending '**' will match files and directories in a "
-                "future Python release. Add a trailing slash to match only "
-                "directories and remove this warning.",
-                FutureWarning, 3)
-            pattern_parts.append('')
 
         if case_sensitive is None:
             # TODO: evaluate case-sensitivity of each directory in _select_children().
@@ -895,9 +875,16 @@ class PathBase(PurePathBase):
                 paths = _select_children(paths, dir_only, follow_symlinks, match)
         return paths
 
+    def rglob(self, pattern, *, case_sensitive=None, follow_symlinks=None):
+        """Recursively yield all existing files (of any kind, including
+        directories) matching the given relative pattern, anywhere in
+        this subtree.
+        """
+        return self.glob(
+            f'**/{pattern}', case_sensitive=case_sensitive, follow_symlinks=follow_symlinks)
+
     def walk(self, top_down=True, on_error=None, follow_symlinks=False):
         """Walk the directory tree from this directory, similar to os.walk()."""
-        sys.audit("pathlib.Path.walk", self, on_error, follow_symlinks)
         paths = [self]
 
         while paths:
index 8f95c804f80e69b4b0f5336dae43b618bc3182bd..b64e6b59da5d9af4c5e9951282f7e4876e9e1096 100644 (file)
@@ -1703,6 +1703,18 @@ class PathTest(test_pathlib_abc.DummyPathTest, PurePathTest):
         with set_recursion_limit(recursion_limit):
             list(base.glob('**/'))
 
+    def test_glob_recursive_no_trailing_slash(self):
+        P = self.cls
+        p = P(self.base)
+        with self.assertWarns(FutureWarning):
+            p.glob('**')
+        with self.assertWarns(FutureWarning):
+            p.glob('*/**')
+        with self.assertWarns(FutureWarning):
+            p.rglob('**')
+        with self.assertWarns(FutureWarning):
+            p.rglob('*/**')
+
 
 @only_posix
 class PosixPathTest(PathTest, PurePosixPathTest):
index e4a4e81e547cd195785423aa0f9372354068d557..a67235b4da3dd3982a88d9a0debcbdef168ed5af 100644 (file)
@@ -1266,19 +1266,6 @@ class DummyPathTest(DummyPurePathTest):
         bad_link.symlink_to("bad" * 200)
         self.assertEqual(sorted(base.glob('**/*')), [bad_link])
 
-    def test_glob_recursive_no_trailing_slash(self):
-        P = self.cls
-        p = P(self.base)
-        with self.assertWarns(FutureWarning):
-            p.glob('**')
-        with self.assertWarns(FutureWarning):
-            p.glob('*/**')
-        with self.assertWarns(FutureWarning):
-            p.rglob('**')
-        with self.assertWarns(FutureWarning):
-            p.rglob('*/**')
-
-
     def test_readlink(self):
         if not self.can_symlink:
             self.skipTest("symlinks required")
diff --git a/Misc/NEWS.d/next/Library/2023-12-29-17-30-49.gh-issue-113568.UpWNAI.rst b/Misc/NEWS.d/next/Library/2023-12-29-17-30-49.gh-issue-113568.UpWNAI.rst
new file mode 100644 (file)
index 0000000..aaca525
--- /dev/null
@@ -0,0 +1,2 @@
+Raise audit events from :class:`pathlib.Path` and not its private base class
+``PathBase``.