summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2013-01-11 20:40:12 (GMT)
committerBrett Cannon <brett@python.org>2013-01-11 20:40:12 (GMT)
commita9976b3e32b612e33dc9f6d8874a88d028de7424 (patch)
treeee962bc60d43e5702d88347cebd3a4aa4a00f515 /Lib
parent8762595ef3fd807a67be4a97e0e5815d2abb0521 (diff)
downloadcpython-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.py5
-rw-r--r--Lib/test/test_importlib/source/test_finder.py35
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)