mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
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:
parent
9e66ac683c
commit
aa93642a35
7 changed files with 1096 additions and 1172 deletions
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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 = ''
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue