mirror of
https://github.com/python/cpython.git
synced 2025-01-26 11:04:21 +08:00
GH-89769: pathlib.Path.glob()
: do not follow symlinks when checking for precise match (GH-29655)
Co-authored-by: Barney Gale <barney.gale@gmail.com>
This commit is contained in:
parent
c7c3a60c88
commit
af886ffa06
@ -819,9 +819,14 @@ call fails (for example because the path doesn't exist).
|
||||
.. versionchanged:: 3.10
|
||||
The *follow_symlinks* parameter was added.
|
||||
|
||||
.. method:: Path.exists()
|
||||
.. method:: Path.exists(*, follow_symlinks=True)
|
||||
|
||||
Whether the path points to an existing file or directory::
|
||||
Return ``True`` if the path points to an existing file or directory.
|
||||
|
||||
This method normally follows symlinks; to check if a symlink exists, add
|
||||
the argument ``follow_symlinks=False``.
|
||||
|
||||
::
|
||||
|
||||
>>> Path('.').exists()
|
||||
True
|
||||
@ -832,10 +837,8 @@ call fails (for example because the path doesn't exist).
|
||||
>>> Path('nonexistentfile').exists()
|
||||
False
|
||||
|
||||
.. note::
|
||||
If the path points to a symlink, :meth:`exists` returns whether the
|
||||
symlink *points to* an existing file or directory.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
The *follow_symlinks* parameter was added.
|
||||
|
||||
.. method:: Path.expanduser()
|
||||
|
||||
|
@ -135,7 +135,8 @@ class _PreciseSelector(_Selector):
|
||||
def _select_from(self, parent_path, is_dir, exists, scandir):
|
||||
try:
|
||||
path = parent_path._make_child_relpath(self.name)
|
||||
if (is_dir if self.dironly else exists)(path):
|
||||
follow = is_dir(path) if self.dironly else exists(path, follow_symlinks=False)
|
||||
if follow:
|
||||
for p in self.successor._select_from(path, is_dir, exists, scandir):
|
||||
yield p
|
||||
except PermissionError:
|
||||
@ -1122,12 +1123,15 @@ class Path(PurePath):
|
||||
|
||||
# Convenience functions for querying the stat results
|
||||
|
||||
def exists(self):
|
||||
def exists(self, *, follow_symlinks=True):
|
||||
"""
|
||||
Whether this path exists.
|
||||
|
||||
This method normally follows symlinks; to check whether a symlink exists,
|
||||
add the argument follow_symlinks=False.
|
||||
"""
|
||||
try:
|
||||
self.stat()
|
||||
self.stat(follow_symlinks=follow_symlinks)
|
||||
except OSError as e:
|
||||
if not _ignore_error(e):
|
||||
raise
|
||||
|
@ -1700,6 +1700,8 @@ class _BasePathTest(object):
|
||||
self.assertIs(True, (p / 'linkB').exists())
|
||||
self.assertIs(True, (p / 'linkB' / 'fileB').exists())
|
||||
self.assertIs(False, (p / 'linkA' / 'bah').exists())
|
||||
self.assertIs(False, (p / 'brokenLink').exists())
|
||||
self.assertIs(True, (p / 'brokenLink').exists(follow_symlinks=False))
|
||||
self.assertIs(False, (p / 'foo').exists())
|
||||
self.assertIs(False, P('/xyzzy').exists())
|
||||
self.assertIs(False, P(BASE + '\udfff').exists())
|
||||
@ -1806,6 +1808,8 @@ class _BasePathTest(object):
|
||||
_check(p.glob("*/fileB"), ['dirB/fileB'])
|
||||
else:
|
||||
_check(p.glob("*/fileB"), ['dirB/fileB', 'linkB/fileB'])
|
||||
if os_helper.can_symlink():
|
||||
_check(p.glob("brokenLink"), ['brokenLink'])
|
||||
|
||||
if not os_helper.can_symlink():
|
||||
_check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE"])
|
||||
|
@ -0,0 +1,5 @@
|
||||
Fixed the bug in :meth:`pathlib.Path.glob` -- previously a dangling symlink
|
||||
would not be found by this method when the pattern is an exact match, but
|
||||
would be found when the pattern contains a wildcard or the recursive
|
||||
wildcard (``**``). With this change, a dangling symlink will be found in
|
||||
both cases.
|
Loading…
Reference in New Issue
Block a user