Extending & Embedding Python Using C - Exceptions |
Written by Mike James | |||||||
Monday, 30 October 2023 | |||||||
Page 3 of 3
Raising ExceptionsAs well as passing exceptions raised by other functions back to the Python system, you can also quite easily raise exceptions directly using; void PyErr_SetString(PyObject *type, const char *message) where type is one of the standard exceptions with names starting PyExc_, such as PyExc_ZeroDivisionError and message is a UTF-8 C string that specifies the error message. For example, we can raise our own division-by-zero exception using: static PyObject *exception2(PyObject *self, If you compile his and try it out: import example you will see: A Dummy divide error has occurred You can raise any of the builtin exceptions and warnings in the same way. You can also create your own exception classes by inheriting from Exception. Creating classes and inheritance is covered in Chapters 11 and 12 but it is very straight forward. However there is a shortcut in the form of the PyObject *PyErr_NewException(const char *name, PyObject *base, PyObject *dict) The second and third parameters are usually set to NULL to accept the default base class, Exception, and dict. A new class is created and this can be added to the module and used in the same way as a built in exception class. For example: static PyObject *myCustomException; PyMODINIT_FUNC PyInit_example(void) This adds a new class to the module and uses the technique for adding attributes to a module described in detail in Chapter 11. All you need to understand at this stage is that we have created a new exception class called myCustomException and stored it in a global variable of the same name and added it as an attribute to the module. Notice that the adding the attribute to the module is also an example of passing an exception up to the Python system. The new exception class can be used by the C extension module and Python programs that import it. For example: static PyObject *exception3(PyObject *self, This raises the new exception with a suitable error message. A Python program that makes use of this function and the new exception is: try: The result is: A Custom error has occurred There is also a range of API functions designed to make it easier to raise common errors. Handling ExceptionsIn most cases you are probably going to pass the exception on to the Python system but you can handle it in the C function if you can. If you handle the exception then you have to clean up anything that the function that raised the exception created before clearing the error using: void PyErr_Clear() Don’t clear the error unless you have cleaned up after the function that raised it. Of course if you are calling a C function you can deal with any errors it returns in the usual way – you don’t need to worry about Python exceptions unless you want to raise one to signal the error to the Python system. Handling an exception can be as easy as calling PyErr_Clear for example: static PyObject *exception3(PyObject *self, In this case all we have to do is test for the error, clear the exception and try again. What if you only want to handle particular types of exception? There are two functions that can help with this:
The first tests to see if the current exception matches exc, i.e. is an instance or a derived type. If exc is a tuple all classes are tested. The given parameter specifies a class to compare exc to. PyErr_ExceptionMatches should only be called when an exception is actually raised. You can discover if an exception is raised using:
It returns NULL if there is no exception or the exception object without incrementing its reference count. For example, to test specifically for division by zero and only handling the exception if it is: static PyObject *exception5(PyObject *self, Notice that if the exception is anything except a division-by zero-error it is passed back to the Python system.
In chapter but not in this extract
Summary
Extending & Embedding Python Using CBy Mike JamesBuy from Amazon. ContentsPreface
<ASIN:B0CK3X93KF> To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.
Comments
or email your comment to: comments@i-programmer.info |
|||||||
Last Updated ( Saturday, 04 November 2023 ) |