pybank r86 - in trunk: . bank



Author: johan
Date: Fri Dec  5 14:14:46 2008
New Revision: 86
URL: http://svn.gnome.org/viewvc/pybank?rev=86&view=rev

Log:
Initial PyGObject integration patch from John Ehresman.
Fixes #559006


Modified:
   trunk/Makefile
   trunk/bank/bank-argument.c
   trunk/bank/bank-info.c
   trunk/bank/bank.c
   trunk/bank/btypes.py
   trunk/bank/module.py
   trunk/bank/repository.py
   trunk/gtktest.py

Modified: trunk/Makefile
==============================================================================
--- trunk/Makefile	(original)
+++ trunk/Makefile	Fri Dec  5 14:14:46 2008
@@ -1,10 +1,12 @@
-PCDEPS=glib-2.0 gobject-2.0 gmodule-2.0 gthread-2.0 gobject-introspection-1.0
+PCDEPS=glib-2.0 gobject-2.0 gmodule-2.0 gthread-2.0 gobject-introspection-1.0 pygobject-2.0
 IR_CFLAGS=-g -Wall -I$(IRPATH) `pkg-config --cflags $(PCDEPS)`
 IR_LIBS=-lffi `pkg-config --libs $(PCDEPS)`
 
 PY_VERSION=2.5
-PY_CFLAGS=-I/usr/include/python$(PY_VERSION) `pkg-config --cflags pygobject-2.0`
-PY_LIBS=-lpython$(PY_VERSION)
+PYTHON=python2.5
+PY_INCLUDE=`$(PYTHON) -c 'from distutils import sysconfig; print sysconfig.get_python_inc()'`
+PY_CFLAGS=-I$(PY_INCLUDE) `pkg-config --cflags pygobject-2.0`
+PY_LIBS=#-lpython$(PY_VERSION)
 
 BANK_SOURCES =			\
 	bank/bank.c		\
@@ -15,7 +17,7 @@
 all: bank/repo.so
 
 bank/repo.so: $(BANK_SOURCES)
-	gcc -fPIC -shared -o bank/repo.so $(BANK_SOURCES) $(IR_CFLAGS) $(IR_LIBS) $(PY_CFLAGS) $(PY_LIBS)
+	gcc -O0 -fPIC -shared -o bank/repo.so $(BANK_SOURCES) $(IR_CFLAGS) $(IR_LIBS) $(PY_CFLAGS) $(PY_LIBS)
 
 clean:
 	@rm -f bank/repo.so

Modified: trunk/bank/bank-argument.c
==============================================================================
--- trunk/bank/bank-argument.c	(original)
+++ trunk/bank/bank-argument.c	Fri Dec  5 14:14:46 2008
@@ -18,6 +18,8 @@
  */
 
 #include "bank.h"
+#include <pygobject.h>
+
 
 GArgument
 pyg_argument_from_pyobject(PyObject *object, GIArgInfo *info)
@@ -46,7 +48,7 @@
 	if (object == Py_None)
 	    arg.v_pointer = NULL;
 	else
-	    arg.v_pointer = PyCObject_AsVoidPtr(object);
+	    arg.v_pointer = pygobject_get(object);
 	break;
     case GI_TYPE_TAG_ARRAY:
 	g_assert (object == Py_None);
@@ -75,7 +77,15 @@
     PyObject *obj;
     
     g_return_val_if_fail(type_info != NULL, NULL);
-    type_tag = g_type_info_get_tag((GITypeInfo*)type_info);
+    type_tag = g_type_info_get_tag(type_info);
+    if ( type_tag == GI_TYPE_TAG_INTERFACE ) {
+	GValue value;
+	GObject* obj = arg->v_pointer;
+	GType gtype = G_OBJECT_TYPE(obj);
+	value.g_type = gtype;
+	value.data[0].v_pointer = obj;
+	return pyg_value_as_pyobject(&value, FALSE);
+    }
 
     switch (type_tag) {
     case GI_TYPE_TAG_VOID:

Modified: trunk/bank/bank-info.c
==============================================================================
--- trunk/bank/bank-info.c	(original)
+++ trunk/bank/bank-info.c	Fri Dec  5 14:14:46 2008
@@ -18,6 +18,7 @@
  */
 
 #include "bank.h"
+#include <pygobject.h>
 
 static void      pyg_base_info_dealloc(PyGIBaseInfo *self);
 static void      pyg_base_info_free(PyObject *op);
@@ -368,7 +369,7 @@
 	if (py_arg == Py_None)
 	    in_args[0].v_pointer = NULL;
 	else
-	    in_args[0].v_pointer = PyCObject_AsVoidPtr(py_arg);
+	    in_args[0].v_pointer = pygobject_get(py_arg);
     }
     for (i = 0; i < g_callable_info_get_n_args((GICallableInfo*)self->info); i++) {
 	arg_info = g_callable_info_get_arg((GICallableInfo*)self->info, i);
@@ -472,7 +473,17 @@
 /* RegisteredTypeInfo */
 NEW_CLASS("RegisteredTypeInfo", GIRegisteredTypeInfo);
 
+static PyObject *
+_wrap_g_registered_type_info_get_g_type (PyGIBaseInfo* self)
+{
+    int gtype;
+    
+    gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo*)self->info);
+    return PyInt_FromLong(gtype);
+}
+
 static PyMethodDef _PyGIRegisteredTypeInfo_methods[] = {
+    { "getGType", (PyCFunction)_wrap_g_registered_type_info_get_g_type, METH_NOARGS },
     { NULL, NULL, 0 }
 };
 

