[Python-checkins] cpython: Issue #15767: back out 8a0ed9f63c6e, finishing the removal of

brett.cannon python-checkins at python.org
Fri Jul 5 00:16:36 CEST 2013


http://hg.python.org/cpython/rev/ee9662d77ebb
changeset:   84445:ee9662d77ebb
user:        Brett Cannon <brett at python.org>
date:        Thu Jul 04 17:51:50 2013 -0400
summary:
  Issue #15767: back out 8a0ed9f63c6e, finishing the removal of
ModuleNotFoundError.

files:
  Doc/c-api/exceptions.rst                         |    2 -
  Doc/library/exceptions.rst                       |   13 +-
  Doc/whatsnew/3.4.rst                             |    3 -
  Include/pyerrors.h                               |    1 -
  Lib/importlib/_bootstrap.py                      |   15 +-
  Lib/pydoc.py                                     |    2 +-
  Lib/test/exception_hierarchy.txt                 |    1 -
  Lib/test/test_exceptions.py                      |    3 +
  Lib/test/test_import.py                          |   25 +-
  Lib/test/test_importlib/import_/test_api.py      |    4 -
  Lib/test/test_importlib/import_/test_fromlist.py |    8 +-
  Lib/test/test_pydoc.py                           |    2 +-
  Lib/test/test_site.py                            |    2 +-
  Misc/NEWS                                        |    3 -
  Objects/exceptions.c                             |    9 -
  Python/ceval.c                                   |    2 +-
  Python/importlib.h                               |  744 +++++----
  17 files changed, 412 insertions(+), 427 deletions(-)


diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -686,8 +686,6 @@
 +-----------------------------------------+---------------------------------+----------+
 | :c:data:`PyExc_ImportError`             | :exc:`ImportError`              |          |
 +-----------------------------------------+---------------------------------+----------+
-| :c:data:`PyExc_ModuleNotFoundError`     | :exc:`ModuleNotFoundError`      |          |
-+-----------------------------------------+---------------------------------+----------+
 | :c:data:`PyExc_IndexError`              | :exc:`IndexError`               |          |
 +-----------------------------------------+---------------------------------+----------+
 | :c:data:`PyExc_InterruptedError`        | :exc:`InterruptedError`         |          |
diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -169,8 +169,8 @@
 
 .. exception:: ImportError
 
-   Raised when the :keyword:`import` statement has troubles trying to load a
-   module.
+   Raised when an :keyword:`import` statement fails to find the module definition
+   or when a ``from ... import`` fails to find a name that is to be imported.
 
    The :attr:`name` and :attr:`path` attributes can be set using keyword-only
    arguments to the constructor. When set they represent the name of the module
@@ -180,15 +180,6 @@
    .. versionchanged:: 3.3
       Added the :attr:`name` and :attr:`path` attributes.
 
-.. exception:: ModuleNotFoundError
-
-   A subclass of :exc:`ImportError` which is raised by :keyword:`import` when a
-   module could not be located. This includes ``from ... import`` statements as
-   the specific attribute being requested cannot be known a priori to be a module
-   or some other type of object.
-
-   .. versionadded:: 3.4
-
 
 .. exception:: IndexError
 
diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst
--- a/Doc/whatsnew/3.4.rst
+++ b/Doc/whatsnew/3.4.rst
@@ -137,9 +137,6 @@
 
 * Unicode database updated to UCD version 6.2.
 
-* Import now raises the new exception :exc:`ModuleNotFoundError` (subclass of
-  :exc:`ImportError`) when it cannot find something.
-
 * :func:`min` and :func:`max` now accept a *default* argument that can be used
   to specify the value they return if the iterable they are evaluating has no
   elements.  Contributed by Julian Berman in :issue:`18111`.
diff --git a/Include/pyerrors.h b/Include/pyerrors.h
--- a/Include/pyerrors.h
+++ b/Include/pyerrors.h
@@ -152,7 +152,6 @@
 PyAPI_DATA(PyObject *) PyExc_FloatingPointError;
 PyAPI_DATA(PyObject *) PyExc_OSError;
 PyAPI_DATA(PyObject *) PyExc_ImportError;
-PyAPI_DATA(PyObject *) PyExc_ModuleNotFoundError;
 PyAPI_DATA(PyObject *) PyExc_IndexError;
 PyAPI_DATA(PyObject *) PyExc_KeyError;
 PyAPI_DATA(PyObject *) PyExc_KeyboardInterrupt;
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -1556,7 +1556,11 @@
             raise ImportError(msg, name=name)
     loader = _find_module(name, path)
     if loader is None:
