[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