Modified: trunk/bank/bank.c
==============================================================================
--- trunk/bank/bank.c	(original)
+++ trunk/bank/bank.c	Fri Dec  5 14:14:46 2008
@@ -18,6 +18,7 @@
  */
 
 #include "bank.h"
+#include <pygobject.h>
 
 #define REGISTER_TYPE(d, type, name) \
     type.ob_type = &PyType_Type; \
@@ -131,6 +132,7 @@
 
     g_type_init();
 
+    pygobject_init(-1, -1, -1);
     register_types(d);
     register_constants(m);
 }

Modified: trunk/bank/btypes.py
==============================================================================
--- trunk/bank/btypes.py	(original)
+++ trunk/bank/btypes.py	Fri Dec  5 14:14:46 2008
@@ -17,13 +17,23 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #
 
+import new
+
 from bank import repo
 
 from .repository import repository
 
 class Callable(object):
+    
+    # Types of callables
+    INSTANCE_METHOD = 'method'
+    STATIC_METHOD = 'static'
+    CLASS_METHOD = 'class'
+    FUNTION = 'function'
+
     def __init__(self, info):
         self.info = info
+        self.call_type = None
 
     def type_check(self, name, value, argType):
         tag = argType.getTag()
@@ -59,13 +69,18 @@
 
         obj = None
         is_method = self.info.isMethod() and not self.info.isConstructor()
-        if not self.static:
+        if self.call_type == self.INSTANCE_METHOD:
             requiredArgs += 1
             if self.info.isConstructor():
                 obj = args[0]
                 args = args[1:]
             elif is_method:
                 obj = args[0]
