WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH,RFC]: libxl python binding

To: Xen Devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH,RFC]: libxl python binding
From: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
Date: Tue, 7 Sep 2010 15:28:00 +0100
Cc: Ian Campbell <Ian.Campbell@xxxxxxxxxxxxx>, Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>, Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Delivery-date: Tue, 07 Sep 2010 07:30:56 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Attached patch is the first-cut of a libxl python binding. Presently
only list_domains, domid_to_name, domain_shutdown and domain_destroy are
implemented. The code takes advantage of Ian Campbells libxl IDL work to
make 178 lines of python generate 4,460 lines of boilerplate.

All that remains is:
 - support marshalling of other than integer types
 - call auto-generated C destructors when python objects are free'd
 - flatten out unions, structs etc. for libxl-type marshalling
 - manually implement a xen.lowlevel.xl.ctx method for each libxl function

Here's an example of what current code can do:

$ sudo python
>>> from xen.lowlevel import xl
>>> xl
<module 'xen.lowlevel.xl' from 
'/usr/lib/python2.6/dist-packages/xen/lowlevel/xl.so'>
>>> dir(xl)
['Error', '__doc__', '__file__', '__name__', '__package__', 'ctx', 
'device_console', 'device_disk', 'device_model_info', 'device_net2', 
'device_nic', 'device_pci', 'device_vfb', 'device_vkb', 'diskinfo', 
'domain_build_info', 'domain_build_state', 'domain_create_info', 'dominfo', 
'file_reference', 'net2info', 'nicinfo', 'physinfo', 'poolinfo', 
'sched_credit', 'vcpuinfo', 'version_info', 'vminfo']
>>> ctx = xl.ctx()
>>> dir(ctx)
['domain_destroy', 'domain_shutdown', 'domid_to_name', 'list_domains']
>>> ctx.list_domains()
[<xen.lowlevel.xl.dominfo object at 0x7f6765492a08>, <xen.lowlevel.xl.dominfo 
object at 0x7f6765492a50>, <xen.lowlevel.xl.dominfo object at 0x7f6765492a98>]
>>> map(lambda x:x.domid, ctx.list_domains())
[0L, 133L, 136L]
>>> map(ctx.domid_to_name, map(lambda x:x.domid, ctx.list_domains()))
['Domain-0', 'netbsd', 'lenny']
>>> ctx.domain_destroy(136)
>>> map(ctx.domid_to_name, map(lambda x:x.domid, ctx.list_domains()))
['Domain-0', 'netbsd']

-----

 tools/python/genwrap.py             |  178 +++++++++++++++++++++++
 tools/python/xen/lowlevel/xl/xl.c   |  269 ++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl.idl               |   10 -
 tools/libxl/libxltypes.py           |   23 ++-
 tools/python/Makefile               |    1 
 tools/python/setup.py               |   19 ++
 6 files changed, 486 insertions(+), 14 deletions(-)

----8<-----------------------------------------------------------------
diff -r d11a52daace3 tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl     Mon Sep 06 15:16:03 2010 +0100
+++ b/tools/libxl/libxl.idl     Tue Sep 07 15:22:24 2010 +0100
@@ -6,11 +6,11 @@
 libxl_ctx = Builtin("ctx")
 libxl_uuid = Builtin("uuid")
 libxl_mac = Builtin("mac")
-libxl_qemu_machine_type = Builtin("qemu_machine_type")
-libxl_console_consback = Builtin("console_consback")
-libxl_console_constype = Builtin("console_constype")
-libxl_disk_phystype = Builtin("disk_phystype")
-libxl_nic_type = Builtin("nic_type")
+libxl_qemu_machine_type = Number("qemu_machine_type", namespace="libxl_")
+libxl_console_consback = Number("console_consback", namespace="libxl_")
+libxl_console_constype = Number("console_constype", namespace="libxl_")
+libxl_disk_phystype = Number("disk_phystype", namespace="libxl_")
+libxl_nic_type = Number("nic_type", namespace="libxl_")
 
 libxl_string_list = Builtin("string_list", 
destructor_fn="libxl_string_list_destroy", passby=PASS_BY_REFERENCE)
 libxl_key_value_list = Builtin("key_value_list", 
destructor_fn="libxl_key_value_list_destroy", passby=PASS_BY_REFERENCE)
diff -r d11a52daace3 tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py Mon Sep 06 15:16:03 2010 +0100
+++ b/tools/libxl/libxltypes.py Tue Sep 07 15:22:24 2010 +0100
@@ -14,10 +14,13 @@ class Type(object):
 
         if typename is None: # Anonymous type
             self.typename = None
