bpo-33635: Handling Bad file descriptor in Path.is_file and related. … · python/cpython@216b745

@@ -7,7 +7,7 @@

77

import re

88

import sys

99

from _collections_abc import Sequence

10-

from errno import EINVAL, ENOENT, ENOTDIR

10+

from errno import EINVAL, ENOENT, ENOTDIR, EBADF

1111

from operator import attrgetter

1212

from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO

1313

from 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+3740

def _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):

528531

try:

529532

entries = list(scandir(parent_path))

530533

for 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():

532541

path = parent_path._make_child_relpath(entry.name)

533542

for p in self._iterate_directories(path, is_dir, scandir):

534543

yield p

@@ -1319,7 +1328,7 @@ def exists(self):

13191328

try:

13201329

self.stat()

13211330

except OSError as e:

1322-

if e.errno not in (ENOENT, ENOTDIR):

1331+

if e.errno not in _IGNORED_ERROS:

13231332

raise

13241333

return False

13251334

return True

@@ -1331,7 +1340,7 @@ def is_dir(self):

13311340

try:

13321341

return S_ISDIR(self.stat().st_mode)

13331342

except OSError as e:

1334-

if e.errno not in (ENOENT, ENOTDIR):

1343+

if e.errno not in _IGNORED_ERROS:

13351344

raise

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):

13451354

try:

13461355

return S_ISREG(self.stat().st_mode)

13471356

except OSError as e:

1348-

if e.errno not in (ENOENT, ENOTDIR):

1357+

if e.errno not in _IGNORED_ERROS:

13491358

raise

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):

13791388

try:

13801389

return S_ISLNK(self.lstat().st_mode)

13811390

except OSError as e:

1382-

if e.errno not in (ENOENT, ENOTDIR):

1391+

if e.errno not in _IGNORED_ERROS:

13831392

raise

13841393

# Path doesn't exist

13851394

return False

@@ -1391,7 +1400,7 @@ def is_block_device(self):

13911400

try:

13921401

return S_ISBLK(self.stat().st_mode)

13931402

except OSError as e:

1394-

if e.errno not in (ENOENT, ENOTDIR):

1403+

if e.errno not in _IGNORED_ERROS:

13951404

raise

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):

14041413

try:

14051414

return S_ISCHR(self.stat().st_mode)

14061415

except OSError as e:

1407-

if e.errno not in (ENOENT, ENOTDIR):

1416+

if e.errno not in _IGNORED_ERROS:

14081417

raise

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):

14171426

try:

14181427

return S_ISFIFO(self.stat().st_mode)

14191428

except OSError as e:

1420-

if e.errno not in (ENOENT, ENOTDIR):

1429+

if e.errno not in _IGNORED_ERROS:

14211430

raise

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):

14301439

try:

14311440

return S_ISSOCK(self.stat().st_mode)

14321441

except OSError as e:

1433-

if e.errno not in (ENOENT, ENOTDIR):

1442+

if e.errno not in _IGNORED_ERROS:

14341443

raise

14351444

# Path doesn't exist or is a broken symlink

14361445

# (see https://bitbucket.org/pitrou/pathlib/issue/12/)