(original) (raw)

changeset: 76582:7025ee00dbf6 parent: 76580:f90c735e7699 user: Brett Cannon brett@python.org date: Fri Apr 27 15:30:58 2012 -0400 files: Lib/importlib/_bootstrap.py Lib/importlib/test/import_/test_path.py Lib/runpy.py Misc/NEWS Modules/main.c Python/import.c Python/importlib.h description: Issue #14605: Use None in sys.path_importer_cache to represent no finder instead of using some (now non-existent) implicit finder. diff -r f90c735e7699 -r 7025ee00dbf6 Lib/importlib/_bootstrap.py --- a/Lib/importlib/_bootstrap.py Fri Apr 27 14:02:33 2012 -0400 +++ b/Lib/importlib/_bootstrap.py Fri Apr 27 15:30:58 2012 -0400 @@ -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 -r f90c735e7699 -r 7025ee00dbf6 Lib/importlib/test/import_/test_path.py --- a/Lib/importlib/test/import_/test_path.py Fri Apr 27 14:02:33 2012 -0400 +++ b/Lib/importlib/test/import_/test_path.py Fri Apr 27 15:30:58 2012 -0400 @@ -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 = '' - 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 -r f90c735e7699 -r 7025ee00dbf6 Lib/runpy.py --- a/Lib/runpy.py Fri Apr 27 14:02:33 2012 -0400 +++ b/Lib/runpy.py Fri Apr 27 15:30:58 2012 -0400 @@ -9,6 +9,7 @@ # Written by Nick Coghlan # 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 = "" 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 -r f90c735e7699 -r 7025ee00dbf6 Misc/NEWS --- a/Misc/NEWS Fri Apr 27 14:02:33 2012 -0400 +++ b/Misc/NEWS Fri Apr 27 15:30:58 2012 -0400 @@ -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 -r f90c735e7699 -r 7025ee00dbf6 Modules/main.c --- a/Modules/main.c Fri Apr 27 14:02:33 2012 -0400 +++ b/Modules/main.c Fri Apr 27 15:30:58 2012 -0400 @@ -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 -r f90c735e7699 -r 7025ee00dbf6 Python/import.c --- a/Python/import.c Fri Apr 27 14:02:33 2012 -0400 +++ b/Python/import.c Fri Apr 27 15:30:58 2012 -0400 @@ -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 -r f90c735e7699 -r 7025ee00dbf6 Python/importlib.h Binary file Python/importlib.h has changed/brett@python.org