+            self.rawname = None
         elif self.namespace is None: # e.g. system provided types
             self.typename = typename
+            self.rawname = typename
         else:
             self.typename = self.namespace + typename
+            self.rawname = typename
 
         if self.typename is not None:
             self.destructor_fn = kwargs.setdefault('destructor_fn', 
self.typename + "_destroy")
@@ -32,11 +35,17 @@ class Builtin(Type):
         kwargs.setdefault('destructor_fn', None)
         Type.__init__(self, typename, **kwargs)
 
-class UInt(Type):
+class Number(Builtin):
+    def __init__(self, ctype, **kwargs):
+        kwargs.setdefault('namespace', None)
+        kwargs.setdefault('destructor_fn', None)
+        Builtin.__init__(self, ctype, **kwargs)
+
+class UInt(Number):
     def __init__(self, w, **kwargs):
         kwargs.setdefault('namespace', None)
         kwargs.setdefault('destructor_fn', None)
-        Type.__init__(self, "uint%d_t" % w, **kwargs)
+        Number.__init__(self, "uint%d_t" % w, **kwargs)
 
         self.width = w
 
@@ -128,12 +137,12 @@ class Reference(Type):
 
 void = Builtin("void *", namespace = None)
 bool = Builtin("bool", namespace = None)
-size_t = Builtin("size_t", namespace = None)
+size_t = Number("size_t", namespace = None)
 
-integer = Builtin("int", namespace = None)
-unsigned_integer = Builtin("unsigned int", namespace = None)
-unsigned = Builtin("unsigned int", namespace = None)
-unsigned_long = Builtin("unsigned long", namespace = None)
+integer = Number("int", namespace = None)
+unsigned_integer = Number("unsigned int", namespace = None)
+unsigned = Number("unsigned int", namespace = None)
+unsigned_long = Number("unsigned long", namespace = None)
 
 uint8 = UInt(8)
 uint16 = UInt(16)
diff -r d11a52daace3 tools/python/Makefile
--- a/tools/python/Makefile     Mon Sep 06 15:16:03 2010 +0100
+++ b/tools/python/Makefile     Tue Sep 07 15:22:24 2010 +0100
@@ -59,6 +59,7 @@ refresh-po: $(POTFILE)
 
 .PHONY: install
 install: install-messages install-dtd
+       PYTHONPATH=$(XEN_ROOT)/tools/libxl $(PYTHON) genwrap.py 
$(XEN_ROOT)/tools/libxl/libxl.idl __pyxl_types.h
        CC="$(CC)" CFLAGS="$(CFLAGS)" $(PYTHON) setup.py install \
                $(PYTHON_PREFIX_ARG) --root="$(DESTDIR)" --force
 
