[Python-checkins] cpython: Issue #14605: Use None in sys.path_importer_cache to represent no
brett.cannon
python-checkins at python.org
Fri Apr 27 21:31:51 CEST 2012
http://hg.python.org/cpython/rev/7025ee00dbf6
changeset: 76582:7025ee00dbf6
parent: 76580:f90c735e7699
user: Brett Cannon <brett at python.org>
date: Fri Apr 27 15:30:58 2012 -0400
summary:
Issue #14605: Use None in sys.path_importer_cache to represent no
finder instead of using some (now non-existent) implicit finder.
files:
Lib/importlib/_bootstrap.py | 26 ++---------
Lib/importlib/test/import_/test_path.py | 28 ++---------
Lib/runpy.py | 9 +--
Misc/NEWS | 6 +-
Modules/main.c | 2 +-
Python/import.c | 10 +---
Python/importlib.h | Bin
7 files changed, 18 insertions(+), 63 deletions(-)
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -766,17 +766,14 @@
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 @@
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 @@
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 @@
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])
diff --git a/Lib/importlib/test/import_/test_path.py b/Lib/importlib/test/import_/test_path.py
--- a/Lib/importlib/test/import_/test_path.py
+++ b/Lib/importlib/test/import_/test_path.py
@@ -66,36 +66,18 @@
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 = ''
diff --git a/Lib/runpy.py b/Lib/runpy.py
--- a/Lib/runpy.py
+++ b/Lib/runpy.py
@@ -9,6 +9,7 @@
# Written by Nick Coghlan <ncoghlan at gmail.com>
# to implement PEP 338 (Executing Modules as Scripts)
+
import os
import sys
import imp
@@ -206,11 +207,7 @@
except ImportError:
pass
else:
- # The following check looks a bit odd. The trick is that
- # NullImporter throws ImportError if the supplied path is a
- # *valid* directory entry (and hence able to be handled
- # by the standard import machinery)
- importer = imp.NullImporter(path_name)
+ importer = None
cache[path_name] = importer
return importer
@@ -237,7 +234,7 @@
if run_name is None:
run_name = "<run_path>"
importer = _get_importer(path_name)
- if isinstance(importer, imp.NullImporter):
+ if isinstance(importer, (type(None), imp.NullImporter)):
# Not a valid sys.path entry, so run the code directly
# execfile() doesn't help as we want to allow compiled files
code = _get_code_from_file(path_name)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -14,9 +14,9 @@
sys.meta_path is found to be empty, raise ImportWarning.
- Issue #14605: No longer have implicit entries in sys.path_hooks. If
- sys.path_hooks is found to be empty, a warning will be raised. If None is
- found in sys.path_importer_cache, a warning is raised and a search on
- sys.path_hooks is attempted.
+ sys.path_hooks is found to be empty, a warning will be raised. None is now
+ inserted into sys.path_importer_cache if no finder was discovered. This also
+ means imp.NullImporter is no longer implicitly used.
- Issue #13903: Implement PEP 412. Individual dictionary instances can now share
their keys with other dictionaries. Classes take advantage of this to share
diff --git a/Modules/main.c b/Modules/main.c
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -224,7 +224,7 @@
if (importer == NULL)
goto error;
- if (importer->ob_type == &PyNullImporter_Type) {
+ if (importer == Py_None) {
Py_DECREF(argv0);
Py_DECREF(importer);
return -1;
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -1186,15 +1186,7 @@
PyErr_Clear();
}
if (importer == NULL) {
- importer = PyObject_CallFunctionObjArgs(
- (PyObject *)&PyNullImporter_Type, p, NULL
- );
- if (importer == NULL) {
- if (PyErr_ExceptionMatches(PyExc_ImportError)) {
- PyErr_Clear();
- return Py_None;
- }
- }
+ return Py_None;
}
if (importer != NULL) {
int err = PyDict_SetItem(path_importer_cache, p, importer);
diff --git a/Python/importlib.h b/Python/importlib.h
index c3a60ef62dd7e8c77ab350d680a441c60903d845..c4080da005e8b4c5facc10e8ed3aaee297a890c0
GIT binary patch
[stripped]
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list