Skip to content

Commit 679ecb5

Browse files
committed
Issue #15767: back out 8a0ed9f63c6e, finishing the removal of
ModuleNotFoundError.
1 parent 82da888 commit 679ecb5

File tree

17 files changed

+412
-427
lines changed

17 files changed

+412
-427
lines changed

Doc/c-api/exceptions.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -686,8 +686,6 @@ the variables:
686686
+-----------------------------------------+---------------------------------+----------+
687687
| :c:data:`PyExc_ImportError` | :exc:`ImportError` | |
688688
+-----------------------------------------+---------------------------------+----------+
689-
| :c:data:`PyExc_ModuleNotFoundError` | :exc:`ModuleNotFoundError` | |
690-
+-----------------------------------------+---------------------------------+----------+
691689
| :c:data:`PyExc_IndexError` | :exc:`IndexError` | |
692690
+-----------------------------------------+---------------------------------+----------+
693691
| :c:data:`PyExc_InterruptedError` | :exc:`InterruptedError` | |

Doc/library/exceptions.rst

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ The following exceptions are the exceptions that are usually raised.
169169

170170
.. exception:: ImportError
171171

172-
Raised when the :keyword:`import` statement has troubles trying to load a
173-
module.
172+
Raised when an :keyword:`import` statement fails to find the module definition
173+
or when a ``from ... import`` fails to find a name that is to be imported.
174174

175175
The :attr:`name` and :attr:`path` attributes can be set using keyword-only
176176
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.
180180
.. versionchanged:: 3.3
181181
Added the :attr:`name` and :attr:`path` attributes.
182182

183-
.. exception:: ModuleNotFoundError
184-
185-
A subclass of :exc:`ImportError` which is raised by :keyword:`import` when a
186-
module could not be located. This includes ``from ... import`` statements as
187-
the specific attribute being requested cannot be known a priori to be a module
188-
or some other type of object.
189-
190-
.. versionadded:: 3.4
191-
192183

193184
.. exception:: IndexError
194185

Doc/whatsnew/3.4.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,6 @@ Some smaller changes made to the core Python language are:
137137

138138
* Unicode database updated to UCD version 6.2.
139139

140-
* Import now raises the new exception :exc:`ModuleNotFoundError` (subclass of
141-
:exc:`ImportError`) when it cannot find something.
142-
143140
* :func:`min` and :func:`max` now accept a *default* argument that can be used
144141
to specify the value they return if the iterable they are evaluating has no
145142
elements. Contributed by Julian Berman in :issue:`18111`.

Include/pyerrors.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ PyAPI_DATA(PyObject *) PyExc_EOFError;
152152
PyAPI_DATA(PyObject *) PyExc_FloatingPointError;
153153
PyAPI_DATA(PyObject *) PyExc_OSError;
154154
PyAPI_DATA(PyObject *) PyExc_ImportError;
155-
PyAPI_DATA(PyObject *) PyExc_ModuleNotFoundError;
156155
PyAPI_DATA(PyObject *) PyExc_IndexError;
157156
PyAPI_DATA(PyObject *) PyExc_KeyError;
158157
PyAPI_DATA(PyObject *) PyExc_KeyboardInterrupt;

Lib/importlib/_bootstrap.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,11 @@ def _find_and_load_unlocked(name, import_):
15561556
raise ImportError(msg, name=name)
15571557
loader = _find_module(name, path)
15581558
if loader is None:
1559-
raise ModuleNotFoundError(_ERR_MSG.format(name), name=name)
1559+
exc = ImportError(_ERR_MSG.format(name), name=name)
1560+
# TODO(brett): switch to a proper ModuleNotFound exception in Python
1561+
# 3.4.
1562+
exc._not_found = True
1563+
raise exc
15601564
elif name not in sys.modules:
15611565
# The parent import may have already imported this module.
15621566
loader.load_module(name)
@@ -1642,12 +1646,15 @@ def _handle_fromlist(module, fromlist, import_):
16421646
from_name = '{}.{}'.format(module.__name__, x)
16431647
try:
16441648
_call_with_frames_removed(import_, from_name)
1645-
except ModuleNotFoundError as exc:
1649+
except ImportError as exc:
16461650
# Backwards-compatibility dictates we ignore failed
16471651
# imports triggered by fromlist for modules that don't
16481652
# exist.
1649-
if exc.name == from_name:
1650-
continue
1653+
# TODO(brett): In Python 3.4, have import raise
1654+
# ModuleNotFound and catch that.
1655+
if getattr(exc, '_not_found', False):
1656+
if exc.name == from_name:
1657+
continue
16511658
raise
16521659
return module
16531660

