Python bindings, errors & exceptions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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)

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]