-        raise ModuleNotFoundError(_ERR_MSG.format(name), name=name)
+        exc = ImportError(_ERR_MSG.format(name), name=name)
+        # TODO(brett): switch to a proper ModuleNotFound exception in Python
+        # 3.4.
+        exc._not_found = True
+        raise exc
     elif name not in sys.modules:
         # The parent import may have already imported this module.
         loader.load_module(name)
@@ -1642,12 +1646,15 @@
                 from_name = '{}.{}'.format(module.__name__, x)
                 try:
                     _call_with_frames_removed(import_, from_name)
-                except ModuleNotFoundError as exc:
+                except ImportError as exc:
                     # Backwards-compatibility dictates we ignore failed
                     # imports triggered by fromlist for modules that don't
                     # exist.
-                    if exc.name == from_name:
-                        continue
+                    # TODO(brett): In Python 3.4, have import raise
+                    #   ModuleNotFound and catch that.
+                    if getattr(exc, '_not_found', False):
+                        if exc.name == from_name:
+                            continue
                     raise
     return module
 
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -316,7 +316,7 @@
         elif exc is SyntaxError:
             # A SyntaxError occurred before we could execute the module.
             raise ErrorDuringImport(value.filename, info)
-        elif issubclass(exc, ImportError) and value.name == path:
+        elif exc is ImportError and value.name == path:
             # No such module in the path.
             return None
         else:
diff --git a/Lib/test/exception_hierarchy.txt b/Lib/test/exception_hierarchy.txt
--- a/Lib/test/exception_hierarchy.txt
+++ b/Lib/test/exception_hierarchy.txt
@@ -13,7 +13,6 @@
       +-- BufferError
       +-- EOFError
       +-- ImportError
-           +-- ModuleNotFoundError
       +-- LookupError
       |    +-- IndexError
       |    +-- KeyError
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -953,5 +953,8 @@
             self.assertEqual(str(arg), str(exc))
 
 
+def test_main():
+    run_unittest(ExceptionTests, ImportErrorTests)
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py
--- a/Lib/test/test_import.py
+++ b/Lib/test/test_import.py
@@ -68,15 +68,7 @@
     def tearDown(self):
         unload(TESTFN)
 
-    def test_import_raises_ModuleNotFoundError(self):
-        with self.assertRaises(ModuleNotFoundError):
-            import something_that_should_not_exist_anywhere
-
-    def test_from_import_raises_ModuleNotFoundError(self):
-        with self.assertRaises(ModuleNotFoundError):
-            from something_that_should_not_exist_anywhere import blah
-        with self.assertRaises(ModuleNotFoundError):
-            from importlib import something_that_should_not_exist_anywhere
+    setUp = tearDown
 
     def test_case_sensitivity(self):
         # Brief digression to test that import is case-sensitive:  if we got
@@ -495,7 +487,7 @@
             header = f.read(12)
             code = marshal.load(f)
         constants = list(code.co_consts)
