From 09b86d1196427f2028d7e072b106847d8c693815 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Tue, 17 Apr 2012 16:57:09 -0500 Subject: [PATCH] Fix #14600. Correct reference handling and naming of ImportError convenience function --- Doc/c-api/exceptions.rst | 23 +++------------- Include/pyerrors.h | 5 ++-- Python/dynload_win.c | 6 ++-- Python/errors.c | 59 ++++++++++++++++++---------------------- Python/import.c | 3 +- 5 files changed, 37 insertions(+), 59 deletions(-) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index d081ff69ff2..877249bc635 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -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 parameter specifying the exception type to be raised. Availability: Windows. -.. c:function:: PyObject* PyErr_SetExcWithArgsKwargs(PyObject *exc, PyObject *args, PyObject *kwargs) - - 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) +.. c:function:: PyObject* PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) 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 - set as the exception's message string. Both *name* and *path* will be set - as the :exc:`ImportError`'s respective ``name`` and ``path`` attributes. + set as the exception's message string. *name* and *path*, both of which can + be ``NULL``, will be set as the :exc:`ImportError`'s respective ``name`` + and ``path`` attributes. .. versionadded:: 3.3 diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 5aacf7ac8a0..458420aa323 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -265,9 +265,8 @@ PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int); PyAPI_FUNC(PyObject *) PyErr_SetExcWithArgsKwargs(PyObject *, PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyErr_SetFromImportErrorWithNameAndPath(PyObject *, - PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyErr_SetFromImportErrorWithName(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetImportError(PyObject *, PyObject *, + PyObject *); /* Export the old function so that the existing API remains available: */ PyAPI_FUNC(void) PyErr_BadInternalCall(void); diff --git a/Python/dynload_win.c b/Python/dynload_win.c index ef3e2c5958a..7bf3dfc811a 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -254,9 +254,9 @@ dl_funcptr _PyImport_GetDynLoadWindows(const char *shortname, theLength)); } if (message != NULL) { - PyErr_SetFromImportErrorWithNameAndPath(message, - PyUnicode_FromString(shortname), - pathname); + PyErr_SetImportError(message, PyUnicode_FromString(shortname), + pathname); + Py_DECREF(message); } return NULL; } else { diff --git a/Python/errors.c b/Python/errors.c index 345a345afe4..a49cde62479 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -586,50 +586,43 @@ PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename( #endif /* MS_WINDOWS */ PyObject * -PyErr_SetExcWithArgsKwargs(PyObject *exc, PyObject *args, PyObject *kwargs) +PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) { - PyObject *val; + PyObject *args, *kwargs, *error; + + args = PyTuple_New(1); + if (args == NULL) + return NULL; + + kwargs = PyDict_New(); + if (args == NULL) + return NULL; + + if (name == NULL) + name = Py_None; + + if (path == NULL) + path = Py_None; + + Py_INCREF(msg); + PyTuple_SetItem(args, 0, msg); + PyDict_SetItemString(kwargs, "name", name); + PyDict_SetItemString(kwargs, "path", path); /* args must at least be an empty tuple */ if (args == NULL) args = PyTuple_New(0); - val = PyObject_Call(exc, args, kwargs); - if (val != NULL) { - PyErr_SetObject((PyObject *) Py_TYPE(val), val); - Py_DECREF(val); + error = PyObject_Call(PyExc_ImportError, args, kwargs); + if (error!= NULL) { + PyErr_SetObject((PyObject *) Py_TYPE(error), error); + Py_DECREF(error); } - return NULL; -} - -PyObject * -PyErr_SetFromImportErrorWithNameAndPath(PyObject *msg, - PyObject *name, PyObject *path) -{ - PyObject *args = PyTuple_New(1); - PyObject *kwargs = PyDict_New(); - PyObject *result; - - if (path == NULL) - path = Py_None; - - PyTuple_SetItem(args, 0, msg); - PyDict_SetItemString(kwargs, "name", name); - PyDict_SetItemString(kwargs, "path", path); - - result = PyErr_SetExcWithArgsKwargs(PyExc_ImportError, args, kwargs); - Py_DECREF(args); Py_DECREF(kwargs); - return result; -} - -PyObject * -PyErr_SetFromImportErrorWithName(PyObject *msg, PyObject *name) -{ - return PyErr_SetFromImportErrorWithNameAndPath(msg, name, NULL); + return NULL; } void diff --git a/Python/import.c b/Python/import.c index 584f30eb381..f3de7d82627 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2460,7 +2460,8 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, PyObject *msg = PyUnicode_FromFormat("import of %R halted; " "None in sys.modules", abs_name); if (msg != NULL) { - PyErr_SetFromImportErrorWithName(msg, abs_name); + PyErr_SetImportError(msg, abs_name, NULL); + Py_DECREF(msg); } mod = NULL; goto error_with_unlock;