| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3e9a9ae commit 8f5ac51
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -292,6 +292,13 @@ in various ways. There is a separate error indicator for each thread. | |||
| 292 | 292 | ||
| 293 | 293 | .. versionadded:: 3.3 | |
| 294 | 294 | ||
| 295 | + .. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *msg, PyObject *name, PyObject *path) | ||
| 296 | + | ||
| 297 | + Much like :c:func:`PyErr_SetImportError` but this function allows for | ||
| 298 | + specifying a subclass of :exc:`ImportError` to raise. | ||
| 299 | + | ||
| 300 | + .. versionadded:: 3.4 | ||
| 301 | + | ||
| 295 | 302 | ||
| 296 | 303 | .. c:function:: void PyErr_SyntaxLocationEx(char *filename, int lineno, int col_offset) | |
| 297 | 304 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -185,7 +185,8 @@ The following exceptions are the exceptions that are usually raised. | |||
| 185 | 185 | A subclass of :exc:`ImportError` which is raised by :keyword:`import` when a | |
| 186 | 186 | module could not be located. This includes ``from ... import`` statements as | |
| 187 | 187 | the specific attribute being requested cannot be known a priori to be a module | |
| 188 | - or some other type of object. | ||
| 188 | + or some other type of object. It is also raised when ``None`` is found in | ||
| 189 | + :data:`sys.modules`. | ||
| 189 | 190 | ||
| 190 | 191 | .. versionadded:: 3.4 | |
| 191 | 192 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -37,7 +37,7 @@ use the standard import system. | |||
| 37 | 37 | ||
| 38 | 38 | When a module is first imported, Python searches for the module and if found, | |
| 39 | 39 | it creates a module object [#fnmo]_, initializing it. If the named module | |
| 40 | - cannot be found, an :exc:`ImportError` is raised. Python implements various | ||
| 40 | + cannot be found, an :exc:`ModuleNotFoundError` is raised. Python implements various | ||
| 41 | 41 | strategies to search for the named module when the import machinery is | |
| 42 | 42 | invoked. These strategies can be modified and extended by using various hooks | |
| 43 | 43 | described in the sections below. | |
@@ -168,7 +168,7 @@ arguments to the :keyword:`import` statement, or from the parameters to the | |||
| 168 | 168 | This name will be used in various phases of the import search, and it may be | |
| 169 | 169 | the dotted path to a submodule, e.g. ``foo.bar.baz``. In this case, Python | |
| 170 | 170 | first tries to import ``foo``, then ``foo.bar``, and finally ``foo.bar.baz``. | |
| 171 | - If any of the intermediate imports fail, an :exc:`ImportError` is raised. | ||
| 171 | + If any of the intermediate imports fail, an :exc:`ModuleNotFoundError` is raised. | ||
| 172 | 172 | ||
| 173 | 173 | ||
| 174 | 174 | The module cache | |
@@ -187,15 +187,15 @@ object. | |||
| 187 | 187 | During import, the module name is looked up in :data:`sys.modules` and if | |
| 188 | 188 | present, the associated value is the module satisfying the import, and the | |
| 189 | 189 | process completes. However, if the value is ``None``, then an | |
| 190 | - :exc:`ImportError` is raised. If the module name is missing, Python will | ||
| 190 | + :exc:`ModuleNotFoundError` is raised. If the module name is missing, Python will | ||
| 191 | 191 | continue searching for the module. | |
| 192 | 192 | ||
| 193 | 193 | :data:`sys.modules` is writable. Deleting a key may not destroy the | |
| 194 | 194 | associated module (as other modules may hold references to it), | |
| 195 | 195 | but it will invalidate the cache entry for the named module, causing | |
| 196 | 196 | Python to search anew for the named module upon its next | |
| 197 | 197 | import. The key can also be assigned to ``None``, forcing the next import | |
| 198 | - of the module to result in an :exc:`ImportError`. | ||
| 198 | + of the module to result in an :exc:`ModuleNotFoundError`. | ||
| 199 | 199 | ||
| 200 | 200 | Beware though, as if you keep a reference to the module object, | |
| 201 | 201 | invalidate its cache entry in :data:`sys.modules`, and then re-import the | |
@@ -284,7 +284,7 @@ handle the named module or not. | |||
| 284 | 284 | If the meta path finder knows how to handle the named module, it returns a | |
| 285 | 285 | loader object. If it cannot handle the named module, it returns ``None``. If | |
| 286 | 286 | :data:`sys.meta_path` processing reaches the end of its list without returning | |
| 287 | - a loader, then an :exc:`ImportError` is raised. Any other exceptions raised | ||
| 287 | + a loader, then an :exc:`ModuleNotFoundError` is raised. Any other exceptions raised | ||
| 288 | 288 | are simply propagated up, aborting the import process. | |
| 289 | 289 | ||
| 290 | 290 | The :meth:`find_module()` method of meta path finders is called with two | |
@@ -647,7 +647,7 @@ import statements within that module. | |||
| 647 | 647 | ||
| 648 | 648 | To selectively prevent import of some modules from a hook early on the | |
| 649 | 649 | meta path (rather than disabling the standard import system entirely), | |
| 650 | - it is sufficient to raise :exc:`ImportError` directly from | ||
| 650 | + it is sufficient to raise :exc:`ModuleNotFoundError` directly from | ||
| 651 | 651 | :meth:`find_module` instead of returning ``None``. The latter indicates | |
| 652 | 652 | that the meta path search should continue. while raising an exception | |
| 653 | 653 | terminates it immediately. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -269,3 +269,6 @@ that may require changes to your code. | |||
| 269 | 269 | * Frozen packages no longer set ``__path__`` to a list containg the package name | |
| 270 | 270 | but an empty list instead. Determing if a module is a package should be done | |
| 271 | 271 | using ``hasattr(module, '__path__')``. | |
| 272 | + | ||
| 273 | + * :c:func:`PyErr_SetImportError` now sets :exc:`TypeError` when its **msg** | ||
| 274 | + argument is not set. Previously only ``NULL`` was returned. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -268,6 +268,9 @@ PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int); | |||
| 268 | 268 | ||
| 269 | 269 | PyAPI_FUNC(PyObject *) PyErr_SetExcWithArgsKwargs(PyObject *, PyObject *, | |
| 270 | 270 | PyObject *); | |
| 271 | + | ||
| 272 | + PyAPI_FUNC(PyObject *) PyErr_SetImportErrorSubclass(PyObject *, PyObject *, | ||
| 273 | + PyObject *, PyObject *); | ||
| 271 | 274 | PyAPI_FUNC(PyObject *) PyErr_SetImportError(PyObject *, PyObject *, | |
| 272 | 275 | PyObject *); | |
| 273 | 276 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1614,7 +1614,7 @@ def _gcd_import(name, package=None, level=0): | |||
| 1614 | 1614 | _imp.release_lock() | |
| 1615 | 1615 | message = ("import of {} halted; " | |
| 1616 | 1616 | "None in sys.modules".format(name)) | |
| 1617 | - raise ImportError(message, name=name) | ||
| 1617 | + raise ModuleNotFoundError(message, name=name) | ||
| 1618 | 1618 | _lock_unlock_module(name) | |
| 1619 | 1619 | return module | |
| 1620 | 1620 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -443,6 +443,10 @@ Tests | |||
| 443 | 443 | C-API | |
| 444 | 444 | ----- | |
| 445 | 445 | ||
| 446 | + - Issue #15767: Added PyErr_SetImportErrorSubclass(). | ||
| 447 | + | ||
| 448 | + - PyErr_SetImportError() now sets TypeError when its msg argument is set. | ||
| 449 | + | ||
| 446 | 450 | - Issue #9369: The types of `char*` arguments of PyObject_CallFunction() and | |
| 447 | 451 | PyObject_CallMethod() now changed to `const char*`. Based on patches by | |
| 448 | 452 | Jörg Müller and Lars Buitinck. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -619,12 +619,25 @@ PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename( | |||
| 619 | 619 | #endif /* MS_WINDOWS */ | |
| 620 | 620 | ||
| 621 | 621 | PyObject * | |
| 622 | - PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) | ||
| 622 | + PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, | ||
| 623 | + PyObject *name, PyObject *path) | ||
| 623 | 624 | { | |
| 625 | + int issubclass; | ||
| 624 | 626 | PyObject *args, *kwargs, *error; | |
| 625 | 627 | ||
| 626 | - if (msg == NULL) | ||
| 628 | + issubclass = PyObject_IsSubclass(exception, PyExc_ImportError); | ||
| 629 | + if (issubclass < 0) { | ||
| 630 | + return NULL; | ||
| 631 | + } | ||
| 632 | + else if (!issubclass) { | ||
| 633 | + PyErr_SetString(PyExc_TypeError, "expected a subclass of ImportError"); | ||
| 634 | + return NULL; | ||
| 635 | + } | ||
| 636 | + | ||
| 637 | + if (msg == NULL) { | ||
| 638 | + PyErr_SetString(PyExc_TypeError, "expected a message argument"); | ||
| 627 | 639 | return NULL; | |
| 640 | + } | ||
| 628 | 641 | ||
| 629 | 642 | args = PyTuple_New(1); | |
| 630 | 643 | if (args == NULL) | |
@@ -649,7 +662,7 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) | |||
| 649 | 662 | PyDict_SetItemString(kwargs, "name", name); | |
| 650 | 663 | PyDict_SetItemString(kwargs, "path", path); | |
| 651 | 664 | ||
| 652 | - error = PyObject_Call(PyExc_ImportError, args, kwargs); | ||
| 665 | + error = PyObject_Call(exception, args, kwargs); | ||
| 653 | 666 | if (error != NULL) { | |
| 654 | 667 | PyErr_SetObject((PyObject *)Py_TYPE(error), error); | |
| 655 | 668 | Py_DECREF(error); | |
@@ -661,6 +674,12 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) | |||
| 661 | 674 | return NULL; | |
| 662 | 675 | } | |
| 663 | 676 | ||
| 677 | + PyObject * | ||
| 678 | + PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) | ||
| 679 | + { | ||
| 680 | + return PyErr_SetImportErrorSubclass(PyExc_ImportError, msg, name, path); | ||
| 681 | + } | ||
| 682 | + | ||
| 664 | 683 | void | |
| 665 | 684 | _PyErr_BadInternalCall(const char *filename, int lineno) | |
| 666 | 685 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1436,7 +1436,8 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, | |||
| 1436 | 1436 | PyObject *msg = PyUnicode_FromFormat("import of %R halted; " | |
| 1437 | 1437 | "None in sys.modules", abs_name); | |
| 1438 | 1438 | if (msg != NULL) { | |
| 1439 | - PyErr_SetImportError(msg, abs_name, NULL); | ||
| 1439 | + PyErr_SetImportErrorSubclass(PyExc_ModuleNotFoundError, msg, | ||
| 1440 | + abs_name, NULL); | ||
| 1440 | 1441 | Py_DECREF(msg); | |
| 1441 | 1442 | } | |
| 1442 | 1443 | mod = NULL; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3239,8 +3239,8 @@ const unsigned char _Py_M__importlib[] = { | |||
| 3239 | 3239 | 0,114,64,1,0,0,114,59,1,0,0,114,96,0,0,0, | |
| 3240 | 3240 | 114,56,1,0,0,114,7,0,0,0,114,145,0,0,0,114, | |
| 3241 | 3241 | 69,1,0,0,244,11,0,0,0,95,103,99,100,95,105,109, | |
| 3242 | - 112,111,114,116,114,97,0,0,0,114,46,0,0,0,114,156, | ||
| 3243 | - 0,0,0,114,98,0,0,0,40,5,0,0,0,114,66,0, | ||
| 3242 | + 112,111,114,116,114,97,0,0,0,114,46,0,0,0,114,66, | ||
| 3243 | + 1,0,0,114,98,0,0,0,40,5,0,0,0,114,66,0, | ||
| 3244 | 3244 | 0,0,114,57,1,0,0,114,58,1,0,0,114,160,0,0, | |
| 3245 | 3245 | 0,114,139,0,0,0,114,4,0,0,0,114,4,0,0,0, | |
| 3246 | 3246 | 114,5,0,0,0,114,70,1,0,0,61,6,0,0,115,26, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments