On Mon, Dec 22, 2008 at 10:45 AM, Guilherme Polo <ggp...@gmail.com> wrote: > 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
By creating a type I mean one that involves defining a tp_init, and everything else your type needs, not about the simple one created by PyErr_NewException. > , 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 > -- -- 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