Hey, So, the semantics for virGetVersion() are: - virGetVersion(&ver, NULL, NULL) returns the libvirt version only - virGetVersion(&ver, NULL, &xenVer) returns the libvirt version and the xen version - virGetVersion(&ver, "foo", &fooVer) returns the libvirt version and the version of the "foo" driver Now, your python version: - virGetVersion() isn't allowed - virGetVersion(None) returns the libvirt version only - virGetVersion("foo") returns the libvirt version and the version of the "foo" driver, or throws an exception if the driver isn't available I'd suggest: - virGetVersion() returns the libvirt version only, perhaps as a single integer - virGetVersion(None) returns the libvirt version and the Xen version, or throws an exception if xen isn't available - virGetVersion("foo") returns the libvirt version and the version of the "foo" driver, or throws an exception if the driver isn't available i.e. static PyObject * libvirt_virGetVersion (PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { char *type = NULL; unsigned long libVer, typeVer = 0; int noTypeVer = 0; int c_retval; if (PyTuple_Size(args) == 0) noTypeVer = 1 else if (!PyArg_ParseTuple (args, (char *) "z", &type)) return NULL; LIBVIRT_BEGIN_ALLOW_THREADS; if (noTypeVer) c_retval = virGetVersion (&libVer, NULL, NULL); else c_retval = virGetVersion (&libVer, type, &typeVer); LIBVIRT_END_ALLOW_THREADS; if (c_retval == -1) { Py_INCREF(Py_None); return (Py_None); } if (noTypeVer) return PyInt_FromLong(libVer); else return Py_BuildValue ((char *) "kk", libVer, typeVer); } Cheers, Mark.