diff -r d11a52daace3 tools/python/genwrap.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/genwrap.py   Tue Sep 07 15:22:24 2010 +0100
@@ -0,0 +1,178 @@
+#!/usr/bin/python
+
+import sys
+import re
+
+import libxltypes
+
+def py_wrapstruct(ty):
+    l = []
+    l.append("typedef struct {")
+    l.append("    PyObject_HEAD;")
+    l.append("    %s obj;"%ty.typename);
+    l.append("}Py_%s;"%ty.rawname)
+    l.append("")
+    return "\n".join(l) + "\n\n"
+
+def py_type(ty):
+    if ty == libxltypes.bool or isinstance(ty, libxltypes.BitField) and 
ty.width == 1:
+        return "Bool"
+    if isinstance(ty, libxltypes.Number):
+        # FIXME: support unsigned properly
+        return "Int"
+    if ty == libxltypes.string:
+        return "String"
+    return None
+
+def py_attrib_get(ty, f):
+    if f.name == None:
+        return ""
+    t = py_type(f.type)
+    l = []
+    l.append("static PyObject *py_%s_%s_get(Py_%s *self, void 
*priv)"%(ty.rawname, f.name, ty.rawname))
+    l.append("{")
+    if t == "Int":
+        l.append("    return PyLong_FromUnsignedLong(self->obj.%s);"%f.name)
+    else:
+        l.append("    // %s"%t)
+        l.append("    return NULL;")
+    l.append("}")
+    return '\n'.join(l) + "\n\n"
+
+def py_attrib_set(ty, f):
+    if f.name == None:
+        return ""
+    t = py_type(f.type)
+    l = []
+    l.append("static int py_%s_%s_set(Py_%s *self, PyObject *v, void 
*priv)"%(ty.rawname, f.name, ty.rawname))
+    l.append("{")
+    if t == "Int":
+        l.append("    self->obj.%s = PyLong_AsLongLong(v);"%f.name)
+        l.append("    return 0;")
+    else:
+        l.append("    // %s"%t)
+        l.append("    return -1;")
+    l.append("}")
+    return '\n'.join(l) + "\n\n"
+
+def py_object_def(ty):
+    l = []
+    funcs="""
+static void Py%s_dealloc(Py_%s *self)
+{
+    self->ob_type->tp_free((PyObject *)self);
+}
+
+static int Py%s_init(Py_%s *self, PyObject *args, PyObject *kwds)
+{
+    return 0;
+}
+
+static PyObject *Py%s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    Py_%s *self = (Py_%s *)type->tp_alloc(type, 0);
+    if (self == NULL)
+        return NULL;
+    memset(&self->obj, 0, sizeof(self->obj));
+    return (PyObject *)self;
+}
+"""%tuple(ty.rawname for x in range(7))
+
+    l.append("static PyGetSetDef Py%s_getset[] = {"%ty.rawname)
+    for f in ty.fields:
+        if f.name == None:
+            continue
+        l.append("    { .name = \"%s\", "%f.name)
+        l.append("      .get = (getter)py_%s_%s_get, "%(ty.rawname, f.name))
+        l.append("      .set = (setter)py_%s_%s_set },"%(ty.rawname, f.name))
+    l.append("    { .name = NULL }")
+    l.append("};")
+    struct="""
+static PyTypeObject Py%s_Type= {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    PKG ".%s",
+    sizeof(Py_%s),
+    0,
+    (destructor)Py%s_dealloc,     /* tp_dealloc        */
+    NULL,                         /* tp_print          */
+    NULL,                         /* tp_getattr        */
+    NULL,                         /* tp_setattr        */
+    NULL,                         /* tp_compare        */
+    NULL,                         /* tp_repr           */
+    NULL,                         /* tp_as_number      */
+    NULL,                         /* tp_as_sequence    */
+    NULL,                         /* tp_as_mapping     */
+    NULL,                         /* tp_hash           */
+    NULL,                         /* tp_call           */
+    NULL,                         /* tp_str            */
+    NULL,                         /* tp_getattro       */
+    NULL,                         /* tp_setattro       */
+    NULL,                         /* tp_as_buffer      */
+    Py_TPFLAGS_DEFAULT,           /* tp_flags          */
+    "%s",                         /* tp_doc            */
+    NULL,                         /* tp_traverse       */
+    NULL,                         /* tp_clear          */
+    NULL,                         /* tp_richcompare    */
+    0,                            /* tp_weaklistoffset */
+    NULL,                         /* tp_iter           */
+    NULL,                         /* tp_iternext       */
+    NULL,                         /* tp_methods        */
+    NULL,                         /* tp_members        */
+    Py%s_getset,                  /* tp_getset         */
+    NULL,                         /* tp_base           */
+    NULL,                         /* tp_dict           */
+    NULL,                         /* tp_descr_get      */
+    NULL,                         /* tp_descr_set      */
+    0,                            /* tp_dictoffset     */
+    (initproc)Py%s_init,          /* tp_init           */
+    NULL,                         /* tp_alloc          */
+    Py%s_new,                     /* tp_new            */
+};
+
+"""%tuple(ty.rawname for x in range(8))
+    return funcs + '\n'.join(l) + "\n\n" + struct
+
+def py_initfuncs(types):
+    l = []
+    l.append("static void gentypes__init(PyObject *m)")
+    l.append("{")
+    for ty in types:
+        l.append("    if (PyType_Ready(&Py%s_Type) >= 0) {"%ty.rawname)
+        l.append("        Py_INCREF(&Py%s_Type);"%ty.rawname)
+        l.append("        PyModule_AddObject(m, \"%s\", (PyObject 
*)&Py%s_Type);"%(ty.rawname, ty.rawname))
+        l.append("    }")
+    l.append("}")
+    return '\n'.join(l) + "\n\n"
+
+if __name__ == '__main__':
+    if len(sys.argv) < 3:
+        print >>sys.stderr, "Usage: genwrap.py <idl> <pythonwrapper>"
+        sys.exit(1)
+
+    idl = sys.argv[1]
+    (_,types) = libxltypes.parse(idl)
+ 
+    wrapper = sys.argv[2]
+    f = open(wrapper, "w")
+    f.write("""#ifndef __PYXL_TYPES_H
+#define __PYXL_TYPES_H
+
+/*
+ * DO NOT EDIT.
+ *
+ * This file is autogenerated by
+ * "%s"
+ */
+ 
+""" % " ".join(sys.argv))
+    for ty in types:
+        f.write("/* Attribute get/set functions for %s */\n"%ty.typename)
+        f.write(py_wrapstruct(ty))
+        for a in ty.fields:
+            f.write(py_attrib_get(ty,a))
+            f.write(py_attrib_set(ty,a))
+        f.write(py_object_def(ty))
+    f.write(py_initfuncs(types))
+    f.write("""#endif /* __PYXL_TYPES_H */\n""")
+    f.close()
diff -r d11a52daace3 tools/python/setup.py
--- a/tools/python/setup.py     Mon Sep 06 15:16:03 2010 +0100
+++ b/tools/python/setup.py     Tue Sep 07 15:22:24 2010 +0100
@@ -9,14 +9,23 @@ extra_compile_args  = [ "-fno-strict-ali
 include_dirs = [ XEN_ROOT + "/tools/libxc",
                  XEN_ROOT + "/tools/xenstore",
                  XEN_ROOT + "/tools/include",
+                 XEN_ROOT + "/tools/libxl",
                  ]
 
 library_dirs = [ XEN_ROOT + "/tools/libxc",
                  XEN_ROOT + "/tools/xenstore",
+                 XEN_ROOT + "/tools/libxl",
+                 XEN_ROOT + "/tools/blktap2/control",
                  ]
 
 libraries = [ "xenctrl", "xenguest", "xenstore" ]
 
+plat = os.uname()[0]
+if plat == 'Linux':
+    uuid_libs = ["uuid"]
+else:
+    uuid_libs = []
+
 xc = Extension("xc",
                extra_compile_args = extra_compile_args,
                include_dirs       = include_dirs + [ "xen/lowlevel/xc" ],
@@ -83,8 +92,14 @@ netlink = Extension("netlink",
                     sources            = [ "xen/lowlevel/netlink/netlink.c",
                                            
"xen/lowlevel/netlink/libnetlink.c"])
 
-modules = [ xc, xs, ptsname, acm, flask ]
-plat = os.uname()[0]
+xl = Extension("xl",
+               extra_compile_args = extra_compile_args,
+               include_dirs       = include_dirs + [ "xen/lowlevel/xl" ],
+               library_dirs       = library_dirs,
+               libraries          = libraries + ["xenlight", "blktapctl" ] + 
uuid_libs,
+               sources            = [ "xen/lowlevel/xl/xl.c" ])
+
+modules = [ xc, xs, ptsname, acm, flask, xl ]
 if plat == 'SunOS':
     modules.extend([ scf, process ])
 if plat == 'Linux':
diff -r d11a52daace3 tools/python/xen/lowlevel/xl/xl.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/lowlevel/xl/xl.c Tue Sep 07 15:22:24 2010 +0100
@@ -0,0 +1,269 @@
+/******************************************************************************
+ * xl.c
+ * 
+ * Copyright (c) 2010 Citrix Ltd.
+ * Author: Gianni Tedesco
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of version 2.1 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <Python.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <arpa/inet.h>
+#include <xenctrl.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+
+#include <libxl.h>
+#include <libxl_utils.h>
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+/* Needed for Python versions earlier than 2.3. */
+#ifndef PyMODINIT_FUNC
+#define PyMODINIT_FUNC DL_EXPORT(void)
+#endif
+
+#define PKG "xen.lowlevel.xl"
+#define CLS "ctx"
+
+static PyObject *xl_error_obj;
+
+#include "_pyxl_types.h"
+
+typedef struct {
+    PyObject_HEAD;
+    libxl_ctx ctx;
+    xentoollog_logger_stdiostream *logger;
+    xentoollog_level minmsglevel;
+} XlObject;
+
+static PyObject *pyxl_list_domains(XlObject *self)
+{
+    libxl_dominfo *cur, *info;
+    PyObject *list;
+    int nr_dom, i;
+
+    info = libxl_list_domain(&self->ctx, &nr_dom);
+    if ( NULL == info )
+        return PyList_New(0);
+
+    list = PyList_New(nr_dom);
+    if ( NULL == list )
+        goto err_mem;
+
+    for(i = 0, cur = info; i < nr_dom; i++, cur++) {
+        Py_dominfo *di;
+        di = (Py_dominfo *)Pydominfo_new(&Pydominfo_Type, NULL, NULL);
+        if ( NULL == di )
+            goto err_mem;
+        memcpy(&di->obj, cur, sizeof(di->obj));
+        PyList_SetItem(list, i, (PyObject *)di);
+    }
+
+    free(info);
+    return list;
+err_mem:
+    Py_DECREF(list);
+    PyErr_SetString(PyExc_MemoryError, "Allocating domain list");
+    return NULL;
+}
+
+static PyObject *pyxl_domid_to_name(XlObject *self, PyObject *args)
+{
+    char *domname;
+    int domid;
+    PyObject *ret;
+
+    if ( !PyArg_ParseTuple(args, "i", &domid) )
+        return NULL;
+
+    domname = libxl_domid_to_name(&self->ctx, domid);
+    ret = PyString_FromString(domname);
+    free(domname);
+
+    return ret;
+}
+
+static PyObject *pyxl_domain_shutdown(XlObject *self, PyObject *args)
+{
+    int domid, req = 0;
+    if ( !PyArg_ParseTuple(args, "i|i", &domid, &req) )
+        return NULL;
+    if ( libxl_domain_shutdown(&self->ctx, domid, req) ) {
+        PyErr_SetString(xl_error_obj, "cannot shutdown domain");
+        return NULL;
+    }
+    return Py_None;
+}
+
+static PyObject *pyxl_domain_destroy(XlObject *self, PyObject *args)
+{
+    int domid, force = 1;
+    if ( !PyArg_ParseTuple(args, "i|i", &domid, &force) )
+        return NULL;
+    if ( libxl_domain_destroy(&self->ctx, domid, force) ) {
+        PyErr_SetString(xl_error_obj, "cannot destroy domain");
+        return NULL;
+    }
+    return Py_None;
+}
+
+static PyMethodDef pyxl_methods[] = {
+    {"list_domains", (PyCFunction)pyxl_list_domains, METH_NOARGS,
+         "List domains"},
+    {"domid_to_name", (PyCFunction)pyxl_domid_to_name, METH_VARARGS,
+         "Retrieve name from domain-id"},
+    {"domain_shutdown", (PyCFunction)pyxl_domain_shutdown, METH_VARARGS,
+         "Shutdown a domain"},
+    {"domain_destroy", (PyCFunction)pyxl_domain_destroy, METH_VARARGS,
+         "Destroy a domain"},
+    { NULL, NULL, 0, NULL }
+};
+
+static PyObject *PyXl_getattr(PyObject *obj, char *name)
+{
+    return Py_FindMethod(pyxl_methods, obj, name);
+}
+
+static PyObject *PyXl_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    XlObject *self = (XlObject *)type->tp_alloc(type, 0);
+
+    if (self == NULL)
+        return NULL;
+
+    memset(&self->ctx, 0, sizeof(self->ctx));
+    self->logger = NULL;
+    self->minmsglevel = XTL_PROGRESS;
+
+    return (PyObject *)self;
+}
+
+static int
+PyXl_init(XlObject *self, PyObject *args, PyObject *kwds)
+{
+    self->logger = xtl_createlogger_stdiostream(stderr, self->minmsglevel,  0);
+    if (!self->logger) {
+        PyErr_SetString(xl_error_obj, "cannot init xl logger");
+        return -1;
+    }
+
+    if ( libxl_ctx_init(&self->ctx, LIBXL_VERSION,
+                (xentoollog_logger*)self->logger) ) {
+        PyErr_SetString(xl_error_obj, "cannot init xl context");
+        return -1;
+    }
+
+    return 0;
+}
+
+static void PyXl_dealloc(XlObject *self)
+{
+    libxl_ctx_free(&self->ctx);
+    if ( self->logger )
+        xtl_logger_destroy((xentoollog_logger*)self->logger);
+
+    self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyTypeObject PyXlType = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    PKG "." CLS,
+    sizeof(XlObject),
+    0,
+    (destructor)PyXl_dealloc,     /* tp_dealloc        */
+    NULL,                         /* tp_print          */
+    PyXl_getattr,                 /* tp_getattr        */
+    NULL,                         /* tp_setattr        */
+    NULL,                         /* tp_compare        */
+    NULL,                         /* tp_repr           */
+    NULL,                         /* tp_as_number      */
+    NULL,                         /* tp_as_sequence    */
+    NULL,                         /* tp_as_mapping     */
+    NULL,                         /* tp_hash           */
+    NULL,                         /* tp_call           */
+    NULL,                         /* tp_str            */
+    NULL,                         /* tp_getattro       */
+    NULL,                         /* tp_setattro       */
+    NULL,                         /* tp_as_buffer      */
+    Py_TPFLAGS_DEFAULT,           /* tp_flags          */
+    "libxenlight connection",     /* tp_doc            */
+    NULL,                         /* tp_traverse       */
+    NULL,                         /* tp_clear          */
+    NULL,                         /* tp_richcompare    */
+    0,                            /* tp_weaklistoffset */
+    NULL,                         /* tp_iter           */
+    NULL,                         /* tp_iternext       */
+    pyxl_methods,                 /* tp_methods        */
+    NULL,                         /* tp_members        */
+    NULL,                         /* tp_getset         */
+    NULL,                         /* tp_base           */
+    NULL,                         /* tp_dict           */
+    NULL,                         /* tp_descr_get      */
+    NULL,                         /* tp_descr_set      */
+    0,                            /* tp_dictoffset     */
+    (initproc)PyXl_init,          /* tp_init           */
+    NULL,                         /* tp_alloc          */
+    PyXl_new,                     /* tp_new            */
+};
+
+static PyMethodDef xl_methods[] = { { NULL } };
+
+PyMODINIT_FUNC initxl(void)
+{
+    PyObject *m;
+
+    if (PyType_Ready(&PyXlType) < 0)
+        return;
+
+    m = Py_InitModule(PKG, xl_methods);
+
+    if (m == NULL)
+      return;
+
+    xl_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
+
+    Py_INCREF(&PyXlType);
+    PyModule_AddObject(m, CLS, (PyObject *)&PyXlType);
+
+    Py_INCREF(xl_error_obj);
+    PyModule_AddObject(m, "Error", xl_error_obj);
+
+    gentypes__init(m);
+}
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ */



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>