mirror of
https://github.com/python/cpython.git
synced 2025-07-19 01:05:26 +00:00
GH-90208: Suppress OSError exceptions from pathlib.Path.glob()
(GH-104141)
`pathlib.Path.glob()` now suppresses all OSError exceptions, except those raised from calling `is_dir()` on the top-level path. Previously, `glob()` suppressed ENOENT, ENOTDIR, EBADF and ELOOP errors and their Windows equivalents. PermissionError was also suppressed unless it occurred when calling `is_dir()` on the top-level path. However, the selector would abort prematurely if a PermissionError was raised, and so `glob()` could return incomplete results.
This commit is contained in:
parent
373bca0cc5
commit
94f30c7557
3 changed files with 28 additions and 45 deletions
|
@ -142,25 +142,21 @@ class _WildcardSelector(_Selector):
|
|||
# avoid exhausting file descriptors when globbing deep trees.
|
||||
with scandir(parent_path) as scandir_it:
|
||||
entries = list(scandir_it)
|
||||
except OSError:
|
||||
pass
|
||||
else:
|
||||
for entry in entries:
|
||||
if self.dironly:
|
||||
try:
|
||||
# "entry.is_dir()" can raise PermissionError
|
||||
# in some cases (see bpo-38894), which is not
|
||||
# among the errors ignored by _ignore_error()
|
||||
if not entry.is_dir():
|
||||
continue
|
||||
except OSError as e:
|
||||
if not _ignore_error(e):
|
||||
raise
|
||||
except OSError:
|
||||
continue
|
||||
name = entry.name
|
||||
if self.match(name):
|
||||
path = parent_path._make_child_relpath(name)
|
||||
for p in self.successor._select_from(path, scandir):
|
||||
yield p
|
||||
except PermissionError:
|
||||
return
|
||||
|
||||
|
||||
class _RecursiveWildcardSelector(_Selector):
|
||||
|
@ -175,28 +171,25 @@ class _RecursiveWildcardSelector(_Selector):
|
|||
# avoid exhausting file descriptors when globbing deep trees.
|
||||
with scandir(parent_path) as scandir_it:
|
||||
entries = list(scandir_it)
|
||||
except OSError:
|
||||
pass
|
||||
else:
|
||||
for entry in entries:
|
||||
entry_is_dir = False
|
||||
try:
|
||||
entry_is_dir = entry.is_dir(follow_symlinks=False)
|
||||
except OSError as e:
|
||||
if not _ignore_error(e):
|
||||
raise
|
||||
except OSError:
|
||||
pass
|
||||
if entry_is_dir:
|
||||
path = parent_path._make_child_relpath(entry.name)
|
||||
for p in self._iterate_directories(path, scandir):
|
||||
yield p
|
||||
except PermissionError:
|
||||
return
|
||||
|
||||
def _select_from(self, parent_path, scandir):
|
||||
try:
|
||||
successor_select = self.successor._select_from
|
||||
for starting_point in self._iterate_directories(parent_path, scandir):
|
||||
for p in successor_select(starting_point, scandir):
|
||||
yield p
|
||||
except PermissionError:
|
||||
return
|
||||
successor_select = self.successor._select_from
|
||||
for starting_point in self._iterate_directories(parent_path, scandir):
|
||||
for p in successor_select(starting_point, scandir):
|
||||
yield p
|
||||
|
||||
|
||||
class _DoubleRecursiveWildcardSelector(_RecursiveWildcardSelector):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue