[Python-checkins] cpython (merge 3.5 -> default): Issue #24120: Ignore PermissionError in pathlib.Path.[r]glob(). Ulrich Petri.
guido.van.rossum
python-checkins at python.org
Wed Jan 6 12:54:13 EST 2016
https://hg.python.org/cpython/rev/f6ae90450a4d
changeset: 99777:f6ae90450a4d
parent: 99771:1118dfcbcc35
parent: 99776:224a026b4ca1
user: Guido van Rossum <guido at dropbox.com>
date: Wed Jan 06 09:53:51 2016 -0800
summary:
Issue #24120: Ignore PermissionError in pathlib.Path.[r]glob(). Ulrich Petri. (Merge 3.5->3.6)
files:
Lib/pathlib.py | 60 ++++++++++++++++-----------
Lib/test/test_pathlib.py | 32 +++++++++-----
Misc/ACKS | 1 +
Misc/NEWS | 3 +
4 files changed, 59 insertions(+), 37 deletions(-)
diff --git a/Lib/pathlib.py b/Lib/pathlib.py
--- a/Lib/pathlib.py
+++ b/Lib/pathlib.py
@@ -499,12 +499,15 @@
_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 @@
_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 @@
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()
#
diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py
--- a/Lib/test/test_pathlib.py
+++ b/Lib/test/test_pathlib.py
@@ -1199,26 +1199,33 @@
# (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 @@
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 @@
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 })
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1110,6 +1110,7 @@
Tim Peters
Benjamin Peterson
Joe Peterson
+Ulrich Petri
Chris Petrilli
Roumen Petrov
Bjorn Pettersen
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -128,6 +128,9 @@
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,
in order to handle the flags with square brackets accepted and produced
by servers such as gmail.
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list