Commit 679ecb56 authored by Brett Cannon's avatar Brett Cannon

Issue #15767: back out 8a0ed9f63c6e, finishing the removal of

ModuleNotFoundError.
parent 82da8886
......@@ -686,8 +686,6 @@ the variables:
+-----------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_ImportError` | :exc:`ImportError` | |
+-----------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_ModuleNotFoundError` | :exc:`ModuleNotFoundError` | |
+-----------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_IndexError` | :exc:`IndexError` | |
+-----------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_InterruptedError` | :exc:`InterruptedError` | |
......
......@@ -169,8 +169,8 @@ The following exceptions are the exceptions that are usually raised.
.. 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 @@ The following exceptions are the exceptions that are usually raised.
.. 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
......
......@@ -137,9 +137,6 @@ Some smaller changes made to the core Python language are:
* 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`.
......
......@@ -152,7 +152,6 @@ PyAPI_DATA(PyObject *) PyExc_EOFError;
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;
......
......@@ -1556,7 +1556,11 @@ def _find_and_load_unlocked(name, import_):
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 @@ def _handle_fromlist(module, fromlist, import_):
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
......
......@@ -316,7 +316,7 @@ def safeimport(path, forceload=0, cache={}):
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:
......
......@@ -13,7 +13,6 @@ BaseException
+-- BufferError
+-- EOFError
+-- ImportError
+-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
......
......@@ -953,5 +953,8 @@ class ImportErrorTests(unittest.TestCase):
self.assertEqual(str(arg), str(exc))
def test_main():
run_unittest(ExceptionTests, ImportErrorTests)
if __name__ == '__main__':
unittest.main()
......@@ -68,15 +68,7 @@ class ImportTests(unittest.TestCase):
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 @@ func_filename = func.__code__.co_filename
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 @@ class ImportTracebackTests(unittest.TestCase):
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()
......@@ -22,10 +22,6 @@ class APITest(unittest.TestCase):
"""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):
......
......@@ -68,16 +68,16 @@ class HandlingFromlist(unittest.TestCase):
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)
......
......@@ -206,7 +206,7 @@ expected_html_data_docstrings = tuple(s.replace(' ', ' ')
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):
"""
......
......@@ -131,7 +131,7 @@ class HelperFunctionsTests(unittest.TestCase):
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")
......
......@@ -25,9 +25,6 @@ Core and Builtins
- 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.
......
......@@ -709,13 +709,6 @@ ComplexExtendsException(PyExc_Exception, ImportError,
"Import can't find module, or can't find name in "
"module.");
/*
* ModuleNotFoundError extends ImportError
*/
MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError,
"Module not found.");
/*
* OSError extends Exception
*/
......@@ -2402,7 +2395,6 @@ _PyExc_Init(PyObject *bltinmod)
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 @@ _PyExc_Init(PyObject *bltinmod)
POST_INIT(SystemExit)
POST_INIT(KeyboardInterrupt)
POST_INIT(ImportError)
POST_INIT(ModuleNotFoundError)
POST_INIT(OSError)
INIT_ALIAS(EnvironmentError, OSError)
INIT_ALIAS(IOError, OSError)
......
......@@ -4588,7 +4588,7 @@ import_from(PyObject *v, PyObject *name)
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;
}
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment