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

This commit is contained in:
Guido van Rossum 2016-01-06 09:51:42 -08:00
commit d54377d2ca
4 changed files with 59 additions and 37 deletions

View File

@ -499,12 +499,15 @@ class _PreciseSelector(_Selector):
_Selector.__init__(self, child_parts)
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
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):
@ -514,15 +517,19 @@ class _WildcardSelector(_Selector):
_Selector.__init__(self, child_parts)
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
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):
@ -539,19 +546,22 @@ class _RecursiveWildcardSelector(_Selector):
yield p
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
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()
#

View File

@ -1199,26 +1199,33 @@ class _BasePathTest(object):
# (BASE)
# |
# |-- dirA/
# |-- linkC -> "../dirB"
# |-- dirB/
# | |-- fileB
# |-- linkD -> "../dirB"
# |-- dirC/
# | |-- fileC
# | |-- fileD
# |-- brokenLink -> non-existing
# |-- dirA
# | `-- linkC -> ../dirB
# |-- dirB
# | |-- fileB
# | `-- linkD -> ../dirB
# |-- dirC
# | |-- dirD
# | | `-- fileD
# | `-- fileC
# |-- dirE
# |-- fileA
# |-- linkA -> "fileA"
# |-- linkB -> "dirB"
# |-- linkA -> fileA
# `-- linkB -> dirB
#
def setUp(self):
def cleanup():
os.chmod(join('dirE'), 0o777)
support.rmtree(BASE)
self.addCleanup(cleanup)
os.mkdir(BASE)
self.addCleanup(support.rmtree, BASE)
os.mkdir(join('dirA'))
os.mkdir(join('dirB'))
os.mkdir(join('dirC'))
os.mkdir(join('dirC', 'dirD'))
os.mkdir(join('dirE'))
with open(join('fileA'), 'wb') as f:
f.write(b"this is file A\n")
with open(join('dirB', 'fileB'), 'wb') as f:
@ -1227,6 +1234,7 @@ class _BasePathTest(object):
f.write(b"this is file C\n")
with open(join('dirC', 'dirD', 'fileD'), 'wb') as f:
f.write(b"this is file D\n")
os.chmod(join('dirE'), 0)
if not symlink_skip_reason:
# Relative symlinks
os.symlink('fileA', join('linkA'))
@ -1363,7 +1371,7 @@ class _BasePathTest(object):
p = P(BASE)
it = p.iterdir()
paths = set(it)
expected = ['dirA', 'dirB', 'dirC', 'fileA']
expected = ['dirA', 'dirB', 'dirC', 'dirE', 'fileA']
if not symlink_skip_reason:
expected += ['linkA', 'linkB', 'brokenLink']
self.assertEqual(paths, { P(BASE, q) for q in expected })

View File

@ -1106,6 +1106,7 @@ Gabriel de Perthuis
Tim Peters
Benjamin Peterson
Joe Peterson
Ulrich Petri
Chris Petrilli
Roumen Petrov
Bjorn Pettersen

View File

@ -41,6 +41,9 @@ Core and Builtins
Library
-------
- Issue #24120: Ignore PermissionError when traversing a tree with
pathlib.Path.[r]glob(). Patch by Ulrich Petri.
- Issue #25447: fileinput now uses sys.stdin as-is if it does not have a
buffer attribute (restores backward compatibility).