Issue #14605: Use None in sys.path_importer_cache to represent no

finder instead of using some (now non-existent) implicit finder.
This commit is contained in:
Brett Cannon 2012-04-27 15:30:58 -04:00
parent 9e66ac683c
commit aa93642a35
7 changed files with 1096 additions and 1172 deletions

View file

@ -766,17 +766,14 @@ class PathFinder:
except ImportError:
continue
else:
raise ImportError("no path hook found for {0}".format(path),
path=path)
return None
@classmethod
def _path_importer_cache(cls, path):
"""Get the finder for the path from sys.path_importer_cache.
If the path is not in the cache, find the appropriate finder and cache
it. Because of NullImporter, some finder should be returned. The only
explicit fail case is if None is cached but the path cannot be used for
the default hook, for which ImportError is raised.
it. If no finder is available, store None.
"""
if path == '':
@ -786,15 +783,6 @@ class PathFinder:
except KeyError:
finder = cls._path_hooks(path)
sys.path_importer_cache[path] = finder
else:
if finder is None:
msg = ("'None' in sys.path_importer_cache[{!r}], so retrying "
"finder search; in future versions of Python 'None' "
"will represent no finder".format(path))
_warnings.warn(msg, ImportWarning)
del sys.path_importer_cache[path]
finder = cls._path_hooks(path)
sys.path_importer_cache[path] = finder
return finder
@classmethod
@ -804,11 +792,8 @@ class PathFinder:
if path is None:
path = sys.path
for entry in path:
try:
finder = cls._path_importer_cache(entry)
except ImportError:
continue
if finder:
finder = cls._path_importer_cache(entry)
if finder is not None:
loader = finder.find_module(fullname)
if loader:
return loader
@ -1192,6 +1177,5 @@ def _install(sys_module, _imp_module):
supported_loaders = [(ExtensionFileLoader, _suffix_list(3), False),
(SourceFileLoader, _suffix_list(1), True),
(SourcelessFileLoader, _suffix_list(2), True)]
sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders),
_imp.NullImporter])
sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)])
sys.meta_path.extend([BuiltinImporter, FrozenImporter, PathFinder])

View file

@ -66,36 +66,18 @@ class FinderTests(unittest.TestCase):
self.assertTrue(sys.path_importer_cache[path] is importer)
def test_empty_path_hooks(self):
# Test that if sys.path_hooks is empty a warning is raised and
# PathFinder returns None.
# tried again (with a warning).
# Test that if sys.path_hooks is empty a warning is raised,
# sys.path_importer_cache gets None set, and PathFinder returns None.
path_entry = 'bogus_path'
with util.import_state(path_importer_cache={}, path_hooks=[],
path=['bogus_path']):
path=[path_entry]):
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
self.assertIsNone(machinery.PathFinder.find_module('os'))
self.assertNotIn('os', sys.path_importer_cache)
self.assertIsNone(sys.path_importer_cache[path_entry])
self.assertEqual(len(w), 1)
self.assertTrue(issubclass(w[-1].category, ImportWarning))
def test_path_importer_cache_has_None_continues(self):
# Test that having None in sys.path_importer_cache causes the search to
# continue.
path = '<test path>'
module = '<test module>'
importer = util.mock_modules(module)
with util.import_state(path=['1', '2'],
path_importer_cache={'1': None, '2': importer},
path_hooks=[imp.NullImporter]):
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
loader = machinery.PathFinder.find_module(module)
self.assertTrue(loader is importer)
self.assertEqual(len(w), 1)
warned = w[0]
self.assertTrue(issubclass(warned.category, ImportWarning))
self.assertIn(repr(None), str(warned.message))
def test_path_importer_cache_empty_string(self):
# The empty string should create a finder using the cwd.
path = ''