import ntpath
import os
import posixpath
+import sys
+import warnings
try:
import pwd
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))
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.
"""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")
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().
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:
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):
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")
--- /dev/null
+Raise audit events from :class:`pathlib.Path` and not its private base class
+``PathBase``.