diff options
author | Brett Cannon <brett@python.org> | 2013-01-11 20:40:12 (GMT) |
---|---|---|
committer | Brett Cannon <brett@python.org> | 2013-01-11 20:40:12 (GMT) |
commit | a9976b3e32b612e33dc9f6d8874a88d028de7424 (patch) | |
tree | ee962bc60d43e5702d88347cebd3a4aa4a00f515 /Lib | |
parent | 8762595ef3fd807a67be4a97e0e5815d2abb0521 (diff) | |
download | cpython-a9976b3e32b612e33dc9f6d8874a88d028de7424.zip cpython-a9976b3e32b612e33dc9f6d8874a88d028de7424.tar.gz cpython-a9976b3e32b612e33dc9f6d8874a88d028de7424.tar.bz2 |
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.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/importlib/_bootstrap.py | 5 | ||||
-rw-r--r-- | Lib/test/test_importlib/source/test_finder.py | 35 |
2 files changed, 38 insertions, 2 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index a18ccc4..f647c2b 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -1395,8 +1395,9 @@ class FileFinder: path = self.path try: contents = _os.listdir(path) - except FileNotFoundError: - # Directory has been removed since last import + except (FileNotFoundError, PermissionError, NotADirectoryError): + # Directory has either been removed, turned into a file, or made + # unreadable. contents = [] # We store two cached versions, to handle runtime changes of the # PYTHONCASEOK environment variable. diff --git a/Lib/test/test_importlib/source/test_finder.py b/Lib/test/test_importlib/source/test_finder.py index 8bc16a5..8e49868 100644 --- a/Lib/test/test_importlib/source/test_finder.py +++ b/Lib/test/test_importlib/source/test_finder.py @@ -6,6 +6,9 @@ import errno import imp import os import py_compile +import stat +import sys +import tempfile from test.support import make_legacy_pyc import unittest import warnings @@ -147,6 +150,38 @@ class FinderTests(abc.FinderTests): self.assertIsNotNone(finder.find_module(mod)) self.assertIsNone(finder.find_module(mod)) + @unittest.skipUnless(sys.platform != 'win32', + 'os.chmod() does not support the needed arguments under Windows') + def test_no_read_directory(self): + # Issue #16730 + tempdir = tempfile.TemporaryDirectory() + original_mode = os.stat(tempdir.name).st_mode + def cleanup(tempdir): + """Cleanup function for the temporary directory. + + Since we muck with the permissions, we want to set them back to + their original values to make sure the directory can be properly + cleaned up. + + """ + os.chmod(tempdir.name, original_mode) + # If this is not explicitly called then the __del__ method is used, + # but since already mucking around might as well explicitly clean + # up. + tempdir.__exit__(None, None, None) + self.addCleanup(cleanup, tempdir) + os.chmod(tempdir.name, stat.S_IWUSR | stat.S_IXUSR) + finder = self.get_finder(tempdir.name) + self.assertEqual((None, []), finder.find_loader('doesnotexist')) + + def test_ignore_file(self): + # If a directory got changed to a file from underneath us, then don't + # worry about looking for submodules. + with tempfile.NamedTemporaryFile() as file_obj: + finder = self.get_finder(file_obj.name) + self.assertEqual((None, []), finder.find_loader('doesnotexist')) + + def test_main(): from test.support import run_unittest run_unittest(FinderTests) |