On Mon, Dec 22, 2008 at 10:06 AM, <chojra...@gmail.com> wrote: > On Mon, Dec 22, 2008 at 03:29, Guilherme Polo <ggp...@gmail.com> wrote: >> On Sun, Dec 21, 2008 at 11:02 PM, <chojra...@gmail.com> wrote: >>> Hello, >>> >>> I'm trying to implement custom exception that have to carry some >>> useful info by means of instance members, to be used like: >>> >>> try: >>> // some code >>> except MyException, data: >>> // use data.errorcode, data.errorcategory, data.errorlevel, >>> data.errormessage and some others >>> >>> The question is - how to implement the instance variables with >>> PyErr_NewException? >> >> Using PyErr_NewException is fine. You must understand that an >> exception is a class, and thus PyErr_NewException creates one for you >> and returns it. >> Just like you would do with a class that has __dict__, set some >> attributes to what you want. That is, use PyObject_SetAttrString or >> something more appropriated for you. > > Ok so I did the following. In init function (forget refcounting and > error checking for a moment ;-) > > PyObject *dict = PyDict_New(); > PyDict_SetItemString(dict, "errorcode", PyInt_FromLong(0)); > static PyObject *myexception = > PyErr_NewException("module.MyException", NULL, dict);
You do not really have to create a dict here, one will be created for you if you pass a NULL there. > PyModule_AddObject(module, "MyException", myexception); > > It worked more or less as expected, the help shown: > > | ---------------------------------------------------------------------- > | Data and other attributes defined here: > | > | errorcode = 0 > | > | ---------------------------------------------------------------------- > > Then I did the following when raising the exception: > > PyObject_SetAttrString(myexception, "errorcode", PyInt_FromLong(111)); > PyErr_SetString(myexception, "Bad thing happened"); > return NULL; > > and the test code was: > try: > do_bad_thing(); > except MyException, data: > > and you surely already guessed it -- data.errorcode was 0.... Not only > that, module.MyException.errorcode was also 0... > > What I'm doing wrong? I certainly don't get the idea of exceptions in > Python, especially what is being raised - a class or an instance? There are two forms raise can take, both will end up involving a class and a intsance. > If > the latter - how's the class instantiated? You can call a class to instantiate it. > If not - what about values > in different threads? The docs are so vague about that... > > > Thanks again in advance, > Chojrak > Again, an exception is a class, so you could create a new type in C, and do anything you wanted. But you probably don't want to create a new type to achieve this, so there are two simple ways I'm going to paste below: #include "Python.h" static PyObject *MyErr; static PyMethodDef module_methods[] = { {"raise_test", (PyCFunction)raise_test, METH_NOARGS, NULL}, {NULL}, }; PyMODINIT_FUNC initfancy_exc(void) { PyObject *m; m = Py_InitModule("fancy_exc", module_methods); if (m == NULL) return; MyErr = PyErr_NewException("fancy_exc.err", NULL, NULL); Py_INCREF(MyErr); if (PyModule_AddObject(m, "err", MyErr) < 0) return; } the raise_test function is missing, pick one of these: static PyObject * raise_test(PyObject *self) { PyObject_SetAttrString(MyErr, "code", PyInt_FromLong(42)); PyObject_SetAttrString(MyErr, "category", PyString_FromString("nice one")); PyErr_SetString(MyErr, "All is good, I hope"); return NULL; } or static PyObject * raise_test(PyObject *self) { PyObject *t = PyTuple_New(3); PyTuple_SetItem(t, 0, PyString_FromString("error message")); PyTuple_SetItem(t, 1, PyInt_FromLong(10)); PyTuple_SetItem(t, 2, PyString_FromString("category name here")); PyErr_SetObject(MyErr, t); Py_DECREF(t); return NULL; } In this second form you check for the args attribute of the exception. -- -- Guilherme H. Polo Goncalves _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com