[Libvir] Python bindings, errors & exceptions

Richard W.M. Jones rjones at redhat.com
Fri Mar 23 12:12:56 UTC 2007


I'm really confused about how the Python bindings are supposed to handle 
errors.  Can someone explain how this is supposed to work?

Case in point: currently virt-manager fails because conn.listNetworks () 
returns None, whereas virt-manager is expecting it to return a list of 
network objects.  The code returns None because the underlying calls 
(either virConnectNumOfNetworks or virConnectListNetworks) is failing.

The functions in question are:

   class virConnect:			# libvirtclass.py
     # ...
     def listNetworks(self):
         """list the networks, stores the pointers to the names in
            @names """
         ret = libvirtmod.virConnectListNetworks(self._o)
         return ret

(the above code is automatically generated by generator.py), and:

   static PyObject *			// libvir.c
   libvirt_virConnectListNetworks(PyObject *self ATTRIBUTE_UNUSED,
			       PyObject *args) {
     PyObject *py_retval;
     char **names = NULL;
     int c_retval, i;
     virConnectPtr conn;
     PyObject *pyobj_conn;

	// ...

     c_retval = virConnectNumOfNetworks(conn);
     if (c_retval < 0) {
         Py_INCREF(Py_None);
         return (Py_None);
     }

	// ...

     py_retval = PyList_New(c_retval);

     if (names) {
         for (i = 0;i < c_retval;i++) {
             PyList_SetItem(py_retval, i, 
libvirt_constcharPtrWrap(names[i]));
             free(names[i]);
         }
         free(names);
     }

     return(py_retval);
   }

(I've omitted some code to make the general idea clearer).

The upshot is that if the underlying functions fail, at no point is an 
exception thrown.

This is not always the case.  For other functions which return C 
structure pointers (eg. libvirt.open which wraps virConnectOpen), the 
bindings automatically catch the invalid return and throw an exception. 
  For example:

   def open(name):			# libvirtclass.py
     """This function should be called first to get a connection to
        the Hypervisor and xen store """
     ret = libvirtmod.virConnectOpen(name)
     if ret is None:raise libvirtError('virConnectOpen() failed')
     return virConnect(_obj=ret)

It is my view that all errors in C code should turn into Python exceptions.

One way to do that would be to have a Python virterror handler which 
just directly throws the exception.  I don't know if this is safe 
because the exception would unwind through C code, and in some languages 
that is safe, in others it is not.

Another way would be to have a Python virterror handler which remembers 
that an exception happened, and after each auto-generated function call 
we check this and raise the exception.  Since I'm just starting out in 
Python, I don't know if there are thread or other issues with this.

Comments would be welcome.

Rich.

-- 
Emerging Technologies, Red Hat  http://et.redhat.com/~rjones/
64 Baker Street, London, W1U 7DF     Mobile: +44 7866 314 421
  "[Negative numbers] darken the very whole doctrines of the equations
  and make dark of the things which are in their nature excessively
  obvious and simple" (Francis Maseres FRS, mathematician, 1759)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3237 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20070323/58956997/attachment-0001.bin>


More information about the libvir-list mailing list