Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a9976b3

Browse files
committed
Issue #16730: Don't raise an exception in
importlib.machinery.FileFinder when the directory has become unreadable or a file. This brings semantics in line with Python 3.2 import. Reported and diagnosed by David Pritchard.
1 parent 8762595 commit a9976b3

4 files changed

Lines changed: 989 additions & 945 deletions

File tree

Lib/importlib/_bootstrap.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,8 +1395,9 @@ def _fill_cache(self):
13951395
path = self.path
13961396
try:
13971397
contents = _os.listdir(path)
1398-
except FileNotFoundError:
1399-
# Directory has been removed since last import
1398+
except (FileNotFoundError, PermissionError, NotADirectoryError):
1399+
# Directory has either been removed, turned into a file, or made
1400+
# unreadable.
14001401
contents = []
14011402
# We store two cached versions, to handle runtime changes of the
14021403
# PYTHONCASEOK environment variable.

Lib/test/test_importlib/source/test_finder.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import imp
77
import os
88
import py_compile
9+
import stat
10+
import sys
11+
import tempfile
912
from test.support import make_legacy_pyc
1013
import unittest
1114
import warnings
@@ -147,6 +150,38 @@ def test_dir_removal_handling(self):
147150
self.assertIsNotNone(finder.find_module(mod))
148151
self.assertIsNone(finder.find_module(mod))
149152

153+
@unittest.skipUnless(sys.platform != 'win32',
154+
'os.chmod() does not support the needed arguments under Windows')
155+
def test_no_read_directory(self):
156+
# Issue #16730
157+
tempdir = tempfile.TemporaryDirectory()
158+
original_mode = os.stat(tempdir.name).st_mode
159+
def cleanup(tempdir):
160+
"""Cleanup function for the temporary directory.
161+
162+
Since we muck with the permissions, we want to set them back to
163+
their original values to make sure the directory can be properly
164+
cleaned up.
165+
166+
"""
167+
os.chmod(tempdir.name, original_mode)
168+
# If this is not explicitly called then the __del__ method is used,
169+
# but since already mucking around might as well explicitly clean
170+
# up.
171+
tempdir.__exit__(None, None, None)
172+
self.addCleanup(cleanup, tempdir)
173+
os.chmod(tempdir.name, stat.S_IWUSR | stat.S_IXUSR)
174+
finder = self.get_finder(tempdir.name)
175+
self.assertEqual((None, []), finder.find_loader('doesnotexist'))
176+
177+
def test_ignore_file(self):
178+
# If a directory got changed to a file from underneath us, then don't
179+
# worry about looking for submodules.
180+
with tempfile.NamedTemporaryFile() as file_obj:
181+
finder = self.get_finder(file_obj.name)
182+
self.assertEqual((None, []), finder.find_loader('doesnotexist'))
183+
184+
150185
def test_main():
151186
from test.support import run_unittest
152187
run_unittest(FinderTests)

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ What's New in Python 3.3.1?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #16730: importlib.machinery.FileFinder now no longers raises an
16+
exception when trying to populate its cache and it finds out the directory is
17+
unreadable or has turned into a file. Reported and diagnosed by
18+
David Pritchard.
19+
1520
- Issue #16906: Fix a logic error that prevented most static strings from being
1621
cleared.
1722

0 commit comments

Comments
 (0)