+        elif self.call_type == self.CLASS_METHOD:
+            requiredArgs += 1
+            cls = args[0]
+            args = args[1:]
+            
 
         if totalInArgs != requiredArgs:
             raise TypeError('%r requires %d arguments' % (
@@ -80,7 +95,6 @@
                 name = infoArg.getName()
                 self.type_check(name, value, argType)
 
-            value = getattr(value, '_object', value)
             inArgs.append(value)
 
         retval = self.info.invoke(*inArgs)
@@ -91,11 +105,7 @@
                     "Invoked constructor %s.%s.%s returned NULL " % (
                     self.__module__, self.className, self.info.getName()))
 
-            if not self.static:
-                obj._object = retval
-                retval = None
-            else:
-                retval = self.newType(retval)
+            return retval
 
         if type(retval).__name__ == 'PyCObject':
              rinfo = self.info.getReturnType()
@@ -119,11 +129,12 @@
 
 
 class Method(Callable):
-    def __init__(self, info, className, static=False):
+    
+    def __init__(self, info, className, call_type=Callable.INSTANCE_METHOD):
         Callable.__init__(self, info)
         self.object = None
         self.className = className
-        self.static = static
+        self.call_type = call_type
         self.__name__ = info.getName()
         self.__module__ = info.getNamespace()
 
@@ -137,14 +148,14 @@
         obj._object = retval
         return obj
 
-    def __get__(self, instance, type):
-        if instance is None:
-            return self
+    #def __get__(self, instance, type):
+        #if instance is None:
+            #return self
 
-        def wrapper(*args, **kwargs):
-            return self(instance, *args, **kwargs)
+        #def wrapper(*args, **kwargs):
+            #return self(instance, *args, **kwargs)
 
-        return wrapper
+        #return wrapper
 
     def __repr__(self):
         return "<method %s of %s.%s object>" % (
@@ -165,7 +176,7 @@
         klass = getattr(module, className)
     return klass
 
-def setupConstructors(className, namespace, constructors):
+def setupConstructors(className, cls, constructors):
     if not constructors:
         return
 
@@ -179,14 +190,14 @@
                 break
 
     if winner != None:
-        func = Method(winner, className)
-        namespace['__init__'] = func
-        func.__name__ = "__init__"
+        func = Method(winner, className, call_type=Method.CLASS_METHOD)
+        cls.__new__ = func
+        func.__name__ = "__new__"
         constructors.remove(winner)
 
     for constructor in constructors:
-        func = Method(constructor, className, static=True)
-        namespace[constructor.getName()] = staticmethod(func)
+        func = Method(constructor, className, call_type=Method.STATIC_METHOD)
+        setattr(cls, constructor.getName(), staticmethod(func))
 
 def buildClass(info, bases):
     className = info.getName()
@@ -197,6 +208,10 @@
         return _classDict[fullName]
 
     namespace = {}
+    namespace['__info__'] = info
+    namespace['__module__'] = namespaceName
+    newType = type(className, bases, namespace)
+
     constructors = []
     for method in info.getMethods():
         if method.isConstructor():
@@ -207,15 +222,17 @@
         else:
             raise AssertionError
         methodName = method.getName()
-        namespace[methodName] = Method(method, className)
+        setattr(newType, methodName, new.instancemethod(Method(method, className),
+                                                        None, newType))
 
-    setupConstructors(className, namespace, constructors)
+    setupConstructors(className, newType, constructors)
 
-    namespace['__info__'] = info
-    namespace['__module__'] = namespaceName
+    def __init__(self, *args, **kw):
+        pass
+    newType.__init__ = new.instancemethod(__init__, None, newType)
 
-    newType = type(className, bases, namespace)
     _classDict[fullName] = newType
+    
     return newType
 
 

Modified: trunk/bank/module.py
==============================================================================
--- trunk/bank/module.py	(original)
+++ trunk/bank/module.py	Fri Dec  5 14:14:46 2008
@@ -19,6 +19,8 @@
 
 import os
 
+import gobject
+
 from .btypes import Function, buildClass
 from .gobject import GEnum
 from .repo import EnumInfo, FunctionInfo, ObjectInfo, UnresolvedInfo
@@ -86,6 +88,7 @@
 
     def _get_parent_for_object(self, object_info):
         parent_info = object_info.getParent()
+        
         if isinstance(parent_info, UnresolvedInfo):
             namespace = parent_info.getNamespace()
             __import__(namespace)
@@ -94,7 +97,16 @@
         if not parent_info:
             parent = object
         else:
-            parent = self._create_object(parent_info)
+            namespace = parent_info.getNamespace()
+            module = repository.get_module(namespace)
+            name = parent_info.getName()
+            try:
+                # Hack for gobject.Object
+                if module == gobject and name == 'Object':
+                    name = 'GObject'
+                parent = getattr(module, name)
+            except AttributeError:
+                return self._get_parent_for_object(parent_info)
 
         if parent is None:
             parent = object
@@ -103,6 +115,18 @@
     def _create_object(self, object_info):
         name = object_info.getName()
 
+        namespace = object_info.getNamespace()
+        if namespace == 'GObject':
+            namespace = 'G'
+        full_name = namespace + name
+        object_info.getGType()
+        try:
+            gtype = gobject.GType.from_name(full_name)
+        except RuntimeError:
+            pass
+        else:
+            if gtype.pytype is not None:
+                return gtype.pytype
         # Check if the klass is already created, eg
         # present in our namespace, this is necessary since we're
         # not always entering here through the __getattr__ hook.
@@ -112,6 +136,8 @@
 
         parent = self._get_parent_for_object(object_info)
         klass = buildClass(object_info, (parent,))
+        if gtype is not None:
+            gtype.pytype = klass
         self.__dict__[name] = klass
 
         return klass

Modified: trunk/bank/repository.py
==============================================================================
--- trunk/bank/repository.py	(original)
+++ trunk/bank/repository.py	Fri Dec  5 14:14:46 2008
@@ -17,6 +17,8 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #
 
+import gobject
+
 from .repo import Repository
 
 class _Repository(object):
@@ -43,3 +45,4 @@
         return self._repo.getInfos(namespace)
 
 repository = _Repository()
+repository.register(gobject, 'GObject', None)
\ No newline at end of file

Modified: trunk/gtktest.py
==============================================================================
--- trunk/gtktest.py	(original)
+++ trunk/gtktest.py	Fri Dec  5 14:14:46 2008
@@ -1,8 +1,12 @@
+import pygtk
+pygtk.require('2.0') 
+
 import bank
 
 import Gtk
 
 window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
+window.connect('delete-event', lambda *args: Gtk.main_quit())
 button = Gtk.Button()
 button.set_label("hello!")
 window.add(button)



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