-        foreign_code = importlib.import_module.__code__
+        foreign_code = test_main.__code__
         pos = constants.index(1)
         constants[pos] = foreign_code
         code = type(code)(code.co_argcount, code.co_kwonlyargcount,
@@ -1021,5 +1013,16 @@
             importlib.SourceLoader.load_module = old_load_module
 
 
+def test_main(verbose=None):
+    run_unittest(ImportTests, PycacheTests, FilePermissionTests,
+                 PycRewritingTests, PathsTests, RelativeImportTests,
+                 OverridingImportBuiltinTests,
+                 ImportlibBootstrapTests,
+                 TestSymbolicallyLinkedPackage,
+                 ImportTracebackTests)
+
+
 if __name__ == '__main__':
-    unittest.main()
+    # Test needs to be a package, so we can do relative imports.
+    from test.test_import import test_main
+    test_main()
diff --git a/Lib/test/test_importlib/import_/test_api.py b/Lib/test/test_importlib/import_/test_api.py
--- a/Lib/test/test_importlib/import_/test_api.py
+++ b/Lib/test/test_importlib/import_/test_api.py
@@ -22,10 +22,6 @@
     """Test API-specific details for __import__ (e.g. raising the right
     exception when passing in an int for the module name)."""
 
-    def test_raises_ModuleNotFoundError(self):
-        with self.assertRaises(ModuleNotFoundError):
-            util.import_('some module that does not exist')
-
     def test_name_requires_rparition(self):
         # Raise TypeError if a non-string is passed in for the module name.
         with self.assertRaises(TypeError):
diff --git a/Lib/test/test_importlib/import_/test_fromlist.py b/Lib/test/test_importlib/import_/test_fromlist.py
--- a/Lib/test/test_importlib/import_/test_fromlist.py
+++ b/Lib/test/test_importlib/import_/test_fromlist.py
@@ -68,16 +68,16 @@
                 self.assertTrue(hasattr(module, 'module'))
                 self.assertEqual(module.module.__name__, 'pkg.module')
 
-    def test_module_from_package_triggers_ModuleNotFoundError(self):
-        # If a submodule causes an ModuleNotFoundError because it tries to import
-        # a module which doesn't exist, that should let the ModuleNotFoundError
+    def test_module_from_package_triggers_ImportError(self):
+        # If a submodule causes an ImportError because it tries to import
+        # a module which doesn't exist, that should let the ImportError
         # propagate.
         def module_code():
             import i_do_not_exist
         with util.mock_modules('pkg.__init__', 'pkg.mod',
                                module_code={'pkg.mod': module_code}) as importer:
             with util.import_state(meta_path=[importer]):
-                with self.assertRaises(ModuleNotFoundError) as exc:
+                with self.assertRaises(ImportError) as exc:
                     import_util.import_('pkg', fromlist=['mod'])
                 self.assertEqual('i_do_not_exist', exc.exception.name)
 
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -206,7 +206,7 @@
 missing_pattern = "no Python documentation found for '%s'"
 
 # output pattern for module with bad imports
-badimport_pattern = "problem in %s - ModuleNotFoundError: No module named %r"
+badimport_pattern = "problem in %s - ImportError: No module named %r"
 
 def run_pydoc(module_name, *args, **env):
     """
diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py
--- a/Lib/test/test_site.py
+++ b/Lib/test/test_site.py
@@ -131,7 +131,7 @@
             re.escape(os.path.join(pth_dir, pth_fn)))
         # XXX: ditto previous XXX comment.
         self.assertRegex(err_out.getvalue(), 'Traceback')
-        self.assertRegex(err_out.getvalue(), 'ModuleNotFoundError')
+        self.assertRegex(err_out.getvalue(), 'ImportError')
 
     @unittest.skipIf(sys.platform == "win32", "Windows does not raise an "
                       "error for file paths containing null characters")
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -25,9 +25,6 @@
 - Issue #18137: Detect integer overflow on precision in float.__format__()
   and complex.__format__().
 
-- Issue #15767: Introduce ModuleNotFoundError which is raised when a module
-  could not be found.
-
 - Issue #18183: Fix various unicode operations on strings with large unicode
   codepoints.
 
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -710,13 +710,6 @@
                         "module.");
 
 /*
- *    ModuleNotFoundError extends ImportError
- */
-
-MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError,
-                         "Module not found.");
-
-/*
  *    OSError extends Exception
  */
 
@@ -2402,7 +2395,6 @@
     PRE_INIT(SystemExit)
     PRE_INIT(KeyboardInterrupt)
     PRE_INIT(ImportError)
-    PRE_INIT(ModuleNotFoundError)
     PRE_INIT(OSError)
     PRE_INIT(EOFError)
     PRE_INIT(RuntimeError)
@@ -2473,7 +2465,6 @@
     POST_INIT(SystemExit)
     POST_INIT(KeyboardInterrupt)
     POST_INIT(ImportError)
-    POST_INIT(ModuleNotFoundError)
     POST_INIT(OSError)
     INIT_ALIAS(EnvironmentError, OSError)
     INIT_ALIAS(IOError, OSError)
diff --git a/Python/ceval.c b/Python/ceval.c
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -4588,7 +4588,7 @@
 
     x = PyObject_GetAttr(v, name);
     if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
-        PyErr_Format(PyExc_ModuleNotFoundError, "cannot import name %S", name);
+        PyErr_Format(PyExc_ImportError, "cannot import name %S", name);
     }
     return x;
 }
diff --git a/Python/importlib.h b/Python/importlib.h
--- a/Python/importlib.h
+++ b/Python/importlib.h
[stripped]

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list