summaryrefslogtreecommitdiffstats
path: root/girepository
diff options
context:
space:
mode:
authorSimon van der Linden <simon.vanderlinden@student.uclouvain.be>2009-05-28 17:45:11 +0200
committerSimon van der Linden <simon.vanderlinden@student.uclouvain.be>2009-06-08 19:08:17 +0200
commite4f2a5ef8734cf40cf8345d442612db1f6c62d5a (patch)
tree45a694e46204e770e184aa4fcaaf8e23075235be /girepository
parentf5ab5046fe9b67ec5e8fc64679e1a3d01787af7e (diff)
downloadpygobject-e4f2a5ef8734cf40cf8345d442612db1f6c62d5a.tar.gz
pygobject-e4f2a5ef8734cf40cf8345d442612db1f6c62d5a.tar.xz
pygobject-e4f2a5ef8734cf40cf8345d442612db1f6c62d5a.zip
Introduces the girepository module from the former PyBank.
Diffstat (limited to 'girepository')
-rw-r--r--girepository/Makefile.am52
-rw-r--r--girepository/__init__.py24
-rw-r--r--girepository/bank-argument.c379
-rw-r--r--girepository/bank-info.c1194
-rw-r--r--girepository/bank-repository.c237
-rw-r--r--girepository/bank.c155
-rw-r--r--girepository/bank.h80
-rw-r--r--girepository/btypes.py300
-rw-r--r--girepository/importer.py52
-rw-r--r--girepository/module.py224
-rw-r--r--girepository/repository.py51
11 files changed, 2748 insertions, 0 deletions
diff --git a/girepository/Makefile.am b/girepository/Makefile.am
new file mode 100644
index 0000000..656795d
--- /dev/null
+++ b/girepository/Makefile.am
@@ -0,0 +1,52 @@
+AUTOMAKE_OPTIONS = 1.7
+PLATFORM_VERSION = 2.0
+
+INCLUDES = \
+ -I$(top_srcdir)/gobject \
+ $(PYTHON_INCLUDES) \
+ $(PYGOBJECT_CFLAGS) \
+ $(GOBJECT_INTROSPECTION_CFLAGS)
+
+pkginclude_HEADERS = bank.h
+
+# girepository extension modules
+pkgpyexecdir = $(pyexecdir)/gtk-2.0/girepository
+
+# girepository python scripts
+pygirepositorydir = $(pkgpyexecdir)
+pygirepository_PYTHON = \
+ __init__.py \
+ importer.py \
+ module.py \
+ repository.py \
+ btypes.py
+
+# linker flags
+common_ldflags = -module -avoid-version
+if PLATFORM_WIN32
+common_ldflags += -no-undefined
+endif
+
+CLEANFILES =
+EXTRA_DIST =
+
+# repo module
+repo_la_CFLAGS = -O0
+repo_la_LDFLAGS = $(common_ldflags) -export-symbols-regex initrepo
+repo_la_LIBADD = $(GOBJECT_INTROSPECTION_LIBS)
+repo_la_SOURCES = \
+ bank-repository.c \
+ bank-argument.c \
+ bank-info.c \
+ bank.c \
+ bank.h
+
+if BUILD_GOBJECT_INTROSPECTION
+pygirepository_LTLIBRARIES = repo.la
+
+all: $(pygirepository_LTLIBRARIES:.la=.so)
+clean-local:
+ rm -f $(pygirepository_LTLIBRARIES:.la=.so)
+.la.so:
+ $(LN_S) .libs/$@ $@ || true
+endif
diff --git a/girepository/__init__.py b/girepository/__init__.py
new file mode 100644
index 0000000..f2e58bf
--- /dev/null
+++ b/girepository/__init__.py
@@ -0,0 +1,24 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+#
+# Copyright (C) 2005, 2007 Johan Dahlin <johan@gnome.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+from .importer import install_importhook
+
+install_importhook()
+
+del install_importhook
diff --git a/girepository/bank-argument.c b/girepository/bank-argument.c
new file mode 100644
index 0000000..9ac28cd
--- /dev/null
+++ b/girepository/bank-argument.c
@@ -0,0 +1,379 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 sw=4 noet ai cindent :
+ *
+ * Copyright (C) 2005 Johan Dahlin <johan@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "bank.h"
+#include <pygobject.h>
+
+GArgument
+pyg_argument_from_pyobject(PyObject *object, GITypeInfo *type_info)
+{
+ GArgument arg;
+ GITypeTag type_tag;
+ GIBaseInfo* interface_info;
+ GIInfoType interface_type;
+
+ type_tag = g_type_info_get_tag((GITypeInfo*)type_info);
+ switch (type_tag) {
+ case GI_TYPE_TAG_VOID:
+ /* Nothing to do */
+ break;
+ case GI_TYPE_TAG_UTF8:
+ if (object == Py_None)
+ arg.v_pointer = NULL;
+ else
+ arg.v_pointer = PyString_AsString(object);
+ break;
+ case GI_TYPE_TAG_UINT8:
+ arg.v_uint8 = PyInt_AsLong(object);
+ break;
+ case GI_TYPE_TAG_UINT:
+ arg.v_uint = PyInt_AsLong(object);
+ break;
+ case GI_TYPE_TAG_UINT16:
+ arg.v_uint16 = PyInt_AsLong(object);
+ break;
+ case GI_TYPE_TAG_UINT32:
+ arg.v_uint32 = PyLong_AsLongLong(object);
+ break;
+ case GI_TYPE_TAG_UINT64:
+ if (PyInt_Check(object)) {
+ PyObject *long_obj = PyNumber_Long(object);
+ arg.v_uint64 = PyLong_AsUnsignedLongLong(long_obj);
+ Py_DECREF(long_obj);
+ } else
+ arg.v_uint64 = PyLong_AsUnsignedLongLong(object);
+ break;
+ case GI_TYPE_TAG_INT8:
+ arg.v_int8 = PyInt_AsLong(object);
+ break;
+ case GI_TYPE_TAG_INT:
+ arg.v_int = PyInt_AsLong(object);
+ break;
+ case GI_TYPE_TAG_LONG:
+ arg.v_long = PyInt_AsLong(object);
+ break;
+ case GI_TYPE_TAG_ULONG:
+ arg.v_ulong = PyInt_AsLong(object);
+ break;
+ case GI_TYPE_TAG_BOOLEAN:
+ arg.v_boolean = PyInt_AsLong(object);
+ break;
+ case GI_TYPE_TAG_INT16:
+ arg.v_int16 = PyInt_AsLong(object);
+ break;
+ case GI_TYPE_TAG_INT32:
+ arg.v_int32 = PyInt_AsLong(object);
+ break;
+ case GI_TYPE_TAG_INT64:
+ arg.v_int64 = PyLong_AsLongLong(object);
+ break;
+ case GI_TYPE_TAG_FLOAT:
+ arg.v_float = (float)PyFloat_AsDouble(object);
+ break;
+ case GI_TYPE_TAG_DOUBLE:
+ arg.v_double = PyFloat_AsDouble(object);
+ break;
+ case GI_TYPE_TAG_INTERFACE:
+ interface_info = g_type_info_get_interface(type_info);
+ interface_type = g_base_info_get_type(interface_info);
+ if (interface_type == GI_INFO_TYPE_ENUM) {
+ arg.v_int = PyInt_AsLong(object);
+ } else if (object == Py_None)
+ arg.v_pointer = NULL;
+ else
+ arg.v_pointer = pygobject_get(object);
+ break;
+ case GI_TYPE_TAG_ARRAY:
+ arg.v_pointer = NULL;
+ break;
+ case GI_TYPE_TAG_ERROR:
+ /* Allow NULL GError, otherwise fall through */
+ if (object == Py_None) {
+ arg.v_pointer = NULL;
+ break;
+ }
+ default:
+ g_print("<PyO->GArg> GITypeTag %s is unhandled\n",
+ g_type_tag_to_string(type_tag));
+ break;
+ }
+
+ return arg;
+}
+
+static PyObject *
+glist_to_pyobject(GITypeTag list_tag, GITypeInfo *type_info, GList *list, GSList *slist)
+{
+ PyObject *py_list;
+ int i;
+ GArgument arg;
+ PyObject *child_obj;
+
+ if ((py_list = PyList_New(0)) == NULL) {
+ g_list_free(list);
+ return NULL;
+ }
+ i = 0;
+ if (list_tag == GI_TYPE_TAG_GLIST) {
+ for ( ; list != NULL; list = list->next) {
+ arg.v_pointer = list->data;
+
+ child_obj = pyg_argument_to_pyobject(&arg, type_info);
+
+ if (child_obj == NULL) {
+ g_list_free(list);
+ Py_DECREF(py_list);
+ return NULL;
+ }
+ PyList_Append(py_list, child_obj);
+ Py_DECREF(child_obj);
+
+ ++i;
+ }
+ } else {
+ for ( ; slist != NULL; slist = slist->next) {
+ arg.v_pointer = slist->data;
+
+ child_obj = pyg_argument_to_pyobject(&arg, type_info);
+
+ if (child_obj == NULL) {
+ g_list_free(list);
+ Py_DECREF(py_list);
+ return NULL;
+ }
+ PyList_Append(py_list, child_obj);
+ Py_DECREF(child_obj);
+
+ ++i;
+ }
+ }
+ g_list_free(list);
+ return py_list;
+}
+
+PyObject *
+pyarray_to_pyobject(gpointer array, int length, GITypeInfo *type_info)
+{
+ PyObject *py_list;
+ PyObject *child_obj;
+ GITypeInfo *element_type = g_type_info_get_param_type (type_info, 0);
+ GITypeTag type_tag = g_type_info_get_tag(element_type);
+ gsize size;
+ char buf[256];
+ int i;
+
+ if (array == NULL)
+ return Py_None;
+
+ // FIXME: Doesn't seem right to have this here:
+ switch (type_tag) {
+ case GI_TYPE_TAG_INT:
+ size = sizeof(int);
+ break;
+ case GI_TYPE_TAG_INTERFACE:
+ size = sizeof(gpointer);
+ break;
+ default:
+ snprintf(buf, sizeof(buf), "Unimplemented type: %s\n", g_type_tag_to_string(type_tag));
+ PyErr_SetString(PyExc_TypeError, buf);
+ return NULL;
+ }
+
+ if ((py_list = PyList_New(0)) == NULL) {
+ return NULL;
+ }
+
+ for( i = 0; i < length; i++ ) {
+ gpointer current_element = array + i * size;
+
+ child_obj = pyg_argument_to_pyobject((GArgument *)&current_element, element_type);
+ if (child_obj == NULL) {
+ Py_DECREF(py_list);
+ return NULL;
+ }
+ PyList_Append(py_list, child_obj);
+ Py_DECREF(child_obj);
+ }
+
+ return py_list;
+}
+
+PyObject *
+pyg_argument_to_pyobject(GArgument *arg, GITypeInfo *type_info)
+{
+ GITypeTag type_tag;
+ PyObject *obj;
+ GIBaseInfo* interface_info;
+ GIInfoType interface_type;
+ GITypeInfo *param_info;
+
+ g_return_val_if_fail(type_info != NULL, NULL);
+ type_tag = g_type_info_get_tag(type_info);
+
+ switch (type_tag) {
+ case GI_TYPE_TAG_VOID:
+ // TODO: Should we take this as a buffer?
+ g_warning("pybank doesn't know what to do with void types");
+ obj = Py_None;
+ break;
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ param_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(param_info != NULL);
+ obj = glist_to_pyobject(type_tag,
+ param_info,
+ type_tag == GI_TYPE_TAG_GLIST ? arg->v_pointer : NULL,
+ type_tag == GI_TYPE_TAG_GSLIST ? arg->v_pointer : NULL);
+ break;
+ case GI_TYPE_TAG_BOOLEAN:
+ obj = PyBool_FromLong(arg->v_boolean);
+ break;
+ case GI_TYPE_TAG_UINT8:
+ obj = PyInt_FromLong(arg->v_uint8);
+ break;
+ case GI_TYPE_TAG_UINT:
+ obj = PyInt_FromLong(arg->v_uint);
+ break;
+ case GI_TYPE_TAG_UINT16:
+ obj = PyInt_FromLong(arg->v_uint16);
+ break;
+ case GI_TYPE_TAG_UINT32:
+ obj = PyLong_FromLongLong(arg->v_uint32);
+ break;
+ case GI_TYPE_TAG_UINT64:
+ obj = PyLong_FromUnsignedLongLong(arg->v_uint64);
+ break;
+ case GI_TYPE_TAG_INT:
+ obj = PyInt_FromLong(arg->v_int);
+ break;
+ case GI_TYPE_TAG_LONG:
+ obj = PyInt_FromLong(arg->v_long);
+ break;
+ case GI_TYPE_TAG_ULONG:
+ obj = PyInt_FromLong(arg->v_ulong);
+ break;
+ case GI_TYPE_TAG_INT8:
+ obj = PyInt_FromLong(arg->v_int8);
+ break;
+ case GI_TYPE_TAG_INT16:
+ obj = PyInt_FromLong(arg->v_int16);
+ break;
+ case GI_TYPE_TAG_INT32:
+ obj = PyInt_FromLong(arg->v_int32);
+ break;
+ case GI_TYPE_TAG_INT64:
+ obj = PyLong_FromLongLong(arg->v_int64);
+ break;
+ case GI_TYPE_TAG_FLOAT:
+ obj = PyFloat_FromDouble(arg->v_float);
+ break;
+ case GI_TYPE_TAG_DOUBLE:
+ obj = PyFloat_FromDouble(arg->v_double);
+ break;
+ case GI_TYPE_TAG_UTF8:
+ if (arg->v_string == NULL)
+ obj = Py_None;
+ else
+ obj = PyString_FromString(arg->v_string);
+ break;
+ case GI_TYPE_TAG_INTERFACE:
+ interface_info = g_type_info_get_interface(type_info);
+ interface_type = g_base_info_get_type(interface_info);
+
+ if (interface_type == GI_INFO_TYPE_STRUCT || interface_type == GI_INFO_TYPE_BOXED) {
+ // Create new struct based on arg->v_pointer
+ const gchar *module_name = g_base_info_get_namespace(interface_info);
+ const gchar *type_name = g_base_info_get_name(interface_info);
+ PyObject *module = PyImport_ImportModule(module_name);
+ PyObject *tp = PyObject_GetAttrString(module, type_name);
+ gsize size;
+ PyObject *buffer;
+ PyObject **dict;
+
+ if (tp == NULL) {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "Type %s.%s not defined", module_name, type_name);
+ PyErr_SetString(PyExc_TypeError, buf);
+ return NULL;
+ }
+
+ obj = PyObject_GC_New(PyObject, (PyTypeObject *) tp);
+ if (obj == NULL)
+ return NULL;
+
+ // FIXME: Any better way to initialize the dict pointer?
+ dict = (PyObject **) ((char *)obj + ((PyTypeObject *) tp)->tp_dictoffset);
+ *dict = NULL;
+
+ size = g_struct_info_get_size ((GIStructInfo*)interface_info);
+ buffer = PyBuffer_FromReadWriteMemory(arg->v_pointer, size);
+ if (buffer == NULL)
+ return NULL;
+
+ PyObject_SetAttrString(obj, "__buffer__", buffer);
+
+ } else if (interface_type == GI_INFO_TYPE_ENUM) {
+ obj = PyInt_FromLong(arg->v_int);
+ } else if ( arg->v_pointer == NULL ) {
+ obj = Py_None;
+ } else {
+ GValue value;
+ GObject* gobj = arg->v_pointer;
+ GType gtype = G_OBJECT_TYPE(gobj);
+ GIRepository *repo = g_irepository_get_default();
+ GIBaseInfo *object_info = g_irepository_find_by_gtype(repo, gtype);
+ const gchar *module_name;
+ const gchar *type_name;
+
+ if (object_info != NULL) {
+ // It's a pybank class, we should make sure it is initialized.
+
+ module_name = g_base_info_get_namespace(object_info);
+ type_name = g_base_info_get_name(object_info);
+
+ // This will make sure the wrapper class is registered.
+ char buf[250];
+ snprintf(buf, sizeof(buf), "%s.%s", module_name, type_name);
+ PyRun_SimpleString(buf);
+ }
+
+ value.g_type = gtype;
+ value.data[0].v_pointer = gobj;
+ obj = pyg_value_as_pyobject(&value, FALSE);
+ }
+ break;
+ case GI_TYPE_TAG_ARRAY:
+ g_warning("pyg_argument_to_pyobject: use pyarray_to_pyobject instead for arrays");
+ obj = Py_None;
+ break;
+ default:
+ g_print("<GArg->PyO> GITypeTag %s is unhandled\n",
+ g_type_tag_to_string(type_tag));
+ obj = PyString_FromString("<unhandled return value!>"); /* */
+ break;
+ }
+
+ if (obj != NULL)
+ Py_INCREF(obj);
+
+ return obj;
+}
+
+
diff --git a/girepository/bank-info.c b/girepository/bank-info.c
new file mode 100644
index 0000000..974d586
--- /dev/null
+++ b/girepository/bank-info.c
@@ -0,0 +1,1194 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 sw=4 noet ai cindent :
+ *
+ * Copyright (C) 2005 Johan Dahlin <johan@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "bank.h"
+#include <pygobject.h>
+
+static void pyg_base_info_dealloc(PyGIBaseInfo *self);
+static void pyg_base_info_free(PyObject *op);
+static PyObject* pyg_base_info_repr(PyGIBaseInfo *self);
+static int pyg_base_info_traverse(PyGIBaseInfo *self,
+ visitproc visit,
+ void *arg);
+static void pyg_base_info_clear(PyGIBaseInfo *self);
+
+static PyObject *
+_wrap_g_object_info_get_methods(PyGIBaseInfo *self);
+
+#define NEW_CLASS(name, cname) \
+static PyMethodDef _Py##cname##_methods[]; \
+PyTypeObject Py##cname##_Type = { \
+ PyObject_HEAD_INIT(NULL) \
+ 0, \
+ "bank." name, \
+ sizeof(PyGIBaseInfo), \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, \
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \
+ NULL, 0, 0, 0, \
+ offsetof(PyGIBaseInfo, weakreflist), \
+ 0, 0, \
+ _Py##cname##_methods, \
+ 0, 0, NULL, NULL, 0, 0, \
+ offsetof(PyGIBaseInfo, instance_dict) \
+}
+
+static PyMethodDef _PyGIBaseInfo_methods[];
+static PyGetSetDef _PyGIBaseInfo_getsets[];
+
+PyTypeObject PyGIBaseInfo_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "bank.BaseInfo",
+ sizeof(PyGIBaseInfo),
+ 0,
+ /* methods */
+ (destructor)pyg_base_info_dealloc,
+ (printfunc)0,
+ (getattrfunc)0,
+ (setattrfunc)0,
+ (cmpfunc)0,
+ (reprfunc)pyg_base_info_repr,
+ 0,
+ 0,
+ 0,
+ (hashfunc)0,
+ (ternaryfunc)0,
+ (reprfunc)0,
+ (getattrofunc)0,
+ (setattrofunc)0,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC,
+ NULL,
+ (traverseproc)pyg_base_info_traverse,
+ (inquiry)pyg_base_info_clear,
+ (richcmpfunc)0,
+ offsetof(PyGIBaseInfo, weakreflist),
+ (getiterfunc)0,
+ (iternextfunc)0,
+ _PyGIBaseInfo_methods,
+ 0,
+ _PyGIBaseInfo_getsets,
+ NULL,
+ NULL,
+ (descrgetfunc)0,
+ (descrsetfunc)0,
+ offsetof(PyGIBaseInfo, instance_dict),
+ (initproc)0,
+ (allocfunc)0, /* tp_alloc */
+ (newfunc)0, /* tp_new */
+ (freefunc)pyg_base_info_free, /* tp_free */
+ (inquiry)0, /* tp_is_gc */
+ (PyObject *)0, /* tp_bases */
+};
+
+static PyObject *
+pyg_base_info_repr(PyGIBaseInfo *self)
+{
+ gchar buf[256];
+
+ g_snprintf(buf, sizeof(buf),
+ "<%s object (%s) at 0x%lx>",
+ self->ob_type->tp_name,
+ g_base_info_get_name(self->info), (long)self);
+ return PyString_FromString(buf);
+}
+
+static void
+pyg_base_info_dealloc(PyGIBaseInfo *self)
+{
+ PyObject_ClearWeakRefs((PyObject *)self);
+ pyg_base_info_clear(self);
+}
+
+static int
+pyg_base_info_traverse(PyGIBaseInfo *self,
+ visitproc visit,
+ void *arg)
+{
+ int ret = 0;
+
+ if (self->instance_dict)
+ ret = visit(self->instance_dict, arg);
+
+ if (ret != 0)
+ return ret;
+
+ return 0;
+
+}
+
+static void
+pyg_base_info_clear(PyGIBaseInfo *self)
+{
+ PyObject_GC_UnTrack((PyObject *)self);
+
+ Py_CLEAR(self->instance_dict);
+
+ if (self->info) {
+ g_base_info_unref(self->info);
+ self->info = NULL;
+ }
+
+ PyObject_GC_Del(self);
+}
+
+static void
+pyg_base_info_free(PyObject *op)
+{
+ PyObject_GC_Del(op);
+}
+
+
+static PyObject *
+pyg_base_info_get_dict(PyGIBaseInfo *self, void *closure)
+{
+ if (self->instance_dict == NULL) {
+ self->instance_dict = PyDict_New();
+ if (self->instance_dict == NULL)
+ return NULL;
+ }
+ Py_INCREF(self->instance_dict);
+ return self->instance_dict;
+}
+
+static PyGetSetDef _PyGIBaseInfo_getsets[] = {
+ { "__dict__", (getter)pyg_base_info_get_dict, (setter)0 },
+ { NULL, 0, 0 }
+};
+
+static PyObject *
+_wrap_g_base_info_get_name(PyGIBaseInfo *self)
+{
+ return PyString_FromString(g_base_info_get_name(self->info));
+}
+
+static PyObject *
+_wrap_g_base_info_get_namespace(PyGIBaseInfo *self)
+{
+ return PyString_FromString(g_base_info_get_namespace(self->info));
+}
+
+static PyObject *
+_wrap_g_base_info_get_type(PyGIBaseInfo *self)
+{
+ return PyInt_FromLong(g_base_info_get_type(self->info));
+}
+
+PyObject *
+pyg_info_new(void *info)
+{
+ PyGIBaseInfo *self;
+ GIInfoType type_info;
+ PyTypeObject *tp;
+
+ if (info == NULL) {
+ PyErr_SetString(PyExc_TypeError, "NULL value sent to pyg_info_new");
+ return NULL;
+ }
+
+ type_info = g_base_info_get_type((GIBaseInfo*)info);
+
+ switch (type_info)
+ {
+ case GI_INFO_TYPE_OBJECT:
+ tp = &PyGIObjectInfo_Type;
+ break;
+ case GI_INFO_TYPE_BOXED:
+ tp = &PyGIBoxedInfo_Type;
+ break;
+ case GI_INFO_TYPE_STRUCT:
+ tp = &PyGIStructInfo_Type;
+ break;
+ case GI_INFO_TYPE_FUNCTION:
+ tp = &PyGIFunctionInfo_Type;
+ break;
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ tp = &PyGIEnumInfo_Type;
+ break;
+ case GI_INFO_TYPE_ARG:
+ tp = &PyGIArgInfo_Type;
+ break;
+ case GI_INFO_TYPE_TYPE:
+ tp = &PyGITypeInfo_Type;
+ break;
+ case GI_INFO_TYPE_INTERFACE:
+ tp = &PyGIInterfaceInfo_Type;
+ break;
+ case GI_INFO_TYPE_UNRESOLVED:
+ tp = &PyGIUnresolvedInfo_Type;
+ break;
+ case GI_INFO_TYPE_VALUE:
+ tp = &PyGIValueInfo_Type;
+ break;
+ case GI_INFO_TYPE_FIELD:
+ tp = &PyGIFieldInfo_Type;
+ break;
+ default:
+ g_print ("Unhandled GIInfoType: %d\n", type_info);
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE)
+ Py_INCREF(tp);
+
+ self = (PyGIBaseInfo*)PyObject_GC_New(PyGIBaseInfo, tp);
+ if (self == NULL)
+ return NULL;
+
+ self->info = g_base_info_ref(info);
+
+ self->instance_dict = NULL;
+ self->weakreflist = NULL;
+
+ PyObject_GC_Track((PyObject *)self);
+
+ return (PyObject*)self;
+}
+
+static PyMethodDef _PyGIBaseInfo_methods[] = {
+ { "getName", (PyCFunction)_wrap_g_base_info_get_name, METH_NOARGS },
+ { "getType", (PyCFunction)_wrap_g_base_info_get_type, METH_NOARGS },
+ { "getNamespace", (PyCFunction)_wrap_g_base_info_get_namespace, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+
+/* CallableInfo */
+NEW_CLASS("CallableInfo", GICallableInfo);
+
+static PyObject *
+_wrap_g_callable_info_get_args(PyGIBaseInfo *self)
+{
+ int i, length;
+ PyObject *retval;
+
+ length = g_callable_info_get_n_args((GICallableInfo*)self->info);
+ retval = PyTuple_New(length);
+
+ for (i = 0; i < length; i++) {
+ GIArgInfo *arg;
+ arg = g_callable_info_get_arg((GICallableInfo*)self->info, i);
+ PyTuple_SetItem(retval, i, pyg_info_new(arg));
+ g_base_info_unref((GIBaseInfo*)arg);
+ }
+
+ return retval;
+}
+
+static PyObject *
+_wrap_g_callable_info_get_return_type(PyGIBaseInfo *self)
+{
+ return pyg_info_new(g_callable_info_get_return_type((GICallableInfo*)self->info));
+}
+
+static PyMethodDef _PyGICallableInfo_methods[] = {
+ { "getArgs", (PyCFunction)_wrap_g_callable_info_get_args, METH_NOARGS },
+ { "getReturnType", (PyCFunction)_wrap_g_callable_info_get_return_type, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+/* FunctionInfo */
+NEW_CLASS("FunctionInfo", GIFunctionInfo);
+
+static PyObject *
+_wrap_g_function_info_is_constructor(PyGIBaseInfo *self)
+{
+ return PyInt_FromLong(g_function_info_get_flags((GIFunctionInfo*)self->info) &
+ GI_FUNCTION_IS_CONSTRUCTOR);
+}
+
+static PyObject *
+_wrap_g_function_info_is_method(PyGIBaseInfo *self)
+{
+ return PyInt_FromLong(g_function_info_get_flags((GIFunctionInfo*)self->info) &
+ GI_FUNCTION_IS_METHOD);
+}
+
+static PyObject *
+_wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
+{
+ GArgument *in_args;
+ GArgument *out_args;
+ GArgument *out_values;
+ GArgument return_arg;
+ int n_args;
+ int expected_in_argc;
+ int expected_out_argc;
+ int i;
+ int argv_pos;
+ int in_args_pos;
+ int out_args_pos;
+ GError *error;
+ gboolean failed;
+ GIFunctionInfoFlags flags;
+ gboolean is_method;
+ gboolean is_constructor;
+ gboolean invoke_ok;
+ GITypeInfo *return_info;
+ GITypeTag return_tag;
+ PyObject **return_values;
+ int n_return_values;
+ int next_rval;
+ PyObject *retval;
+ PyObject *py_arg;
+
+ flags = g_function_info_get_flags((GIFunctionInfo*)self->info);
+ is_method = (flags & GI_FUNCTION_IS_METHOD) != 0;
+ is_constructor = (flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0;
+
+ expected_in_argc = 0;
+ expected_out_argc = 0;
+
+ n_args = g_callable_info_get_n_args( (GICallableInfo*) self->info);
+ for (i = 0; i < n_args; i++) {
+ GIDirection direction;
+ GIArgInfo *arg_info;
+
+ arg_info = g_callable_info_get_arg( (GICallableInfo*) self->info, i);
+ direction = g_arg_info_get_direction(arg_info);
+ if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT)
+ expected_in_argc += 1;
+ if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT)
+ expected_out_argc += 1;
+ g_base_info_unref( (GIBaseInfo*) arg_info);
+ }
+ /*
+ g_debug("Call is to %s %s.%s with expected: %d in args, %d out args, %d total args",
+ is_method ? "method" : "function",
+ g_base_info_get_namespace( (GIBaseInfo*) self->info),
+ g_base_info_get_name( (GIBaseInfo*) self->info),
+ expected_in_argc,
+ expected_out_argc,
+ n_args);
+ */
+ if (is_method)
+ expected_in_argc += 1;
+
+ in_args = g_newa(GArgument, expected_in_argc);
+ out_args = g_newa(GArgument, expected_out_argc);
+ /* each out arg is a pointer, they point to these values */
+ /* FIXME: This will break for caller-allocates funcs:
+ http://bugzilla.gnome.org/show_bug.cgi?id=573314 */
+ out_values = g_newa(GArgument, expected_out_argc);
+
+ failed = FALSE;
+ in_args_pos = 0; /* index into in_args */
+ out_args_pos = 0; /* into out_args */
+ argv_pos = 0; /* index into argv */
+
+ if (is_method && !is_constructor) {
+ GIBaseInfo *container = g_base_info_get_container((GIBaseInfo *) self->info);
+ GIInfoType type = g_base_info_get_type(container);
+
+ py_arg = PyTuple_GetItem(args, 0);
+ if (!py_arg) {
+ PyErr_SetString(PyExc_ValueError, "Calling a method without passing an instance");
+ return NULL;
+ }
+ if (py_arg == Py_None) {
+ in_args[0].v_pointer = NULL;
+ } else if (type == GI_INFO_TYPE_STRUCT || type == GI_INFO_TYPE_BOXED) {
+ PyObject *pybuffer = PyObject_GetAttrString((PyObject *)py_arg,
+ "__buffer__");
+ PyBufferProcs *buffer_procs = pybuffer->ob_type->tp_as_buffer;
+ (*buffer_procs->bf_getreadbuffer)(pybuffer, 0, &in_args[0].v_pointer);
+ } else { /* by fallback is always object */
+ in_args[0].v_pointer = pygobject_get(py_arg);
+ }
+ ++in_args_pos;
+ }
+
+ for (i = 0; i < n_args; i++) {
+ GIDirection direction;
+ GIArgInfo *arg_info;
+ GArgument *out_value;
+
+ arg_info = g_callable_info_get_arg( (GICallableInfo*) self->info, i);
+ direction = g_arg_info_get_direction(arg_info);
+
+ out_value = NULL;
+ if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
+ g_assert(out_args_pos < expected_out_argc);
+
+ out_value = &out_values[out_args_pos];
+ out_args[out_args_pos].v_pointer = out_value;
+ ++out_args_pos;
+ }
+
+ if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
+ if (is_method || is_constructor)
+ py_arg = PyTuple_GetItem(args, i + 1);
+ else
+ py_arg = PyTuple_GetItem(args, i);
+
+ GArgument in_value = pyg_argument_from_pyobject(py_arg, g_arg_info_get_type(arg_info));
+
+ ++argv_pos;
+
+ if (direction == GI_DIRECTION_IN) {
+ in_args[in_args_pos] = in_value;
+ } else {
+ /* INOUT means we pass a pointer */
+ g_assert(out_value != NULL);
+ *out_value = in_value;
+ in_args[in_args_pos].v_pointer = out_value;
+ }
+
+ ++in_args_pos;
+ }
+
+ g_base_info_unref( (GIBaseInfo*) arg_info);
+
+ if (failed)
+ break;
+ }
+
+ if (failed) {
+ PyErr_SetString(PyExc_ValueError, "Failed to convert all args.");
+ return NULL;
+ }
+
+ g_assert(in_args_pos == expected_in_argc);
+ g_assert(out_args_pos == expected_out_argc);
+
+ error = NULL;
+ invoke_ok = g_function_info_invoke( (GIFunctionInfo*) self->info,
+ in_args, expected_in_argc,
+ out_args, expected_out_argc,
+ &return_arg,
+ &error);
+
+ return_info = g_callable_info_get_return_type( (GICallableInfo*) self->info);
+ g_assert(return_info != NULL);
+
+ if (!invoke_ok) {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "Error invoking %s.%s: %s",
+ g_base_info_get_namespace( (GIBaseInfo*) self->info),
+ g_base_info_get_name( (GIBaseInfo*) self->info),
+ error->message);
+
+ g_assert(error != NULL);
+ PyErr_SetString(PyExc_RuntimeError, buf);
+ g_error_free(error);
+
+ return NULL;
+ }
+
+ return_tag = g_type_info_get_tag(return_info);
+
+ if (is_constructor) {
+ py_arg = PyTuple_GetItem(args, 0);
+
+ if (return_tag == GI_TYPE_TAG_INTERFACE) {
+ GIBaseInfo *interface_info = g_type_info_get_interface(return_info);
+ GIInfoType interface_type = g_base_info_get_type(interface_info);
+
+ if (interface_type == GI_INFO_TYPE_STRUCT || interface_type == GI_INFO_TYPE_BOXED) {
+ // FIXME: We should reuse this. Perhaps by separating the
+ // wrapper creation from the binding to the wrapper.
+ gsize size = g_struct_info_get_size ((GIStructInfo*)return_info);
+ PyObject *buffer = PyBuffer_FromReadWriteMemory(return_arg.v_pointer, size);
+
+ //PyObject *dict = PyObject_GetDict(py_arg);
+ PyObject_SetAttrString(py_arg, "__buffer__", buffer);
+
+ Py_INCREF(py_arg);
+ return py_arg;
+ } else {
+ PyGObject *self = (PyGObject *) py_arg;
+ if (self->obj != NULL) {
+ PyErr_SetString(PyExc_ValueError, "Calling constructor on an instance that isn't a GObject");
+ return NULL;
+ }
+ self->obj = return_arg.v_pointer;
+ g_object_ref(return_arg.v_pointer);
+ pygobject_register_wrapper(py_arg);
+ Py_INCREF(py_arg);
+ return py_arg;
+ }
+ } else {
+ PyErr_SetString(PyExc_NotImplementedError, "");
+ return NULL;
+ }
+ }
+
+ retval = NULL;
+
+ next_rval = 0; /* index into return_values */
+
+ n_return_values = expected_out_argc;
+ if (return_tag != GI_TYPE_TAG_VOID)
+ n_return_values += 1;
+
+ return_values = g_newa(PyObject*, n_return_values);
+ if (!is_constructor && n_return_values > 0) {
+ if (return_tag != GI_TYPE_TAG_VOID) {
+ PyObject *obj = pyg_argument_to_pyobject(&return_arg, return_info);
+ if (obj == NULL) {
+ return NULL;
+ }
+ return_values[next_rval] = obj;
+
+ ++next_rval;
+ }
+ }
+
+ /* We walk over all args, release in args (if allocated) and convert
+ * all out args
+ */
+ in_args_pos = is_method ? 1 : 0; /* index into in_args */
+ out_args_pos = 0; /* into out_args */
+
+ for (i = 0; i < n_args; i++) {
+ GIDirection direction;
+ GIArgInfo *arg_info;
+ GITypeInfo *arg_type_info;
+
+ arg_info = g_callable_info_get_arg( (GICallableInfo*) self->info, i);
+ direction = g_arg_info_get_direction(arg_info);
+
+ arg_type_info = g_arg_info_get_type(arg_info);
+
+ if (direction == GI_DIRECTION_IN) {
+ g_assert(in_args_pos < expected_in_argc);
+
+ ++in_args_pos;
+ } else {
+ /* INOUT or OUT */
+ if (direction == GI_DIRECTION_INOUT)
+ g_assert(in_args_pos < expected_in_argc);
+ g_assert(next_rval < n_return_values);
+ g_assert(out_args_pos < expected_out_argc);
+
+ PyObject *obj;
+ GITypeTag type_tag = g_type_info_get_tag(arg_type_info);
+
+ if (type_tag == GI_TYPE_TAG_ARRAY) {
+ GArgument *arg = out_args[out_args_pos].v_pointer;
+ gint length_arg_index = g_type_info_get_array_length(arg_type_info);
+ GArgument *length_arg;
+
+ if (is_method)
+ length_arg_index--;
+
+ if (length_arg_index == -1) {
+ PyErr_SetString(PyExc_NotImplementedError, "Need a field to specify the array length");
+ return NULL;
+ }
+
+ length_arg = out_args[length_arg_index].v_pointer;
+
+ if (length_arg == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to get the length of the array");
+ return NULL;
+ }
+
+ obj = pyarray_to_pyobject(arg->v_pointer, length_arg->v_int, arg_type_info);
+ } else
+ obj = pyg_argument_to_pyobject(out_args[out_args_pos].v_pointer, arg_type_info);
+ if (obj == NULL) {
+ return NULL;
+ }
+ return_values[next_rval] = obj;
+
+ if (direction == GI_DIRECTION_INOUT)
+ ++in_args_pos;
+
+ ++out_args_pos;
+
+ ++next_rval;
+ }
+
+ g_base_info_unref( (GIBaseInfo*) arg_type_info);
+ g_base_info_unref( (GIBaseInfo*) arg_info);
+ }
+
+ g_assert(next_rval == n_return_values);
+ g_assert(out_args_pos == expected_out_argc);
+ g_assert(in_args_pos == expected_in_argc);
+
+ if (n_return_values > 0) {
+ if (n_return_values == 0) {
+ retval = Py_None;
+ Py_INCREF(retval);
+ } else if (n_return_values == 1) {
+ retval = return_values[0];
+ } else {
+ retval = PyTuple_New(n_return_values);
+ for (i = 0; i < n_return_values; i++) {
+ PyTuple_SetItem(retval, i, return_values[i]);
+ }
+ }
+ }
+
+ g_base_info_unref( (GIBaseInfo*) return_info);
+
+ if (retval == NULL) {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+
+ return retval;
+}
+
+static PyMethodDef _PyGIFunctionInfo_methods[] = {
+ { "isConstructor", (PyCFunction)_wrap_g_function_info_is_constructor, METH_NOARGS },
+ { "isMethod", (PyCFunction)_wrap_g_function_info_is_method, METH_NOARGS },
+ { "invoke", (PyCFunction)_wrap_g_function_info_invoke, METH_VARARGS },
+ { NULL, NULL, 0 }
+};
+
+/* GICallbackInfo */
+NEW_CLASS("CallbackInfo", GICallbackInfo);
+
+static PyMethodDef _PyGICallbackInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* 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 }
+};
+
+/* GIStructInfo */
+NEW_CLASS("StructInfo", GIStructInfo);
+
+static PyObject *
+_wrap_g_struct_info_get_fields(PyGIBaseInfo *self)
+{
+ int i, length;
+ PyObject *retval;
+
+ g_base_info_ref(self->info);
+ length = g_struct_info_get_n_fields((GIStructInfo*)self->info);
+ retval = PyTuple_New(length);
+
+ for (i = 0; i < length; i++) {
+ GIFieldInfo *field;
+ field = g_struct_info_get_field((GIStructInfo*)self->info, i);
+ PyTuple_SetItem(retval, i, pyg_info_new(field));
+ g_base_info_unref((GIBaseInfo*)field);
+ }
+ g_base_info_unref(self->info);
+
+ return retval;
+}
+
+static PyObject *
+_wrap_g_struct_info_get_methods(PyGIBaseInfo *self)
+{
+ int i, length;
+ PyObject *retval;
+
+ g_base_info_ref(self->info);
+ length = g_struct_info_get_n_methods((GIStructInfo*)self->info);
+ retval = PyTuple_New(length);
+
+ for (i = 0; i < length; i++) {
+ GIFunctionInfo *function;
+ function = g_struct_info_get_method((GIStructInfo*)self->info, i);
+ PyTuple_SetItem(retval, i, pyg_info_new(function));
+ g_base_info_unref((GIBaseInfo*)function);
+ }
+ g_base_info_unref(self->info);
+
+ return retval;
+}
+
+static PyObject *
+_wrap_g_struct_info_new_buffer(PyGIBaseInfo *self)
+{
+ gsize size = g_struct_info_get_size ((GIStructInfo*)self->info);
+ PyObject *buffer = PyBuffer_New (size);
+ Py_INCREF(buffer);
+ return buffer;
+}
+
+static PyMethodDef _PyGIStructInfo_methods[] = {
+ { "getFields", (PyCFunction)_wrap_g_struct_info_get_fields, METH_NOARGS },
+ { "getMethods", (PyCFunction)_wrap_g_struct_info_get_methods, METH_NOARGS },
+ { "newBuffer", (PyCFunction)_wrap_g_struct_info_new_buffer, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+/* GIUnionInfo */
+NEW_CLASS("UnionInfo", GIUnionInfo);
+
+static PyMethodDef _PyGIUnionInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* EnumInfo */
+NEW_CLASS("EnumInfo", GIEnumInfo);
+
+static PyObject *
+_wrap_g_enum_info_get_values(PyGIBaseInfo *self)
+{
+ int n_values, i;
+ GIValueInfo *value;
+ PyObject *list;
+
+ g_base_info_ref(self->info);
+ n_values = g_enum_info_get_n_values((GIEnumInfo*)self->info);
+ list = PyList_New(n_values);
+ for (i = 0; i < n_values; i++)
+ {
+ value = g_enum_info_get_value((GIEnumInfo*)self->info, i);
+ PyList_SetItem(list, i, pyg_info_new(value));
+ g_base_info_unref((GIBaseInfo*)value);
+ }
+ g_base_info_unref(self->info);
+
+ return list;
+}
+
+static PyMethodDef _PyGIEnumInfo_methods[] = {
+ { "getValues", (PyCFunction)_wrap_g_enum_info_get_values, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+/* BoxedInfo */
+NEW_CLASS("BoxedInfo", GIBoxedInfo);
+
+static PyMethodDef _PyGIBoxedInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* ObjectInfo */
+NEW_CLASS("ObjectInfo", GIObjectInfo);
+
+static PyObject *
+_wrap_g_object_info_get_parent(PyGIBaseInfo *self)
+{
+ GIObjectInfo *parent_info;
+
+ g_base_info_ref(self->info);
+ parent_info = g_object_info_get_parent((GIObjectInfo*)self->info);
+ g_base_info_unref(self->info);
+
+ if (parent_info)
+ return pyg_info_new(parent_info);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+_wrap_g_object_info_get_type_name(PyGIBaseInfo *self)
+{
+ const gchar *type_name;
+
+ g_base_info_ref(self->info);
+ type_name = g_object_info_get_type_name((GIObjectInfo*)self->info);
+ g_base_info_unref(self->info);
+
+ return PyString_FromString(type_name);
+}
+
+static PyObject *
+_wrap_g_object_info_get_methods(PyGIBaseInfo *self)
+{
+ int i, length;
+ PyObject *retval;
+
+ g_base_info_ref(self->info);
+ length = g_object_info_get_n_methods((GIObjectInfo*)self->info);
+ retval = PyTuple_New(length);
+
+ for (i = 0; i < length; i++) {
+ GIFunctionInfo *function;
+ function = g_object_info_get_method((GIObjectInfo*)self->info, i);
+ PyTuple_SetItem(retval, i, pyg_info_new(function));
+ g_base_info_unref((GIBaseInfo*)function);
+ }
+ g_base_info_unref(self->info);
+
+ return retval;
+}
+
+static PyObject *
+_wrap_g_object_info_get_fields(PyGIBaseInfo *self)
+{
+ int i, length;
+ PyObject *retval;
+
+ g_base_info_ref(self->info);
+ length = g_object_info_get_n_fields((GIObjectInfo*)self->info);
+ retval = PyTuple_New(length);
+
+ for (i = 0; i < length; i++) {
+ GIFieldInfo *field;
+ field = g_object_info_get_field((GIObjectInfo*)self->info, i);
+ PyTuple_SetItem(retval, i, pyg_info_new(field));
+ g_base_info_unref((GIBaseInfo*)field);
+ }
+ g_base_info_unref(self->info);
+
+ return retval;
+}
+
+static PyObject *
+_wrap_g_object_info_get_interfaces(PyGIBaseInfo *self)
+{
+ int i, length;
+ PyObject *retval;
+
+ g_base_info_ref(self->info);
+ length = g_object_info_get_n_interfaces((GIObjectInfo*)self->info);
+ retval = PyTuple_New(length);
+
+ for (i = 0; i < length; i++) {
+ GIInterfaceInfo *interface;
+ interface = g_object_info_get_interface((GIObjectInfo*)self->info, i);
+ PyTuple_SetItem(retval, i, pyg_info_new(interface));
+ g_base_info_unref((GIBaseInfo*)interface);
+ }
+ g_base_info_unref(self->info);
+
+ return retval;
+}
+
+static PyMethodDef _PyGIObjectInfo_methods[] = {
+ { "getParent", (PyCFunction)_wrap_g_object_info_get_parent, METH_NOARGS },
+ { "getTypeName", (PyCFunction)_wrap_g_object_info_get_type_name, METH_NOARGS },
+ { "getMethods", (PyCFunction)_wrap_g_object_info_get_methods, METH_NOARGS },
+ { "getFields", (PyCFunction)_wrap_g_object_info_get_fields, METH_NOARGS },
+ { "getInterfaces", (PyCFunction)_wrap_g_object_info_get_interfaces, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+
+
+/* GIInterfaceInfo */
+NEW_CLASS("InterfaceInfo", GIInterfaceInfo);
+
+static PyObject *
+_wrap_g_interface_info_get_methods(PyGIBaseInfo *self)
+{
+ int i, length;
+ PyObject *retval;
+
+ g_base_info_ref(self->info);
+ length = g_interface_info_get_n_methods((GIInterfaceInfo*)self->info);
+ retval = PyTuple_New(length);
+
+ for (i = 0; i < length; i++) {
+ GIFunctionInfo *function;
+ function = g_interface_info_get_method((GIInterfaceInfo*)self->info, i);
+ PyTuple_SetItem(retval, i, pyg_info_new(function));
+ g_base_info_unref((GIBaseInfo*)function);
+ }
+ g_base_info_unref(self->info);
+
+ return retval;
+}
+
+static void
+initialize_interface (GTypeInterface *iface, PyTypeObject *pytype)
+{
+ // TODO: Implement this when g-i adds supports for vfunc offsets:
+ // http://bugzilla.gnome.org/show_bug.cgi?id=560281
+ /*
+ GIRepository *repo = g_irepository_get_default();
+ GIBaseInfo *iface_info = g_irepository_find_by_gtype(repo, G_TYPE_FROM_INTERFACE(iface));
+ int length, i;
+ GTypeInterface *parent_iface = g_type_interface_peek_parent(iface);
+
+ length = g_interface_info_get_n_methods((GIInterfaceInfo *) iface_info);
+
+ for (i = 0; i < length; i++) {
+ GIFunctionInfo *method = g_interface_info_get_method((GIInterfaceInfo *) iface_info, i);
+ const gchar *method_name = g_base_info_get_name((GIBaseInfo *) method);
+ gchar pymethod_name[250];
+ PyObject *py_method;
+ void *method_ptr = iface + i * sizeof(void*);
+
+ printf("%s\n", method_name);
+
+ g_snprintf(pymethod_name, sizeof(pymethod_name), "do_%s", pymethod_name);
+ py_method = PyObject_GetAttrString((PyObject *) pytype, pymethod_name);
+ if (py_method && !PyObject_TypeCheck(py_method, &PyCFunction_Type)) {
+ method_ptr = interface_method;
+ } else {
+ PyErr_Clear();
+ if (parent_iface) {
+ method_ptr = parent_iface + i * sizeof(void*);
+ }
+ Py_XDECREF(py_method);
+ }
+
+ g_base_info_unref((GIBaseInfo *) method);
+ }
+ */
+}
+
+static PyObject *
+_wrap_g_interface_info_register(PyGIBaseInfo *self)
+{
+ GType gtype;
+ GInterfaceInfo *info_struct = g_new0(GInterfaceInfo, 1);
+
+ info_struct->interface_init = (GInterfaceInitFunc) initialize_interface;
+ info_struct->interface_finalize = NULL;
+ info_struct->interface_data = NULL;
+
+ gtype = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *) self->info);
+ pyg_register_interface_info(gtype, info_struct);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef _PyGIInterfaceInfo_methods[] = {
+ { "getMethods", (PyCFunction)_wrap_g_interface_info_get_methods, METH_NOARGS },
+ { "register", (PyCFunction)_wrap_g_interface_info_register, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+
+/* GIConstantInfo */
+NEW_CLASS("ConstantInfo", GIConstantInfo);
+
+static PyMethodDef _PyGIConstantInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+
+/* GIValueInfo */
+NEW_CLASS("ValueInfo", GIValueInfo);
+
+static PyObject *
+_wrap_g_value_info_get_value(PyGIBaseInfo *self)
+{
+ glong value;
+
+ g_base_info_ref(self->info);
+ value = g_value_info_get_value((GIValueInfo*)self->info);
+ g_base_info_unref(self->info);
+
+ return PyLong_FromLong(value);
+}
+
+
+static PyMethodDef _PyGIValueInfo_methods[] = {
+ { "getValue", (PyCFunction)_wrap_g_value_info_get_value, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+
+/* GISignalInfo */
+NEW_CLASS("SignalInfo", GISignalInfo);
+
+static PyMethodDef _PyGISignalInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+
+/* GIVFuncInfo */
+NEW_CLASS("VFuncInfo", GIVFuncInfo);
+
+static PyMethodDef _PyGIVFuncInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* GIPropertyInfo */
+NEW_CLASS("PropertyInfo", GIPropertyInfo);
+
+static PyMethodDef _PyGIPropertyInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* GIFieldInfo */
+NEW_CLASS("FieldInfo", GIFieldInfo);
+
+static PyObject *
+_wrap_g_field_info_get_value(PyGIBaseInfo *self, PyObject *args)
+{
+ PyObject *obj;
+ void *buffer;
+ GArgument value;
+ GIFieldInfo *field_info;
+ PyObject *retval;
+
+ field_info = (GIFieldInfo *)self->info;
+
+ if (!PyArg_ParseTuple(args, "O:TypeInfo.getValue", &obj))
+ return NULL;
+
+ GIBaseInfo *container = g_base_info_get_container((GIBaseInfo *) self->info);
+ GIInfoType container_type = g_base_info_get_type(container);
+
+ if (container_type == GI_INFO_TYPE_STRUCT || container_type == GI_INFO_TYPE_BOXED) {
+ PyObject *pybuffer = PyObject_GetAttrString(obj, "__buffer__");
+ PyBufferProcs *buffer_procs = pybuffer->ob_type->tp_as_buffer;
+ if (buffer_procs == NULL || buffer_procs->bf_getreadbuffer == 0) {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to get buffer for struct");
+ return NULL;
+ }
+ (*buffer_procs->bf_getreadbuffer)(pybuffer, 0, &buffer);
+ } else {
+ buffer = ((PyGObject *) obj)->obj;
+ printf("obj: %p\n", buffer);
+ }
+
+ if (!g_field_info_get_field (field_info, buffer, &value)) {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to get value for field");
+ return NULL;
+ }
+
+ retval = pyg_argument_to_pyobject (&value, g_field_info_get_type (field_info));
+ if (retval == NULL) {
+ return NULL;
+ }
+
+ Py_INCREF(retval);
+ return retval;
+}
+
+static PyObject *
+_wrap_g_field_info_set_value(PyGIBaseInfo *self, PyObject *args)
+{
+ PyObject *obj;
+ void *buffer;
+ GArgument arg;
+ GIFieldInfo *field_info;
+ PyObject *value;
+
+ field_info = (GIFieldInfo *)self->info;
+
+ if (!PyArg_ParseTuple(args, "OO:TypeInfo.setValue", &obj, &value))
+ return NULL;
+
+ GIBaseInfo *container = g_base_info_get_container((GIBaseInfo *) self->info);
+ GIInfoType container_type = g_base_info_get_type(container);
+
+ if (container_type == GI_INFO_TYPE_STRUCT || container_type == GI_INFO_TYPE_BOXED) {
+ PyObject *pybuffer = PyObject_GetAttrString(obj, "__buffer__");
+ PyBufferProcs *buffer_procs = pybuffer->ob_type->tp_as_buffer;
+ if (buffer_procs == NULL || buffer_procs->bf_getreadbuffer == 0) {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to get buffer for struct");
+ return NULL;
+ }
+ (*buffer_procs->bf_getreadbuffer)(pybuffer, 0, &buffer);
+ } else {
+ buffer = ((PyGObject *) obj)->obj;
+ }
+
+ arg = pyg_argument_from_pyobject(value, g_field_info_get_type (field_info));
+
+ if (!g_field_info_set_field (field_info, buffer, &arg)) {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to set value for field");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef _PyGIFieldInfo_methods[] = {
+ { "getValue", (PyCFunction)_wrap_g_field_info_get_value, METH_VARARGS },
+ { "setValue", (PyCFunction)_wrap_g_field_info_set_value, METH_VARARGS },
+ { NULL, NULL, 0 }
+};
+
+/* ArgInfo */
+NEW_CLASS("ArgInfo", GIArgInfo);
+
+static PyObject *
+_wrap_g_arg_info_get_type(PyGIBaseInfo *self)
+{
+ return pyg_info_new(g_arg_info_get_type((GIArgInfo*)self->info));
+}
+
+static PyObject *
+_wrap_g_arg_info_get_direction(PyGIBaseInfo *self)
+{
+ return PyInt_FromLong(g_arg_info_get_direction((GIArgInfo*)self->info));
+}
+
+static PyMethodDef _PyGIArgInfo_methods[] = {
+ { "getType", (PyCFunction)_wrap_g_arg_info_get_type, METH_NOARGS },
+ { "getDirection", (PyCFunction)_wrap_g_arg_info_get_direction, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+/* TypeInfo */
+NEW_CLASS("TypeInfo", GITypeInfo);
+
+static PyObject *
+_wrap_g_type_info_get_tag(PyGIBaseInfo *self)
+{
+ return PyInt_FromLong(g_type_info_get_tag((GITypeInfo*)self->info));
+}
+
+static PyObject *
+_wrap_g_type_info_get_param_type(PyGIBaseInfo *self, PyObject *args)
+{
+ int index;
+
+ if (!PyArg_ParseTuple(args, "i:TypeInfo.getParamType",
+ &index))
+ return NULL;
+
+ return pyg_info_new(g_type_info_get_param_type((GITypeInfo*)self->info, index));
+}
+
+static PyObject *
+_wrap_g_type_info_get_interface(PyGIBaseInfo *self)
+{
+ return pyg_info_new(g_type_info_get_interface((GITypeInfo*)self->info));
+}
+
+static PyMethodDef _PyGITypeInfo_methods[] = {
+ { "getTag", (PyCFunction)_wrap_g_type_info_get_tag, METH_NOARGS },
+ { "getParamType", (PyCFunction)_wrap_g_type_info_get_param_type, METH_VARARGS },
+ { "getInterface", (PyCFunction)_wrap_g_type_info_get_interface, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+#if 0
+GIErrorDomainInfo
+#endif
+
+/* GIUnresolvedInfo */
+NEW_CLASS("UnresolvedInfo", GIUnresolvedInfo);
+
+static PyMethodDef _PyGIUnresolvedInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+
diff --git a/girepository/bank-repository.c b/girepository/bank-repository.c
new file mode 100644
index 0000000..699806c
--- /dev/null
+++ b/girepository/bank-repository.c
@@ -0,0 +1,237 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 sw=4 noet ai cindent :
+ *
+ * Copyright (C) 2005 Johan Dahlin <johan@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "bank.h"
+
+static PyMethodDef _PyGIRepository_methods[];
+
+PyTypeObject PyGIRepository_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "bank.IRepository",
+ sizeof(PyGIRepository),
+ 0,
+ /* methods */
+ (destructor)0,
+ (printfunc)0,
+ (getattrfunc)0,
+ (setattrfunc)0,
+ (cmpfunc)0,
+ (reprfunc)0,
+ 0,
+ 0,
+ 0,
+ (hashfunc)0,
+ (ternaryfunc)0,
+ (reprfunc)0,
+ (getattrofunc)0,
+ (setattrofunc)0,
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ NULL,
+ (traverseproc)0,
+ (inquiry)0,
+ (richcmpfunc)0,
+ 0,
+ (getiterfunc)0,
+ (iternextfunc)0,
+ _PyGIRepository_methods,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ (descrgetfunc)0,
+ (descrsetfunc)0,
+ 0,
+ (initproc)0,
+};
+
+static PyObject *
+_wrap_g_irepository_require(PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", "lazy", NULL };
+ gchar *namespace;
+ PyObject *lazy_obj = NULL;
+ int flags = 0;
+ GTypelib *ret;
+ PyObject *pyret;
+ GError *error = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "s|O:GIRepository.require",
+ kwlist, &namespace, &lazy_obj))
+ return NULL;
+
+ if (lazy_obj != NULL && PyObject_IsTrue(lazy_obj))
+ flags |= G_IREPOSITORY_LOAD_FLAG_LAZY;
+
+ /* TODO - handle versioning in some way, need to figure out what
+ * this looks like Python side.
+ */
+ ret = g_irepository_require(self->repo, namespace, NULL, flags, &error);
+
+ if (ret == NULL) {
+#if 0
+ g_print ("ERROR: %s (FIXME: raise GError exception)\n",
+ error->message);
+ g_clear_error (&error);
+#endif
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ pyret = PyBool_FromLong(ret != NULL);
+ Py_INCREF(pyret);
+ return pyret;
+}
+
+static PyObject *
+_wrap_g_irepository_find_by_name(PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", "name", NULL };
+ char *namespace, *name;
+ GIBaseInfo *info;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "ss:GIRepository.findByName",
+ kwlist, &namespace, &name))
+ return NULL;
+
+ info = g_irepository_find_by_name (self->repo, namespace, name);
+ if (!info) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ return pyg_info_new(info);
+}
+
+static PyObject *
+_wrap_g_irepository_get_namespaces(PyGIRepository *self)
+{
+ char ** namespaces;
+ int i, length;
+ PyObject *retval;
+
+ namespaces = g_irepository_get_loaded_namespaces(self->repo);
+
+ length = g_strv_length(namespaces);
+ retval = PyTuple_New(length);
+
+ for (i = 0; i < length; i++)
+ PyTuple_SetItem(retval, i, PyString_FromString(namespaces[i]));
+
+ g_strfreev (namespaces);
+
+ return retval;
+}
+
+static PyObject *
+_wrap_g_irepository_get_infos(PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", NULL };
+ char *namespace;
+ int i, length;
+ PyObject *retval;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "s:GIRepository.getInfos",
+ kwlist, &namespace))
+ return NULL;
+
+ length = g_irepository_get_n_infos(self->repo, namespace);
+
+ retval = PyTuple_New(length);
+
+ for (i = 0; i < length; i++) {
+ GIBaseInfo *info = g_irepository_get_info(self->repo, namespace, i);
+ PyTuple_SetItem(retval, i, pyg_info_new(info));
+ }
+
+ return retval;
+}
+
+static PyObject *
+_wrap_g_irepository_is_registered(PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", NULL };
+ char *namespace;
+
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "s:GIRepository.isRegistered",
+ kwlist, &namespace))
+ return NULL;
+
+ return PyBool_FromLong(g_irepository_is_registered(self->repo, namespace, NULL));
+}
+
+static PyObject *
+_wrap_g_irepository_get_c_prefix(PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", NULL };
+ char *namespace;
+
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "s:GIRepository.getCPrefix",
+ kwlist, &namespace))
+ return NULL;
+
+ return PyString_FromString(g_irepository_get_c_prefix(self->repo, namespace));
+}
+
+static PyObject *
+_wrap_g_irepository_get_default(PyObject *_)
+{
+ static PyGIRepository *self = NULL;
+
+ if (!self) {
+ self = (PyGIRepository *)PyObject_New(PyGIRepository,
+ &PyGIRepository_Type);
+ if (self == NULL)
+ return NULL;
+
+ self->repo = g_irepository_get_default();
+ }
+
+ return (PyObject*)self;
+}
+
+static PyMethodDef _PyGIRepository_methods[] = {
+ { "require", (PyCFunction)_wrap_g_irepository_require, METH_VARARGS|METH_KEYWORDS },
+ { "getNamespaces", (PyCFunction)_wrap_g_irepository_get_namespaces, METH_NOARGS },
+ { "getInfos", (PyCFunction)_wrap_g_irepository_get_infos, METH_VARARGS|METH_KEYWORDS },
+ { "getDefault", (PyCFunction)_wrap_g_irepository_get_default, METH_STATIC|METH_NOARGS },
+ { "findByName", (PyCFunction)_wrap_g_irepository_find_by_name, METH_VARARGS|METH_KEYWORDS },
+ { "isRegistered", (PyCFunction)_wrap_g_irepository_is_registered, METH_VARARGS|METH_KEYWORDS },
+ { "getCPrefix", (PyCFunction)_wrap_g_irepository_get_c_prefix, METH_VARARGS|METH_KEYWORDS },
+ { NULL, NULL, 0 }
+};
+
diff --git a/girepository/bank.c b/girepository/bank.c
new file mode 100644
index 0000000..c069a18
--- /dev/null
+++ b/girepository/bank.c
@@ -0,0 +1,155 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 sw=4 noet ai cindent :
+ *
+ * Copyright (C) 2005 Johan Dahlin <johan@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "bank.h"
+#include <pygobject.h>
+
+#define REGISTER_TYPE(d, type, name) \
+ type.ob_type = &PyType_Type; \
+ type.tp_alloc = PyType_GenericAlloc; \
+ type.tp_new = PyType_GenericNew; \
+ if (PyType_Ready(&type)) \
+ return; \
+ PyDict_SetItemString(d, name, (PyObject *)&type); \
+ Py_INCREF(&type);
+
+#define REGISTER_SUBTYPE(d, type, name, base) \
+ type.tp_base = &base; \
+ REGISTER_TYPE(d, type, name)
+
+static PyObject *
+_wrap_set_object_has_new_constructor(PyGIBaseInfo *self, PyObject *args)
+{
+ PyObject *pygtype;
+
+ if (!PyArg_ParseTuple(args, "O:setObjectHasNewConstructor", &pygtype))
+ return NULL;
+
+ pyg_set_object_has_new_constructor(pyg_type_from_object(pygtype));
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef pybank_functions[] = {
+ { "setObjectHasNewConstructor", (PyCFunction)_wrap_set_object_has_new_constructor, METH_VARARGS },
+ { NULL, NULL, 0 }
+};
+
+static void
+register_types(PyObject *d)
+{
+ REGISTER_TYPE(d, PyGIRepository_Type, "Repository");
+ REGISTER_TYPE(d, PyGIBaseInfo_Type, "BaseInfo");
+ REGISTER_SUBTYPE(d, PyGIUnresolvedInfo_Type,
+ "UnresolvedInfo", PyGIBaseInfo_Type);
+ REGISTER_SUBTYPE(d, PyGICallableInfo_Type,
+ "CallableInfo", PyGIBaseInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIFunctionInfo_Type,
+ "FunctionInfo", PyGICallableInfo_Type);
+ REGISTER_SUBTYPE(d, PyGICallbackInfo_Type,
+ "CallbackInfo", PyGICallableInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIRegisteredTypeInfo_Type,
+ "RegisteredTypeInfo", PyGIBaseInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIStructInfo_Type,
+ "StructInfo", PyGIRegisteredTypeInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIEnumInfo_Type,
+ "EnumInfo", PyGIRegisteredTypeInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIObjectInfo_Type,
+ "ObjectInfo", PyGIRegisteredTypeInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIBoxedInfo_Type,
+ "BoxedInfo", PyGIRegisteredTypeInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIInterfaceInfo_Type,
+ "InterfaceInfo", PyGIRegisteredTypeInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIConstantInfo_Type,
+ "ConstantInfo", PyGIBaseInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIValueInfo_Type,
+ "ValueInfo", PyGIBaseInfo_Type);
+ REGISTER_SUBTYPE(d, PyGISignalInfo_Type,
+ "SignalInfo", PyGICallableInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIVFuncInfo_Type,
+ "VFuncInfo", PyGICallableInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIPropertyInfo_Type,
+ "PropertyInfo", PyGIBaseInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIFieldInfo_Type,
+ "FieldInfo", PyGIBaseInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIArgInfo_Type,
+ "ArgInfo", PyGIBaseInfo_Type);
+ REGISTER_SUBTYPE(d, PyGITypeInfo_Type,
+ "TypeInfo", PyGIBaseInfo_Type);
+ REGISTER_SUBTYPE(d, PyGIUnionInfo_Type,
+ "UnionInfo", PyGIRegisteredTypeInfo_Type);
+}
+
+static void
+register_constants(PyObject *m)
+{
+ PyModule_AddIntConstant(m, "TYPE_TAG_VOID", GI_TYPE_TAG_VOID);
+ PyModule_AddIntConstant(m, "TYPE_TAG_BOOLEAN", GI_TYPE_TAG_BOOLEAN);
+ PyModule_AddIntConstant(m, "TYPE_TAG_INT8", GI_TYPE_TAG_INT8);
+ PyModule_AddIntConstant(m, "TYPE_TAG_UINT8", GI_TYPE_TAG_UINT8);
+ PyModule_AddIntConstant(m, "TYPE_TAG_INT16", GI_TYPE_TAG_INT16);
+ PyModule_AddIntConstant(m, "TYPE_TAG_UINT16", GI_TYPE_TAG_UINT16);
+ PyModule_AddIntConstant(m, "TYPE_TAG_INT32", GI_TYPE_TAG_INT32);
+ PyModule_AddIntConstant(m, "TYPE_TAG_UINT32", GI_TYPE_TAG_UINT32);
+ PyModule_AddIntConstant(m, "TYPE_TAG_INT64", GI_TYPE_TAG_INT64);
+ PyModule_AddIntConstant(m, "TYPE_TAG_UINT64", GI_TYPE_TAG_UINT64);
+ /* FIXME: Removed from metadata format, fix properly by introducing
+ special-case struct */
+/* PyModule_AddIntConstant(m, "TYPE_TAG_GSTRING", GI_TYPE_TAG_GSTRING); */
+ PyModule_AddIntConstant(m, "TYPE_TAG_INT", GI_TYPE_TAG_INT);
+ PyModule_AddIntConstant(m, "TYPE_TAG_UINT", GI_TYPE_TAG_UINT);
+ PyModule_AddIntConstant(m, "TYPE_TAG_LONG", GI_TYPE_TAG_LONG);
+ PyModule_AddIntConstant(m, "TYPE_TAG_ULONG", GI_TYPE_TAG_ULONG);
+ PyModule_AddIntConstant(m, "TYPE_TAG_SSIZE", GI_TYPE_TAG_SSIZE);
+ PyModule_AddIntConstant(m, "TYPE_TAG_SIZE", GI_TYPE_TAG_SIZE);
+ PyModule_AddIntConstant(m, "TYPE_TAG_FLOAT", GI_TYPE_TAG_FLOAT);
+ PyModule_AddIntConstant(m, "TYPE_TAG_DOUBLE", GI_TYPE_TAG_DOUBLE);
+ PyModule_AddIntConstant(m, "TYPE_TAG_TIME_T", GI_TYPE_TAG_TIME_T);
+ PyModule_AddIntConstant(m, "TYPE_TAG_GTYPE", GI_TYPE_TAG_GTYPE);
+ PyModule_AddIntConstant(m, "TYPE_TAG_UTF8", GI_TYPE_TAG_UTF8);
+ PyModule_AddIntConstant(m, "TYPE_TAG_FILENAME", GI_TYPE_TAG_FILENAME);
+ PyModule_AddIntConstant(m, "TYPE_TAG_ARRAY", GI_TYPE_TAG_ARRAY);
+ PyModule_AddIntConstant(m, "TYPE_TAG_INTERFACE", GI_TYPE_TAG_INTERFACE);
+ PyModule_AddIntConstant(m, "TYPE_TAG_GLIST", GI_TYPE_TAG_GLIST);
+ PyModule_AddIntConstant(m, "TYPE_TAG_GSLIST", GI_TYPE_TAG_GSLIST);
+ PyModule_AddIntConstant(m, "TYPE_TAG_GHASH", GI_TYPE_TAG_GHASH);
+ PyModule_AddIntConstant(m, "TYPE_TAG_ERROR", GI_TYPE_TAG_ERROR);
+
+ PyModule_AddIntConstant(m, "DIRECTION_IN", GI_DIRECTION_IN);
+ PyModule_AddIntConstant(m, "DIRECTION_OUT", GI_DIRECTION_OUT);
+ PyModule_AddIntConstant(m, "DIRECTION_INOUT", GI_DIRECTION_INOUT);
+}
+
+void
+initrepo(void)
+{
+ PyObject *d, *m;
+
+ m = Py_InitModule("girepository.repo", pybank_functions);
+ d = PyModule_GetDict(m);
+
+ g_type_init();
+
+ pygobject_init(-1, -1, -1);
+ register_types(d);
+ register_constants(m);
+}
+
diff --git a/girepository/bank.h b/girepository/bank.h
new file mode 100644
index 0000000..d960483
--- /dev/null
+++ b/girepository/bank.h
@@ -0,0 +1,80 @@
+/* -*- Mode: C; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2005 Johan Dahlin <johan@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <Python.h>
+#include <girepository.h>
+
+/* This was added in Python 2.4 */
+#ifndef Py_CLEAR
+#define Py_CLEAR(op) \
+ do { \
+ if (op) { \
+ PyObject *tmp = (PyObject *)(op); \
+ (op) = NULL; \
+ Py_DECREF(tmp); \
+ } \
+ } while (0)
+#endif /* Py_CLEAR */
+
+typedef struct {
+ PyObject_HEAD
+ GIRepository *repo;
+} PyGIRepository;
+
+extern PyTypeObject PyGIRepository_Type;
+
+PyObject * pyg_info_new(gpointer info);
+
+typedef struct {
+ PyObject_HEAD
+ GIBaseInfo *info;
+ PyObject *instance_dict;
+ PyObject *weakreflist;
+} PyGIBaseInfo;
+
+extern PyTypeObject PyGIBaseInfo_Type;
+extern PyTypeObject PyGICallableInfo_Type;
+extern PyTypeObject PyGIFunctionInfo_Type;
+extern PyTypeObject PyGICallbackInfo_Type;
+extern PyTypeObject PyGIRegisteredTypeInfo_Type;
+extern PyTypeObject PyGIStructInfo_Type;
+extern PyTypeObject PyGIUnionInfo_Type;
+extern PyTypeObject PyGIEnumInfo_Type;
+extern PyTypeObject PyGIObjectInfo_Type;
+extern PyTypeObject PyGIBoxedInfo_Type;
+extern PyTypeObject PyGIInterfaceInfo_Type;
+extern PyTypeObject PyGIConstantInfo_Type;
+extern PyTypeObject PyGIValueInfo_Type;
+extern PyTypeObject PyGISignalInfo_Type;
+extern PyTypeObject PyGIVFuncInfo_Type;
+extern PyTypeObject PyGIPropertyInfo_Type;
+extern PyTypeObject PyGIFieldInfo_Type;
+extern PyTypeObject PyGIArgInfo_Type;
+extern PyTypeObject PyGITypeInfo_Type;
+#if 0
+extern PyTypeObject PyGIErrorDomainInfo_Type;
+#endif
+extern PyTypeObject PyGIUnresolvedInfo_Type;
+
+GArgument pyg_argument_from_pyobject(PyObject *object,
+ GITypeInfo *info);
+PyObject* pyg_argument_to_pyobject(GArgument *arg,
+ GITypeInfo *info);
+PyObject* pyarray_to_pyobject(gpointer array, int length, GITypeInfo *info);
+
diff --git a/girepository/btypes.py b/girepository/btypes.py
new file mode 100644
index 0000000..03e8826
--- /dev/null
+++ b/girepository/btypes.py
@@ -0,0 +1,300 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+#
+# Copyright (C) 2005, 2007 Johan Dahlin <johan@gnome.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import gobject
+
+import new
+
+from . 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()
+ if tag == repo.TYPE_TAG_UTF8:
+ if not isinstance(value, basestring) and value is not None:
+ raise TypeError("%s must be string, not %s" % (
+ name, type(value).__name__))
+ elif tag in (repo.TYPE_TAG_INT,
+ repo.TYPE_TAG_INT8,
+ repo.TYPE_TAG_UINT,
+ repo.TYPE_TAG_UINT8,
+ repo.TYPE_TAG_INT16,
+ repo.TYPE_TAG_UINT16,
+ repo.TYPE_TAG_INT32):
+ try:
+ int(value)
+ except ValueError:
+ raise TypeError("%s must be int, not %s" % (name, type(value).__name__))
+ if tag in (repo.TYPE_TAG_UINT,
+ repo.TYPE_TAG_UINT8,
+ repo.TYPE_TAG_UINT16) and value < 0:
+ raise TypeError("%s must be an unsigned value, not %s", name, value)
+ elif tag in (repo.TYPE_TAG_UINT32,
+ repo.TYPE_TAG_INT64,
+ repo.TYPE_TAG_UINT64,
+ repo.TYPE_TAG_ULONG):
+ try:
+ long(value)
+ except ValueError:
+ raise TypeError("%s must be int or long, not %s" % (name, type(value).__name__))
+ if tag in (repo.TYPE_TAG_UINT32,
+ repo.TYPE_TAG_UINT64,
+ repo.TYPE_TAG_ULONG) and value < 0:
+ raise TypeError("%s must be an unsigned value, not %s", name, value)
+ elif tag in (repo.TYPE_TAG_FLOAT,
+ repo.TYPE_TAG_DOUBLE):
+ try:
+ float(value)
+ except ValueError:
+ raise TypeError("%s must be float, not %s" % (name, type(value).__name__))
+ elif tag == repo.TYPE_TAG_INTERFACE:
+ # TODO
+ pass
+ elif tag == repo.TYPE_TAG_BOOLEAN:
+ try:
+ bool(value)
+ except ValueError:
+ raise TypeError("%s must be bool, not %s" % (name, type(value).__name__))
+ elif tag == repo.TYPE_TAG_ARRAY:
+ if value is not None:
+ raise TypeError("Must pass None for arrays currently")
+ elif tag == repo.TYPE_TAG_ERROR:
+ # TODO
+ pass
+ elif tag == repo.TYPE_TAG_VOID:
+ # TODO
+ pass
+ else:
+ raise NotImplementedError('type checking for tag %d' % tag)
+
+ def __call__(self, *args, **kwargs):
+ infoArgs = list(self.info.getArgs())
+ requiredArgs = 0
+ for arg in infoArgs:
+ direct = arg.getDirection()
+ if direct in [repo.DIRECTION_IN, repo.DIRECTION_INOUT]:
+ requiredArgs += 1
+
+ is_method = self.call_type in [self.INSTANCE_METHOD, self.CLASS_METHOD]
+ if is_method:
+ requiredArgs += 1
+
+ # TODO: put the kwargs in their right positions
+ totalInArgs = args + tuple(kwargs.values())
+
+ if len(totalInArgs) != requiredArgs:
+ raise TypeError('%r requires %d arguments, passed %d instead.' % (
+ self, requiredArgs, len(totalInArgs)))
+
+ for i, value in enumerate(totalInArgs):
+ if not is_method or i > 0:
+ off = is_method and 1 or 0
+ infoArg = infoArgs[i - off]
+ argType = infoArg.getType()
+ name = infoArg.getName()
+ self.type_check(name, value, argType)
+
+ retval = self.info.invoke(*totalInArgs)
+
+ if self.info.isConstructor():
+ return None
+
+ return retval
+
+class Function(Callable):
+ def __init__(self, info):
+ Callable.__init__(self, info)
+ self.info = info
+ self.static = True
+
+ def __repr__(self):
+ return "<function %s>" % (self.info.getName(),)
+
+
+class Method(Callable):
+
+ def __init__(self, info, className, call_type=Callable.INSTANCE_METHOD):
+ Callable.__init__(self, info)
+ self.object = None
+ self.className = className
+ self.call_type = call_type
+ self.__name__ = info.getName()
+ self.__module__ = info.getNamespace()
+
+ def newType(self, retval, type_info=None):
+ if type_info == None:
+ type_info = self.info.getReturnType()
+
+ info = type_info.getInterface()
+ klass = getClass(info)
+ obj = klass.__new__(klass)
+ obj._object = retval
+ return obj
+
+ #def __get__(self, instance, type):
+ #if instance is None:
+ #return self
+
+ #def wrapper(*args, **kwargs):
+ #return self(instance, *args, **kwargs)
+
+ #return wrapper
+
+ def __repr__(self):
+ return "<method %s of %s.%s object>" % (
+ self.__name__,
+ self.__module__,
+ self.className)
+
+class FieldDescriptor(object):
+ def __init__(self, info):
+ self._info = info
+
+ def __get__(self, obj, klass=None):
+ return self._info.getValue(obj)
+
+ def __set__(self, obj, value):
+ return self._info.setValue(obj, value)
+
+class PyBankMeta(gobject.GObjectMeta):
+ def __init__(cls, name, bases, dict_):
+ gobject.GObjectMeta.__init__(cls, name, bases, dict_)
+
+ if hasattr(cls, '__gtype__'):
+ repo.setObjectHasNewConstructor(cls.__gtype__)
+
+ # Only set up the wrapper methods and fields in their base classes
+ if name == cls.__info__.getName():
+ needs_constructor = not '__init__' in dict_
+ cls._setup_methods(needs_constructor)
+
+ if hasattr(cls.__info__, 'getFields'):
+ cls._setup_fields()
+
+ def _setup_methods(cls, needs_constructor):
+ info = cls.__info__
+ constructors = []
+ static_methods = []
+ for method in info.getMethods():
+ name = method.getName()
+
+ if method.isConstructor():
+ constructors.append(method)
+ elif method.isMethod():
+ func = Method(method, cls.__name__)
+ setattr(cls, name, new.instancemethod(func, None, cls))
+ else:
+ static_methods.append(method)
+
+ if hasattr(info, 'getInterfaces'):
+ for interface in info.getInterfaces():
+ for method in interface.getMethods():
+ name = method.getName()
+ if method.isMethod():
+ func = Method(method, interface.getName())
+ setattr(cls, name, new.instancemethod(func, None, cls))
+ else:
+ static_methods.append(method)
+
+ winner = None
+ if needs_constructor:
+ if len(constructors) == 1:
+ winner = constructors[0]
+ else:
+ for constructor in constructors:
+ if constructor.getName() == 'new':
+ winner = constructor
+ break
+
+ if winner is not None:
+ func = Method(winner, cls.__name__, call_type=Method.CLASS_METHOD)
+ func.__name__ = '__init__'
+ func.__orig_name__ = winner.getName()
+ cls.__init__ = new.instancemethod(func, None, cls)
+ # TODO: do we want the constructor as a static method?
+ #constructors.remove(winner)
+
+ static_methods.extend(constructors)
+ for static_method in static_methods:
+ func = Method(static_method, cls.__name__, call_type=Method.STATIC_METHOD)
+ setattr(cls, static_method.getName(), staticmethod(func))
+
+ def _setup_fields(cls):
+ info = cls.__info__
+ for field in info.getFields():
+ name = field.getName().replace('-', '_')
+ setattr(cls, name, FieldDescriptor(field))
+
+_classDict = {}
+
+def getClass(info):
+ className = info.getName()
+ namespaceName = info.getNamespace()
+ fullName = namespaceName + '.' + className
+
+ klass = _classDict.get(fullName)
+ if klass is None:
+ module = repository.get_module(info.getNamespace())
+ klass = getattr(module, className)
+ return klass
+
+def buildType(info, bases):
+ className = info.getName()
+ namespaceName = info.getNamespace()
+ fullName = namespaceName + '.' + className
+
+ if _classDict.has_key(fullName):
+ return _classDict[fullName]
+
+ namespace = {}
+ namespace['__info__'] = info
+ namespace['__module__'] = namespaceName
+ newType = PyBankMeta(className, bases, namespace)
+
+ _classDict[fullName] = newType
+
+ return newType
+
+class BaseBlob(object):
+ """Base class for Struct, Boxed and Union.
+ """
+ def __init__(self, buf=None):
+ if buf is None:
+ buf = self.__info__.newBuffer()
+ self.__buffer__ = buf
+
+ def __eq__(self, other):
+ for field in self.__info__.getFields():
+ if getattr(self, field.getName()) != getattr(other, field.getName()):
+ return False
+ return True
+
diff --git a/girepository/importer.py b/girepository/importer.py
new file mode 100644
index 0000000..c371f79
--- /dev/null
+++ b/girepository/importer.py
@@ -0,0 +1,52 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+#
+# Copyright (C) 2005,2007 Johan Dahlin <johan@gnome.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import os
+import sys
+
+from .repository import repository
+
+class DynamicImporter(object):
+ def __init__(self, name, path):
+ self.name = name
+ self.path = path
+
+ @staticmethod
+ def find_module(name, path=None):
+ if name == 'cairo':
+ return None
+ namespace = repository.require(name)
+ if namespace:
+ return DynamicImporter(name, path)
+
+ def load_module(self, name):
+ from .module import DynamicModule
+ module_name = 'girepository.overrides.%s' % (name,)
+ try:
+ d = {}
+ module = __import__(module_name, d, d, ' ', 2)
+ modtype = getattr(module, name + 'Module')
+ except ImportError, e:
+ modtype = DynamicModule
+ return modtype(name, self.path)
+
+
+def install_importhook():
+ sys.meta_path.append(DynamicImporter)
+
diff --git a/girepository/module.py b/girepository/module.py
new file mode 100644
index 0000000..2a87816
--- /dev/null
+++ b/girepository/module.py
@@ -0,0 +1,224 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+#
+# Copyright (C) 2007 Johan Dahlin <johan@gnome.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import os
+
+import gobject
+from gobject import GEnum
+
+from .btypes import Function, BaseBlob, buildType
+from .repo import EnumInfo, FunctionInfo, ObjectInfo, UnresolvedInfo, \
+ InterfaceInfo, StructInfo, BoxedInfo
+from .repository import repository
+
+class DynamicModule(object):
+ def __init__(self, namespace, path):
+ self._namespace = namespace
+ self._path = path
+ repository.register(self, namespace, path)
+ self.created()
+
+ @property
+ def __file__(self):
+ return self._namespace
+
+ @property
+ def __name__(self):
+ return self._namespace
+
+ @property
+ def __path__(self):
+ return [os.path.dirname(self.__file__)]
+
+ def __repr__(self):
+ return "<dyn-module %r from %r>" % (self._namespace, self._path)
+
+ def __getattr__(self, name):
+ type_info = repository.get_by_name(self._namespace, name)
+ if not type_info:
+ raise AttributeError("%r object has no attribute %r" % (
+ self.__class__.__name__, name))
+
+ value = self._create_attribute(name, type_info)
+ self.__dict__[name] = value
+ return value
+
+ @property
+ def __members__(self):
+ r = []
+ for type_info in repository.get_infos(self._namespace):
+ if type_info is None:
+ continue
+ r.append(type_info.getName())
+ return r
+
+
+
+ # Override this in a subclass
+
+ def created(self):
+ pass
+
+ # Private API
+
+ def _create_attribute(self, attr, type_info):
+ if isinstance(type_info, ObjectInfo):
+ return self._create_object(type_info)
+ elif isinstance(type_info, EnumInfo):
+ return self._create_enum(type_info)
+ elif isinstance(type_info, FunctionInfo):
+ return self._create_function(type_info)
+ elif isinstance(type_info, InterfaceInfo):
+ return self._create_interface(type_info)
+ elif isinstance(type_info, StructInfo) or \
+ isinstance(type_info, BoxedInfo):
+ return self._create_boxed(type_info)
+ else:
+ raise NotImplementedError(type_info)
+
+ def _get_parent_for_object(self, object_info):
+ parent_info = object_info.getParent()
+
+ if isinstance(parent_info, UnresolvedInfo):
+ namespace = parent_info.getNamespace()
+ __import__(namespace)
+ parent_info = object_info.getParent()
+
+ if not parent_info:
+ parent = object
+ else:
+ 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
+ return parent
+
+ def _create_object(self, object_info):
+ name = object_info.getName()
+
+ namespace = repository.get_c_prefix(object_info.getNamespace())
+ full_name = namespace + name
+ object_info.getGType()
+ gtype = None
+ 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.
+ klass = self.__dict__.get(name)
+ if klass:
+ return klass
+
+ parent = self._get_parent_for_object(object_info)
+ klass = buildType(object_info, (parent,))
+ if gtype is not None:
+ klass.__gtype__ = gtype
+ gtype.pytype = klass
+ self.__dict__[name] = klass
+
+ return klass
+
+ def _create_enum(self, enum_info):
+ ns = dict(__name__=enum_info.getName(),
+ __module__=enum_info.getNamespace())
+ for value in enum_info.getValues():
+ ns[value.getName().upper()] = value.getValue()
+ return type(enum_info.getName(), (GEnum,), ns)
+
+ def _create_function(self, function_info):
+ return Function(function_info)
+
+ def _create_interface(self, interface_info):
+ name = interface_info.getName()
+
+ namespace = repository.get_c_prefix(interface_info.getNamespace())
+ full_name = namespace + name
+ interface_info.getGType()
+ gtype = None
+ 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.
+ klass = self.__dict__.get(name)
+ if klass:
+ return klass
+
+ bases = (gobject.GInterface,)
+ klass = buildType(interface_info, bases)
+ if gtype is not None:
+ klass.__gtype__ = gtype
+ gtype.pytype = klass
+ interface_info.register()
+ self.__dict__[name] = klass
+
+ return klass
+
+ def _create_boxed(self, boxed_info):
+ name = boxed_info.getName()
+
+ namespace = repository.get_c_prefix(boxed_info.getNamespace())
+ full_name = namespace + name
+ boxed_info.getGType()
+ gtype = None
+ 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.
+ klass = self.__dict__.get(name)
+ if klass:
+ return klass
+
+ bases = (BaseBlob,)
+ if isinstance(boxed_info, BoxedInfo):
+ bases += gobject.Boxed
+
+ klass = buildType(boxed_info, bases)
+ if gtype is not None:
+ klass.__gtype__ = gtype
+ gtype.pytype = klass
+ self.__dict__[name] = klass
+
+ return klass
+
diff --git a/girepository/repository.py b/girepository/repository.py
new file mode 100644
index 0000000..a72c6a9
--- /dev/null
+++ b/girepository/repository.py
@@ -0,0 +1,51 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+#
+# Copyright (C) 2007 Johan Dahlin <johan@gnome.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import gobject
+
+from .repo import Repository
+
+class _Repository(object):
+ def __init__(self):
+ self._repo = Repository.getDefault()
+ self._modules = {}
+
+ def register(self, module, namespace, filename):
+ self._modules[namespace] = module
+
+ def require(self, namespace):
+ return self._repo.require(namespace)
+
+ def get_module(self, namespace):
+ return self._modules.get(namespace)
+
+ def get_by_name(self, namespace, name):
+ return self._repo.findByName(namespace, name)
+
+ def get_by_typename(self, typename):
+ raise NotImplemented
+
+ def get_infos(self, namespace):
+ return self._repo.getInfos(namespace)
+
+ def get_c_prefix(self, namespace):
+ return self._repo.getCPrefix(namespace)
+
+repository = _Repository()
+repository.register(gobject, 'GObject', None)