[pybank] Add field support to objects
- From: Johan Dahlin <johan src gnome org>
- To: svn-commits-list gnome org
- Subject: [pybank] Add field support to objects
- Date: Tue, 2 Jun 2009 10:45:17 -0400 (EDT)
commit 4df4fa25a9fd4700890c084c8b007feb47b5bd2d
Author: Tomeu Vizoso <tomeu sugarlabs org>
Date: Tue May 12 15:42:35 2009 +0200
Add field support to objects
---
bank/bank-info.c | 193 +++++++++++++++++++++++++++++-------------------------
bank/btypes.py | 30 +++++++--
2 files changed, 128 insertions(+), 95 deletions(-)
diff --git a/bank/bank-info.c b/bank/bank-info.c
index 389ace2..e3075ac 100644
--- a/bank/bank-info.c
+++ b/bank/bank-info.c
@@ -713,98 +713,10 @@ _wrap_g_struct_info_new_buffer(PyGIBaseInfo *self)
return buffer;
}
-static PyObject *
-_wrap_g_struct_info_get_value(PyGIBaseInfo *self, PyObject *args)
-{
- PyObject *pybuffer;
- PyBufferProcs *buffer_procs;
- void *buffer;
- char *field_name;
- GArgument value;
- GIFieldInfo *field_info;
- int i;
- int n_fields;
- PyObject *retval;
-
- if (!PyArg_ParseTuple(args, "Os:TypeInfo.getValue", &pybuffer, &field_name))
- return NULL;
-
- buffer_procs = pybuffer->ob_type->tp_as_buffer;
- (*buffer_procs->bf_getreadbuffer)(pybuffer, 0, &buffer);
-
- field_info = NULL;
- n_fields = g_struct_info_get_n_fields ((GIStructInfo*) self->info);
- for( i = 0; i < n_fields; i++ ) {
- GIFieldInfo *temp = g_struct_info_get_field((GIStructInfo*) self->info, i);
- if( !strcmp( g_base_info_get_name((GIBaseInfo *) temp), field_name ) ) {
- field_info = temp;
- break;
- }
- }
-
- if( field_info == NULL ) {
- return NULL;
- }
-
- if (!g_field_info_get_field (field_info, buffer, &value)) {
- return NULL;
- }
-
- retval = pyg_argument_to_pyobject(&value, g_field_info_get_type (field_info));
-
- Py_INCREF(retval);
- return retval;
-}
-
-static PyObject *
-_wrap_g_struct_info_set_value(PyGIBaseInfo *self, PyObject *args)
-{
- PyObject *pybuffer;
- PyBufferProcs *buffer_procs;
- void *buffer;
- char *field_name;
- GArgument arg;
- GIFieldInfo *field_info;
- int i;
- int n_fields;
- PyObject *value;
-
- if (!PyArg_ParseTuple(args, "OsO:TypeInfo.setValue", &pybuffer, &field_name, &value))
- return NULL;
-
- buffer_procs = pybuffer->ob_type->tp_as_buffer;
- (*buffer_procs->bf_getreadbuffer)(pybuffer, 0, &buffer);
-
- field_info = NULL;
- n_fields = g_struct_info_get_n_fields ((GIStructInfo*) self->info);
- for( i = 0; i < n_fields; i++ ) {
- GIFieldInfo *temp = g_struct_info_get_field((GIStructInfo*) self->info, i);
- if( !strcmp( g_base_info_get_name((GIBaseInfo *) temp), field_name ) ) {
- field_info = temp;
- break;
- }
- }
-
- if( field_info == NULL ) {
- return NULL;
- }
-
- arg = pyg_argument_from_pyobject(value, g_field_info_get_type (field_info));
-
- if (!g_field_info_set_field (field_info, buffer, &arg)) {
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
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 },
- { "getValue", (PyCFunction)_wrap_g_struct_info_get_value, METH_VARARGS },
- { "setValue", (PyCFunction)_wrap_g_struct_info_set_value, METH_VARARGS },
{ NULL, NULL, 0 }
};
@@ -903,10 +815,32 @@ _wrap_g_object_info_get_methods(PyGIBaseInfo *self)
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 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 },
{ NULL, NULL, 0 }
};
@@ -997,7 +931,90 @@ static PyMethodDef _PyGIPropertyInfo_methods[] = {
/* 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));
+
+ 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 }
};
diff --git a/bank/btypes.py b/bank/btypes.py
index 6ee24f9..d889920 100644
--- a/bank/btypes.py
+++ b/bank/btypes.py
@@ -82,6 +82,9 @@ class Callable(object):
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)
@@ -163,6 +166,16 @@ class Method(Callable):
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_)
@@ -170,6 +183,9 @@ class PyBankMeta(gobject.GObjectMeta):
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 = []
@@ -208,6 +224,12 @@ class PyBankMeta(gobject.GObjectMeta):
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):
@@ -244,13 +266,7 @@ class BaseBlob(object):
def __init__(self, buf=None):
if buf is None:
buf = self.__info__.newBuffer()
- self.__dict__['__buffer__'] = buf
-
- def __getattr__(self, name):
- return self.__info__.getValue(self.__dict__['__buffer__'], name)
-
- def __setattr__(self, name, value):
- self.__info__.setValue(self.__dict__['__buffer__'], name, value)
+ self.__buffer__ = buf
def __eq__(self, other):
for field in self.__info__.getFields():
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]