Lib/pydoc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ def safeimport(path, forceload=0, cache={}):
316316
elif exc is SyntaxError:
317317
# A SyntaxError occurred before we could execute the module.
318318
raise ErrorDuringImport(value.filename, info)
319-
elif issubclass(exc, ImportError) and value.name == path:
319+
elif exc is ImportError and value.name == path:
320320
# No such module in the path.
321321
return None
322322
else:

Lib/test/exception_hierarchy.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ BaseException
1313
+-- BufferError
1414
+-- EOFError
1515
+-- ImportError
16-
+-- ModuleNotFoundError
1716
+-- LookupError
1817
| +-- IndexError
1918
| +-- KeyError

Lib/test/test_exceptions.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,5 +953,8 @@ def test_non_str_argument(self):
953953
self.assertEqual(str(arg), str(exc))
954954

955955

956+
def test_main():
957+
run_unittest(ExceptionTests, ImportErrorTests)
958+
956959
if __name__ == '__main__':
957960
unittest.main()

Lib/test/test_import.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,7 @@ def setUp(self):
6868
def tearDown(self):
6969
unload(TESTFN)
7070

71-
def test_import_raises_ModuleNotFoundError(self):
72-
with self.assertRaises(ModuleNotFoundError):
73-
import something_that_should_not_exist_anywhere
74-
75-
def test_from_import_raises_ModuleNotFoundError(self):
76-
with self.assertRaises(ModuleNotFoundError):
77-
from something_that_should_not_exist_anywhere import blah
78-
with self.assertRaises(ModuleNotFoundError):
79-
from importlib import something_that_should_not_exist_anywhere
71+
setUp = tearDown
8072

8173
def test_case_sensitivity(self):
8274
# Brief digression to test that import is case-sensitive: if we got
@@ -495,7 +487,7 @@ def test_foreign_code(self):
495487
header = f.read(12)
496488
code = marshal.load(f)
497489
constants = list(code.co_consts)
498-
foreign_code = importlib.import_module.__code__
490+
foreign_code = test_main.__code__
499491
pos = constants.index(1)
500492
constants[pos] = foreign_code
501493
code = type(code)(code.co_argcount, code.co_kwonlyargcount,
@@ -1021,5 +1013,16 @@ def load_module(*args):
10211013
importlib.SourceLoader.load_module = old_load_module
10221014

10231015

1016+
def test_main(verbose=None):
1017+
run_unittest(ImportTests, PycacheTests, FilePermissionTests,
1018+
PycRewritingTests, PathsTests, RelativeImportTests,
1019+
OverridingImportBuiltinTests,
1020+
ImportlibBootstrapTests,
1021+
TestSymbolicallyLinkedPackage,
1022+
ImportTracebackTests)
1023+
1024+
10241025
if __name__ == '__main__':
1025-
unittest.main()
1026+
# Test needs to be a package, so we can do relative imports.
1027+
from test.test_import import test_main
1028+
test_main()

Lib/test/test_importlib/import_/test_api.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ class APITest(unittest.TestCase):
2222
"""Test API-specific details for __import__ (e.g. raising the right
2323
exception when passing in an int for the module name)."""
2424

25-
def test_raises_ModuleNotFoundError(self):
26-
with self.assertRaises(ModuleNotFoundError):
27-
util.import_('some module that does not exist')
28-
2925
def test_name_requires_rparition(self):
3026
# Raise TypeError if a non-string is passed in for the module name.
3127
with self.assertRaises(TypeError):

0 commit comments

Comments
 (0)