diff options
-rw-r--r-- | Doc/c-api/exceptions.rst | 2 | ||||
-rw-r--r-- | Doc/library/exceptions.rst | 13 | ||||
-rw-r--r-- | Include/pyerrors.h | 1 | ||||
-rw-r--r-- | Lib/_compat_pickle.py | 7 | ||||
-rw-r--r-- | Lib/test/exception_hierarchy.txt | 1 | ||||
-rw-r--r-- | Lib/test/test_pickle.py | 8 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Objects/exceptions.c | 9 |
8 files changed, 42 insertions, 2 deletions
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 226b619..5644410 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -782,6 +782,8 @@ 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` | | diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 1747efe..a428f51 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -170,8 +170,9 @@ The following exceptions are the exceptions that are usually raised. .. exception:: ImportError - 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. + Raised when the :keyword:`import` statement has troubles trying to + load a module. Also raised when the "from list" in ``from ... import`` + has a name that cannot be found. 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 @@ -181,6 +182,14 @@ 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. It is also raised when ``None`` + is found in :data:`sys.modules`. + + .. versionadded:: 3.6 + .. exception:: IndexError diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 35aedb7..6bc3ca7 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -160,6 +160,7 @@ 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; diff --git a/Lib/_compat_pickle.py b/Lib/_compat_pickle.py index c0e0443..f68496a 100644 --- a/Lib/_compat_pickle.py +++ b/Lib/_compat_pickle.py @@ -242,3 +242,10 @@ PYTHON3_OSERROR_EXCEPTIONS = ( for excname in PYTHON3_OSERROR_EXCEPTIONS: REVERSE_NAME_MAPPING[('builtins', excname)] = ('exceptions', 'OSError') + +PYTHON3_IMPORTERROR_EXCEPTIONS = ( + 'ModuleNotFoundError', +) + +for excname in PYTHON3_IMPORTERROR_EXCEPTIONS: + REVERSE_NAME_MAPPING[('builtins', excname)] = ('exceptions', 'ImportError') diff --git a/Lib/test/exception_hierarchy.txt b/Lib/test/exception_hierarchy.txt index 0513765..7333b2a 100644 --- a/Lib/test/exception_hierarchy.txt +++ b/Lib/test/exception_hierarchy.txt @@ -14,6 +14,7 @@ BaseException +-- BufferError +-- EOFError +-- ImportError + +-- ModuleNotFoundError +-- LookupError | +-- IndexError | +-- KeyError diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py index 05203e5..e6c5d08 100644 --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -335,6 +335,9 @@ class CompatPickleTests(unittest.TestCase): if (module2, name2) == ('exceptions', 'OSError'): attr = getattribute(module3, name3) self.assertTrue(issubclass(attr, OSError)) + elif (module2, name2) == ('exceptions', 'ImportError'): + attr = getattribute(module3, name3) + self.assertTrue(issubclass(attr, ImportError)) else: module, name = mapping(module2, name2) if module3[:1] != '_': @@ -401,6 +404,11 @@ class CompatPickleTests(unittest.TestCase): if exc is not OSError and issubclass(exc, OSError): self.assertEqual(reverse_mapping('builtins', name), ('exceptions', 'OSError')) + elif exc is not ImportError and issubclass(exc, ImportError): + self.assertEqual(reverse_mapping('builtins', name), + ('exceptions', 'ImportError')) + self.assertEqual(mapping('exceptions', name), + ('exceptions', name)) else: self.assertEqual(reverse_mapping('builtins', name), ('exceptions', name)) @@ -8043,6 +8043,9 @@ 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. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 336c32c..6fb5eb7 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -706,6 +706,13 @@ ComplexExtendsException(PyExc_Exception, ImportError, "module."); /* + * ModuleNotFoundError extends ImportError + */ + +MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError, + "Module not found."); + +/* * OSError extends Exception */ @@ -2469,6 +2476,7 @@ _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) @@ -2541,6 +2549,7 @@ _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) |