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)