Commit 09b86d11 authored by Brian Curtin's avatar Brian Curtin

Fix #14600. Correct reference handling and naming of ImportError convenience function

parent fba807ac
...@@ -229,27 +229,12 @@ in various ways. There is a separate error indicator for each thread. ...@@ -229,27 +229,12 @@ in various ways. There is a separate error indicator for each thread.
Similar to :c:func:`PyErr_SetFromWindowsErrWithFilename`, with an additional Similar to :c:func:`PyErr_SetFromWindowsErrWithFilename`, with an additional
parameter specifying the exception type to be raised. Availability: Windows. parameter specifying the exception type to be raised. Availability: Windows.
.. c:function:: PyObject* PyErr_SetExcWithArgsKwargs(PyObject *exc, PyObject *args, PyObject *kwargs) .. c:function:: PyObject* PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
This is a convenience function to set an *exc* with the given *args* and
*kwargs* values. If *args* is ``NULL``, an empty :func:`tuple` will be
created when *exc* is created via :c:func:`PyObject_Call`.
.. versionadded:: 3.3
.. c:function:: PyObject* PyErr_SetFromImportErrorWithName(PyObject *msg, PyObject *name)
This is a convenience function to raise :exc:`ImportError`. *msg* will be
set as the exception's message string, and *name* will be set as the
:exc:`ImportError`'s ``name`` attribute.
.. versionadded:: 3.3
.. c:function:: PyObject* PyErr_SetFromImportErrorWithNameAndPath(PyObject *msg, PyObject *name, PyObject *path)
This is a convenience function to raise :exc:`ImportError`. *msg* will be This is a convenience function to raise :exc:`ImportError`. *msg* will be
set as the exception's message string. Both *name* and *path* will be set set as the exception's message string. *name* and *path*, both of which can
as the :exc:`ImportError`'s respective ``name`` and ``path`` attributes. be ``NULL``, will be set as the :exc:`ImportError`'s respective ``name``
and ``path`` attributes.
.. versionadded:: 3.3 .. versionadded:: 3.3
......
...@@ -265,9 +265,8 @@ PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int); ...@@ -265,9 +265,8 @@ PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int);
PyAPI_FUNC(PyObject *) PyErr_SetExcWithArgsKwargs(PyObject *, PyObject *, PyAPI_FUNC(PyObject *) PyErr_SetExcWithArgsKwargs(PyObject *, PyObject *,
PyObject *); PyObject *);
PyAPI_FUNC(PyObject *) PyErr_SetFromImportErrorWithNameAndPath(PyObject *, PyAPI_FUNC(PyObject *) PyErr_SetImportError(PyObject *, PyObject *,
PyObject *, PyObject *); PyObject *);
PyAPI_FUNC(PyObject *) PyErr_SetFromImportErrorWithName(PyObject *, PyObject *);
/* Export the old function so that the existing API remains available: */ /* Export the old function so that the existing API remains available: */
PyAPI_FUNC(void) PyErr_BadInternalCall(void); PyAPI_FUNC(void) PyErr_BadInternalCall(void);
......
...@@ -254,9 +254,9 @@ dl_funcptr _PyImport_GetDynLoadWindows(const char *shortname, ...@@ -254,9 +254,9 @@ dl_funcptr _PyImport_GetDynLoadWindows(const char *shortname,
theLength)); theLength));
} }
if (message != NULL) { if (message != NULL) {
PyErr_SetFromImportErrorWithNameAndPath(message, PyErr_SetImportError(message, PyUnicode_FromString(shortname),
PyUnicode_FromString(shortname),
pathname); pathname);
Py_DECREF(message);
} }
return NULL; return NULL;
} else { } else {
......
...@@ -586,50 +586,43 @@ PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename( ...@@ -586,50 +586,43 @@ PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
#endif /* MS_WINDOWS */ #endif /* MS_WINDOWS */
PyObject * PyObject *
PyErr_SetExcWithArgsKwargs(PyObject *exc, PyObject *args, PyObject *kwargs) PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
{ {
PyObject *val; PyObject *args, *kwargs, *error;
/* args must at least be an empty tuple */ args = PyTuple_New(1);
if (args == NULL) if (args == NULL)
args = PyTuple_New(0); return NULL;
val = PyObject_Call(exc, args, kwargs);
if (val != NULL) {
PyErr_SetObject((PyObject *) Py_TYPE(val), val);
Py_DECREF(val);
}
kwargs = PyDict_New();
if (args == NULL)
return NULL; return NULL;
}
PyObject * if (name == NULL)
PyErr_SetFromImportErrorWithNameAndPath(PyObject *msg, name = Py_None;
PyObject *name, PyObject *path)
{
PyObject *args = PyTuple_New(1);
PyObject *kwargs = PyDict_New();
PyObject *result;
if (path == NULL) if (path == NULL)
path = Py_None; path = Py_None;
Py_INCREF(msg);
PyTuple_SetItem(args, 0, msg); PyTuple_SetItem(args, 0, msg);
PyDict_SetItemString(kwargs, "name", name); PyDict_SetItemString(kwargs, "name", name);
PyDict_SetItemString(kwargs, "path", path); PyDict_SetItemString(kwargs, "path", path);
result = PyErr_SetExcWithArgsKwargs(PyExc_ImportError, args, kwargs); /* args must at least be an empty tuple */
if (args == NULL)
args = PyTuple_New(0);
error = PyObject_Call(PyExc_ImportError, args, kwargs);
if (error!= NULL) {
PyErr_SetObject((PyObject *) Py_TYPE(error), error);
Py_DECREF(error);
}
Py_DECREF(args); Py_DECREF(args);
Py_DECREF(kwargs); Py_DECREF(kwargs);
return result; return NULL;
}
PyObject *
PyErr_SetFromImportErrorWithName(PyObject *msg, PyObject *name)
{
return PyErr_SetFromImportErrorWithNameAndPath(msg, name, NULL);
} }
void void
......
...@@ -2460,7 +2460,8 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, ...@@ -2460,7 +2460,8 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
PyObject *msg = PyUnicode_FromFormat("import of %R halted; " PyObject *msg = PyUnicode_FromFormat("import of %R halted; "
"None in sys.modules", abs_name); "None in sys.modules", abs_name);
if (msg != NULL) { if (msg != NULL) {
PyErr_SetFromImportErrorWithName(msg, abs_name); PyErr_SetImportError(msg, abs_name, NULL);
Py_DECREF(msg);
} }
mod = NULL; mod = NULL;
goto error_with_unlock; goto error_with_unlock;
......
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