bpo-33635: Handling Bad file descriptor in Path.is_file and related. (GH-8542)

This commit is contained in:
Przemysław Spodymek 2018-08-27 23:33:45 +02:00 committed by Steve Dower
parent 7ef1697be5
commit 216b745eaf
3 changed files with 48 additions and 10 deletions

View file

@ -7,7 +7,7 @@ import posixpath
import re
import sys
from _collections_abc import Sequence
from errno import EINVAL, ENOENT, ENOTDIR
from errno import EINVAL, ENOENT, ENOTDIR, EBADF
from operator import attrgetter
from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO
from urllib.parse import quote_from_bytes as urlquote_from_bytes
@ -34,6 +34,9 @@ __all__ = [
# Internals
#
# EBADF - guard agains macOS `stat` throwing EBADF
_IGNORED_ERROS = (ENOENT, ENOTDIR, EBADF)
def _is_wildcard_pattern(pat):
# Whether this pattern needs actual matching using fnmatch, or can
# be looked up directly as a file.
@ -528,7 +531,13 @@ class _RecursiveWildcardSelector(_Selector):
try:
entries = list(scandir(parent_path))
for entry in entries:
if entry.is_dir() and not entry.is_symlink():
entry_is_dir = False
try:
entry_is_dir = entry.is_dir()
except OSError as e:
if e.errno not in _IGNORED_ERROS:
raise
if entry_is_dir and not entry.is_symlink():
path = parent_path._make_child_relpath(entry.name)
for p in self._iterate_directories(path, is_dir, scandir):
yield p
@ -1319,7 +1328,7 @@ class Path(PurePath):
try:
self.stat()
except OSError as e:
if e.errno not in (ENOENT, ENOTDIR):
if e.errno not in _IGNORED_ERROS:
raise
return False
return True
@ -1331,7 +1340,7 @@ class Path(PurePath):
try:
return S_ISDIR(self.stat().st_mode)
except OSError as e:
if e.errno not in (ENOENT, ENOTDIR):
if e.errno not in _IGNORED_ERROS:
raise
# Path doesn't exist or is a broken symlink
# (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@ -1345,7 +1354,7 @@ class Path(PurePath):
try:
return S_ISREG(self.stat().st_mode)
except OSError as e:
if e.errno not in (ENOENT, ENOTDIR):
if e.errno not in _IGNORED_ERROS:
raise
# Path doesn't exist or is a broken symlink
# (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@ -1379,7 +1388,7 @@ class Path(PurePath):
try:
return S_ISLNK(self.lstat().st_mode)
except OSError as e:
if e.errno not in (ENOENT, ENOTDIR):
if e.errno not in _IGNORED_ERROS:
raise
# Path doesn't exist
return False
@ -1391,7 +1400,7 @@ class Path(PurePath):
try:
return S_ISBLK(self.stat().st_mode)
except OSError as e:
if e.errno not in (ENOENT, ENOTDIR):
if e.errno not in _IGNORED_ERROS:
raise
# Path doesn't exist or is a broken symlink
# (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@ -1404,7 +1413,7 @@ class Path(PurePath):
try:
return S_ISCHR(self.stat().st_mode)
except OSError as e:
if e.errno not in (ENOENT, ENOTDIR):
if e.errno not in _IGNORED_ERROS:
raise
# Path doesn't exist or is a broken symlink
# (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@ -1417,7 +1426,7 @@ class Path(PurePath):
try:
return S_ISFIFO(self.stat().st_mode)
except OSError as e:
if e.errno not in (ENOENT, ENOTDIR):
if e.errno not in _IGNORED_ERROS:
raise
# Path doesn't exist or is a broken symlink
# (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@ -1430,7 +1439,7 @@ class Path(PurePath):
try:
return S_ISSOCK(self.stat().st_mode)
except OSError as e:
if e.errno not in (ENOENT, ENOTDIR):
if e.errno not in _IGNORED_ERROS:
raise
# Path doesn't exist or is a broken symlink
# (see https://bitbucket.org/pitrou/pathlib/issue/12/)