# HG changeset patch # User Filip GruszczyƄski # Date 1299444591 -3600 # Node ID c5677e9539d46aedb7b2824c172f6eb992501ecf # Parent 88fe1ac4846005a0b060a89bb39658f4d789d3ed early draft of patch for issue #1559549 diff -r 88fe1ac48460 -r c5677e9539d4 Include/pyerrors.h --- a/Include/pyerrors.h Mon Mar 07 08:31:52 2011 +0100 +++ b/Include/pyerrors.h Sun Mar 06 21:49:51 2011 +0100 @@ -47,6 +47,12 @@ PyObject *filename; } PyEnvironmentErrorObject; +typedef struct { + PyException_HEAD + PyObject *msg; + PyObject *module; +} PyImportErrorObject; + #ifdef MS_WINDOWS typedef struct { PyException_HEAD diff -r 88fe1ac48460 -r c5677e9539d4 Objects/exceptions.c --- a/Objects/exceptions.c Mon Mar 07 08:31:52 2011 +0100 +++ b/Objects/exceptions.c Sun Mar 06 21:49:51 2011 +0100 @@ -544,11 +544,91 @@ "Program interrupted by user."); + + /* * ImportError extends Exception */ -SimpleExtendsException(PyExc_Exception, ImportError, - "Import can't find module, or can't find name in module."); + +static int +ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *msg = NULL; + PyObject *module = NULL; + + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) + return -1; + + if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) { + return 0; + } + + if (!PyArg_UnpackTuple(args, "ImportError", 2, 2, + &msg, &module)) { + return -1; + } + + Py_CLEAR(self->module); /* replacing */ + self->module = module; + Py_INCREF(self->module); + + Py_CLEAR(self->msg); /* replacing */ + self->msg = msg; + Py_INCREF(self->msg); + + return 0; +} + +static int +ImportError_clear(PyImportErrorObject *self) +{ + Py_CLEAR(self->module); + return BaseException_clear((PyBaseExceptionObject *)self); +} + +static void +ImportError_dealloc(PyImportErrorObject *self) +{ + _PyObject_GC_UNTRACK(self); + ImportError_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +ImportError_traverse(PyImportErrorObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->module); + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); +} + +static PyObject * +ImportError_str(PyImportErrorObject *self) +{ + if (self->msg) + return self->msg; + else + return BaseException_str((PyBaseExceptionObject *)self); +} + +static PyMemberDef ImportError_members[] = { + {"msg", T_OBJECT, offsetof(PyImportErrorObject, msg), 0, + PyDoc_STR("exception message")}, + {"module", T_OBJECT, offsetof(PyImportErrorObject, module), 0, + PyDoc_STR("exception module")}, + {NULL} /* Sentinel */ +}; + +static PyMethodDef ImportError_methods[] = { + {NULL} +}; + + +ComplexExtendsException(PyExc_Exception, ImportError, + ImportError, ImportError_dealloc, + ImportError_methods, ImportError_members, + ImportError_str, + "Import can't find module, or can't find name in " + "module."); /* diff -r 88fe1ac48460 -r c5677e9539d4 Python/import.c --- a/Python/import.c Mon Mar 07 08:31:52 2011 +0100 +++ b/Python/import.c Sun Mar 06 21:49:51 2011 +0100 @@ -2768,8 +2768,14 @@ if (result == Py_None) { Py_DECREF(result); - PyErr_Format(PyExc_ImportError, - "No module named %.200s", name); + PyObject *message = PyUnicode_FromFormat("No module named %.200s", name); + PyObject *module = PyUnicode_DecodeASCII(name, strlen(name), "strict"); + PyObject *value = Py_BuildValue("(OO)", message, module); + Py_DECREF(message); + Py_DECREF(module); + + PyErr_SetObject(PyExc_ImportError, value); + Py_DECREF(value); return NULL; } # HG changeset patch # User Filip GruszczyƄski # Date 1299497443 -3600 # Node ID 648a9ea7e04b7fe2ecd682e4f029c72e7c354df6 # Parent c5677e9539d46aedb7b2824c172f6eb992501ecf improving patch for issue #1559549 according to Trundle comments diff -r c5677e9539d4 -r 648a9ea7e04b Objects/exceptions.c --- a/Objects/exceptions.c Sun Mar 06 21:49:51 2011 +0100 +++ b/Objects/exceptions.c Mon Mar 07 12:30:43 2011 +0100 @@ -559,7 +559,7 @@ if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) return -1; - if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) { + if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 2) { return 0; } @@ -583,6 +583,7 @@ ImportError_clear(PyImportErrorObject *self) { Py_CLEAR(self->module); + Py_CLEAR(self->msg); return BaseException_clear((PyBaseExceptionObject *)self); } @@ -598,14 +599,17 @@ ImportError_traverse(PyImportErrorObject *self, visitproc visit, void *arg) { Py_VISIT(self->module); + Py_VISIT(self->msg); return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } static PyObject * ImportError_str(PyImportErrorObject *self) { - if (self->msg) + if (self->msg) { + Py_INCREF(self->msg); return self->msg; + } else return BaseException_str((PyBaseExceptionObject *)self); } diff -r c5677e9539d4 -r 648a9ea7e04b Python/import.c --- a/Python/import.c Sun Mar 06 21:49:51 2011 +0100 +++ b/Python/import.c Mon Mar 07 12:30:43 2011 +0100 @@ -2769,10 +2769,19 @@ if (result == Py_None) { Py_DECREF(result); PyObject *message = PyUnicode_FromFormat("No module named %.200s", name); - PyObject *module = PyUnicode_DecodeASCII(name, strlen(name), "strict"); + if (message == NULL) + return NULL; + PyObject *module = PyUnicode_DecodeUTF8(name, strlen(name), "strict"); + if (module == NULL){ + Py_DECREF(message); + return NULL; + } + PyObject *value = Py_BuildValue("(OO)", message, module); Py_DECREF(message); Py_DECREF(module); + if (value == NULL) + return NULL; PyErr_SetObject(PyExc_ImportError, value); Py_DECREF(value);