https://github.com/python/cpython/commit/3c4e972d6d0945a5401377bed25b307a88b19c75
commit: 3c4e972d6d0945a5401377bed25b307a88b19c75
branch: main
author: Barney Gale <[email protected]>
committer: barneygale <[email protected]>
date: 2024-01-05T21:41:19Z
summary:

GH-113568: Stop raising auditing events from pathlib ABCs (#113571)

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.

files:
A Misc/NEWS.d/next/Library/2023-12-29-17-30-49.gh-issue-113568.UpWNAI.rst
M Lib/pathlib/__init__.py
M Lib/pathlib/_abc.py
M Lib/test/test_pathlib/test_pathlib.py
M Lib/test/test_pathlib/test_pathlib_abc.py

diff --git a/Lib/pathlib/__init__.py b/Lib/pathlib/__init__.py
index 79b8b4917f6cc4..6a94886040f95d 100644
--- a/Lib/pathlib/__init__.py
+++ b/Lib/pathlib/__init__.py
@@ -9,6 +9,8 @@
 import ntpath
 import os
 import posixpath
+import sys
+import warnings
 
 try:
     import pwd
@@ -230,7 +232,6 @@ def _unsupported(cls, method_name):
 
     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 @@ def _make_child_entry(self, entry):
         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.
diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py
index f75b20a1d5f1e5..da8d67f624107a 100644
--- a/Lib/pathlib/_abc.py
+++ b/Lib/pathlib/_abc.py
@@ -811,18 +811,6 @@ 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)
-        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 @@ def _glob(self, pattern, case_sensitive, follow_symlinks):
         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 @@ def _glob(self, pattern, case_sensitive, follow_symlinks):
                 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:
diff --git a/Lib/test/test_pathlib/test_pathlib.py 
b/Lib/test/test_pathlib/test_pathlib.py
index 8f95c804f80e69..b64e6b59da5d9a 100644
--- a/Lib/test/test_pathlib/test_pathlib.py
+++ b/Lib/test/test_pathlib/test_pathlib.py
@@ -1703,6 +1703,18 @@ def test_glob_above_recursion_limit(self):
         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):
diff --git a/Lib/test/test_pathlib/test_pathlib_abc.py 
b/Lib/test/test_pathlib/test_pathlib_abc.py
index e4a4e81e547cd1..a67235b4da3dd3 100644
--- a/Lib/test/test_pathlib/test_pathlib_abc.py
+++ b/Lib/test/test_pathlib/test_pathlib_abc.py
@@ -1266,19 +1266,6 @@ def test_glob_long_symlink(self):
         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
index 00000000000000..aaca5250184122
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-12-29-17-30-49.gh-issue-113568.UpWNAI.rst
@@ -0,0 +1,2 @@
+Raise audit events from :class:`pathlib.Path` and not its private base class
+``PathBase``.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to