Commit 080169c4 authored by Guido van Rossum's avatar Guido van Rossum

Issue #24120: Ignore PermissionError in pathlib.Path.[r]glob(). Ulrich Petri. (Merge 3.5->3.6)

parents 576f132b d54377d2
...@@ -499,12 +499,15 @@ class _PreciseSelector(_Selector): ...@@ -499,12 +499,15 @@ class _PreciseSelector(_Selector):
_Selector.__init__(self, child_parts) _Selector.__init__(self, child_parts)
def _select_from(self, parent_path, is_dir, exists, listdir): def _select_from(self, parent_path, is_dir, exists, listdir):
if not is_dir(parent_path): try:
if not is_dir(parent_path):
return
path = parent_path._make_child_relpath(self.name)
if exists(path):
for p in self.successor._select_from(path, is_dir, exists, listdir):
yield p
except PermissionError:
return return
path = parent_path._make_child_relpath(self.name)
if exists(path):
for p in self.successor._select_from(path, is_dir, exists, listdir):
yield p
class _WildcardSelector(_Selector): class _WildcardSelector(_Selector):
...@@ -514,15 +517,19 @@ class _WildcardSelector(_Selector): ...@@ -514,15 +517,19 @@ class _WildcardSelector(_Selector):
_Selector.__init__(self, child_parts) _Selector.__init__(self, child_parts)
def _select_from(self, parent_path, is_dir, exists, listdir): def _select_from(self, parent_path, is_dir, exists, listdir):
if not is_dir(parent_path): try:
if not is_dir(parent_path):
return
cf = parent_path._flavour.casefold
for name in listdir(parent_path):
casefolded = cf(name)
if self.pat.match(casefolded):
path = parent_path._make_child_relpath(name)
for p in self.successor._select_from(path, is_dir, exists, listdir):
yield p
except PermissionError:
return return
cf = parent_path._flavour.casefold
for name in listdir(parent_path):
casefolded = cf(name)
if self.pat.match(casefolded):
path = parent_path._make_child_relpath(name)
for p in self.successor._select_from(path, is_dir, exists, listdir):
yield p
class _RecursiveWildcardSelector(_Selector): class _RecursiveWildcardSelector(_Selector):
...@@ -539,19 +546,22 @@ class _RecursiveWildcardSelector(_Selector): ...@@ -539,19 +546,22 @@ class _RecursiveWildcardSelector(_Selector):
yield p yield p
def _select_from(self, parent_path, is_dir, exists, listdir): def _select_from(self, parent_path, is_dir, exists, listdir):
if not is_dir(parent_path): try:
if not is_dir(parent_path):
return
with _cached(listdir) as listdir:
yielded = set()
try:
successor_select = self.successor._select_from
for starting_point in self._iterate_directories(parent_path, is_dir, listdir):
for p in successor_select(starting_point, is_dir, exists, listdir):
if p not in yielded:
yield p
yielded.add(p)
finally:
yielded.clear()
except PermissionError:
return return
with _cached(listdir) as listdir:
yielded = set()
try:
successor_select = self.successor._select_from
for starting_point in self._iterate_directories(parent_path, is_dir, listdir):
for p in successor_select(starting_point, is_dir, exists, listdir):
if p not in yielded:
yield p
yielded.add(p)
finally:
yielded.clear()
# #
......
...@@ -1199,26 +1199,33 @@ class _BasePathTest(object): ...@@ -1199,26 +1199,33 @@ class _BasePathTest(object):
# (BASE) # (BASE)
# | # |
# |-- dirA/ # |-- brokenLink -> non-existing
# |-- linkC -> "../dirB" # |-- dirA
# |-- dirB/ # | `-- linkC -> ../dirB
# | |-- fileB # |-- dirB
# |-- linkD -> "../dirB" # | |-- fileB
# |-- dirC/ # | `-- linkD -> ../dirB
# | |-- fileC # |-- dirC
# | |-- fileD # | |-- dirD
# | | `-- fileD
# | `-- fileC
# |-- dirE
# |-- fileA # |-- fileA
# |-- linkA -> "fileA" # |-- linkA -> fileA
# |-- linkB -> "dirB" # `-- linkB -> dirB
# #
def setUp(self): def setUp(self):
def cleanup():
os.chmod(join('dirE'), 0o777)
support.rmtree(BASE)
self.addCleanup(cleanup)
os.mkdir(BASE) os.mkdir(BASE)
self.addCleanup(support.rmtree, BASE)
os.mkdir(join('dirA')) os.mkdir(join('dirA'))
os.mkdir(join('dirB')) os.mkdir(join('dirB'))
os.mkdir(join('dirC')) os.mkdir(join('dirC'))
os.mkdir(join('dirC', 'dirD')) os.mkdir(join('dirC', 'dirD'))
os.mkdir(join('dirE'))
with open(join('fileA'), 'wb') as f: with open(join('fileA'), 'wb') as f:
f.write(b"this is file A\n") f.write(b"this is file A\n")
with open(join('dirB', 'fileB'), 'wb') as f: with open(join('dirB', 'fileB'), 'wb') as f:
...@@ -1227,6 +1234,7 @@ class _BasePathTest(object): ...@@ -1227,6 +1234,7 @@ class _BasePathTest(object):
f.write(b"this is file C\n") f.write(b"this is file C\n")
with open(join('dirC', 'dirD', 'fileD'), 'wb') as f: with open(join('dirC', 'dirD', 'fileD'), 'wb') as f:
f.write(b"this is file D\n") f.write(b"this is file D\n")
os.chmod(join('dirE'), 0)
if not symlink_skip_reason: if not symlink_skip_reason:
# Relative symlinks # Relative symlinks
os.symlink('fileA', join('linkA')) os.symlink('fileA', join('linkA'))
...@@ -1363,7 +1371,7 @@ class _BasePathTest(object): ...@@ -1363,7 +1371,7 @@ class _BasePathTest(object):
p = P(BASE) p = P(BASE)
it = p.iterdir() it = p.iterdir()
paths = set(it) paths = set(it)
expected = ['dirA', 'dirB', 'dirC', 'fileA'] expected = ['dirA', 'dirB', 'dirC', 'dirE', 'fileA']
if not symlink_skip_reason: if not symlink_skip_reason:
expected += ['linkA', 'linkB', 'brokenLink'] expected += ['linkA', 'linkB', 'brokenLink']
self.assertEqual(paths, { P(BASE, q) for q in expected }) self.assertEqual(paths, { P(BASE, q) for q in expected })
......
...@@ -1110,6 +1110,7 @@ Gabriel de Perthuis ...@@ -1110,6 +1110,7 @@ Gabriel de Perthuis
Tim Peters Tim Peters
Benjamin Peterson Benjamin Peterson
Joe Peterson Joe Peterson
Ulrich Petri
Chris Petrilli Chris Petrilli
Roumen Petrov Roumen Petrov
Bjorn Pettersen Bjorn Pettersen
......
...@@ -128,6 +128,9 @@ Core and Builtins ...@@ -128,6 +128,9 @@ Core and Builtins
Library Library
------- -------
- Issue #24120: Ignore PermissionError when traversing a tree with
pathlib.Path.[r]glob(). Patch by Ulrich Petri.
- Issue #21815: Accept ] characters in the data portion of imap responses, - Issue #21815: Accept ] characters in the data portion of imap responses,
in order to handle the flags with square brackets accepted and produced in order to handle the flags with square brackets accepted and produced
by servers such as gmail. by servers such as gmail.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment