bpo-33635: Handling Bad file descriptor in Path.is_file and related. … · python/cpython@216b745
@@ -7,7 +7,7 @@
77import re
88import sys
99from _collections_abc import Sequence
10-from errno import EINVAL, ENOENT, ENOTDIR
10+from errno import EINVAL, ENOENT, ENOTDIR, EBADF
1111from operator import attrgetter
1212from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO
1313from urllib.parse import quote_from_bytes as urlquote_from_bytes
@@ -34,6 +34,9 @@
3434# Internals
3535#
363637+# EBADF - guard agains macOS `stat` throwing EBADF
38+_IGNORED_ERROS = (ENOENT, ENOTDIR, EBADF)
39+3740def _is_wildcard_pattern(pat):
3841# Whether this pattern needs actual matching using fnmatch, or can
3942# be looked up directly as a file.
@@ -528,7 +531,13 @@ def _iterate_directories(self, parent_path, is_dir, scandir):
528531try:
529532entries = list(scandir(parent_path))
530533for entry in entries:
531-if entry.is_dir() and not entry.is_symlink():
534+entry_is_dir = False
535+try:
536+entry_is_dir = entry.is_dir()
537+except OSError as e:
538+if e.errno not in _IGNORED_ERROS:
539+raise
540+if entry_is_dir and not entry.is_symlink():
532541path = parent_path._make_child_relpath(entry.name)
533542for p in self._iterate_directories(path, is_dir, scandir):
534543yield p
@@ -1319,7 +1328,7 @@ def exists(self):
13191328try:
13201329self.stat()
13211330except OSError as e:
1322-if e.errno not in (ENOENT, ENOTDIR):
1331+if e.errno not in _IGNORED_ERROS:
13231332raise
13241333return False
13251334return True
@@ -1331,7 +1340,7 @@ def is_dir(self):
13311340try:
13321341return S_ISDIR(self.stat().st_mode)
13331342except OSError as e:
1334-if e.errno not in (ENOENT, ENOTDIR):
1343+if e.errno not in _IGNORED_ERROS:
13351344raise
13361345# Path doesn't exist or is a broken symlink
13371346# (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@@ -1345,7 +1354,7 @@ def is_file(self):
13451354try:
13461355return S_ISREG(self.stat().st_mode)
13471356except OSError as e:
1348-if e.errno not in (ENOENT, ENOTDIR):
1357+if e.errno not in _IGNORED_ERROS:
13491358raise
13501359# Path doesn't exist or is a broken symlink
13511360# (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@@ -1379,7 +1388,7 @@ def is_symlink(self):
13791388try:
13801389return S_ISLNK(self.lstat().st_mode)
13811390except OSError as e:
1382-if e.errno not in (ENOENT, ENOTDIR):
1391+if e.errno not in _IGNORED_ERROS:
13831392raise
13841393# Path doesn't exist
13851394return False
@@ -1391,7 +1400,7 @@ def is_block_device(self):
13911400try:
13921401return S_ISBLK(self.stat().st_mode)
13931402except OSError as e:
1394-if e.errno not in (ENOENT, ENOTDIR):
1403+if e.errno not in _IGNORED_ERROS:
13951404raise
13961405# Path doesn't exist or is a broken symlink
13971406# (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@@ -1404,7 +1413,7 @@ def is_char_device(self):
14041413try:
14051414return S_ISCHR(self.stat().st_mode)
14061415except OSError as e:
1407-if e.errno not in (ENOENT, ENOTDIR):
1416+if e.errno not in _IGNORED_ERROS:
14081417raise
14091418# Path doesn't exist or is a broken symlink
14101419# (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@@ -1417,7 +1426,7 @@ def is_fifo(self):
14171426try:
14181427return S_ISFIFO(self.stat().st_mode)
14191428except OSError as e:
1420-if e.errno not in (ENOENT, ENOTDIR):
1429+if e.errno not in _IGNORED_ERROS:
14211430raise
14221431# Path doesn't exist or is a broken symlink
14231432# (see https://bitbucket.org/pitrou/pathlib/issue/12/)
@@ -1430,7 +1439,7 @@ def is_socket(self):
14301439try:
14311440return S_ISSOCK(self.stat().st_mode)
14321441except OSError as e:
1433-if e.errno not in (ENOENT, ENOTDIR):
1442+if e.errno not in _IGNORED_ERROS:
14341443raise
14351444# Path doesn't exist or is a broken symlink
14361445# (see https://bitbucket.org/pitrou/pathlib/issue/12/)