[pybank] Fix constructors
- From: Johan Dahlin <johan src gnome org>
- To: svn-commits-list gnome org
- Subject: [pybank] Fix constructors
- Date: Tue, 2 Jun 2009 10:44:42 -0400 (EDT)
commit 5924cb177f79c5de0ff32ee17beecac24155ed44
Author: Tomeu Vizoso <tomeu sugarlabs org>
Date: Mon May 11 11:53:02 2009 +0200
Fix constructors
---
bank/bank-argument.c | 27 ++++++++---------
bank/bank-info.c | 73 ++++++++++++++++++++++++++++++++++++-----------
bank/btypes.py | 17 ++---------
everything_unittest.py | 1 +
4 files changed, 73 insertions(+), 45 deletions(-)
diff --git a/bank/bank-argument.c b/bank/bank-argument.c
index babb023..e611448 100644
--- a/bank/bank-argument.c
+++ b/bank/bank-argument.c
@@ -83,7 +83,6 @@ pyg_argument_from_pyobject(PyObject *object, GITypeInfo *type_info)
arg.v_pointer = pygobject_get(object);
break;
case GI_TYPE_TAG_ARRAY:
- g_assert (object == Py_None);
arg.v_pointer = NULL;
break;
case GI_TYPE_TAG_ERROR:
@@ -116,20 +115,20 @@ pyg_argument_to_pyobject(GArgument *arg, GITypeInfo *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 = g_struct_info_get_size ((GIStructInfo*)type_info);
- PyObject *buffer = PyBuffer_FromReadWriteMemory(arg->v_pointer, size);
- PyObject *args = Py_BuildValue("(O)", buffer);
+ // 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 = g_struct_info_get_size ((GIStructInfo*)type_info);
+ PyObject *buffer = PyBuffer_FromReadWriteMemory(arg->v_pointer, size);
+ PyObject *args = Py_BuildValue("(O)", buffer);
- obj = PyObject_Call(tp, args, NULL);
- if (obj == NULL)
- return NULL;
- Py_INCREF(obj);
- return obj;
+ obj = PyObject_Call(tp, args, NULL);
+ if (obj == NULL)
+ return NULL;
+ Py_INCREF(obj);
+ return obj;
} else if (interface_type == GI_INFO_TYPE_ENUM) {
g_warning("pyg_argument_to_pyobject: enums not implemented");
obj = Py_None;
diff --git a/bank/bank-info.c b/bank/bank-info.c
index d85ab09..9f220f3 100644
--- a/bank/bank-info.c
+++ b/bank/bank-info.c
@@ -343,6 +343,7 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
gboolean failed;
GIFunctionInfoFlags flags;
gboolean is_method;
+ gboolean is_constructor;
gboolean invoke_ok;
GITypeInfo *return_info;
GITypeTag return_tag;
@@ -354,6 +355,7 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
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;
@@ -395,7 +397,7 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
out_args_pos = 0; /* into out_args */
argv_pos = 0; /* index into argv */
- if (is_method) {
+ if (is_method && !is_constructor) {
GIBaseInfo *container = g_base_info_get_container((GIBaseInfo *) self->info);
GIInfoType type = g_base_info_get_type(container);
@@ -404,14 +406,14 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
PyErr_SetString(PyExc_ValueError, "Calling a method without passing an instance");
return NULL;
}
- if (py_arg == Py_None)
+ if (py_arg == Py_None) {
in_args[0].v_pointer = NULL;
- else if (type == GI_INFO_TYPE_STRUCT || type == GI_INFO_TYPE_BOXED) {
- PyObject *buffer = PyObject_GetAttrString((PyObject *)py_arg,
- "__buffer__");
- in_args[0].v_pointer = PyString_AsString(buffer);
+ } else if (type == GI_INFO_TYPE_STRUCT || type == GI_INFO_TYPE_BOXED) {
+ PyObject *buffer = PyObject_GetAttrString((PyObject *)py_arg,
+ "__buffer__");
+ in_args[0].v_pointer = PyString_AsString(buffer);
} else { /* by fallback is always object */
- in_args[0].v_pointer = pygobject_get(py_arg);
+ in_args[0].v_pointer = pygobject_get(py_arg);
}
++in_args_pos;
}
@@ -434,11 +436,12 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
}
if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
- if (is_method)
+ 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));
+
+ GArgument in_value = pyg_argument_from_pyobject(py_arg, g_arg_info_get_type(arg_info));
++argv_pos;
@@ -494,6 +497,42 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
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 */
@@ -505,7 +544,7 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
return_values = g_newa(PyObject*, n_return_values);
if (n_return_values > 0) {
if (return_tag != GI_TYPE_TAG_VOID) {
- return_values[next_rval] = pyg_argument_to_pyobject(&return_arg, return_info);
+ return_values[next_rval] = pyg_argument_to_pyobject(&return_arg, return_info);
++next_rval;
}
@@ -538,7 +577,7 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
g_assert(next_rval < n_return_values);
g_assert(out_args_pos < expected_out_argc);
- return_values[next_rval] = pyg_argument_to_pyobject(&out_args[out_args_pos], arg_type_info);
+ return_values[next_rval] = pyg_argument_to_pyobject(&out_args[out_args_pos], arg_type_info);
if (direction == GI_DIRECTION_INOUT)
++in_args_pos;
@@ -557,16 +596,16 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
g_assert(in_args_pos == expected_in_argc);
if (n_return_values > 0) {
- if (n_return_values == 0) {
- retval = Py_None;
- Py_INCREF(retval);
+ 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]);
- }
+ for (i = 0; i < n_return_values; i++) {
+ PyTuple_SetItem(retval, i, return_values[i]);
+ }
}
}
diff --git a/bank/btypes.py b/bank/btypes.py
index 66f69c0..9f47b0d 100644
--- a/bank/btypes.py
+++ b/bank/btypes.py
@@ -82,6 +82,7 @@ class Callable(object):
raise NotImplementedError('type checking for tag %d' % tag)
def __call__(self, *args, **kwargs):
+ print '__call__ %r' % (args,)
infoArgs = list(self.info.getArgs())
requiredArgs = 0
for arg in infoArgs:
@@ -89,17 +90,9 @@ class Callable(object):
if direct in [repo.DIRECTION_IN, repo.DIRECTION_INOUT]:
requiredArgs += 1
- obj = None
is_method = self.info.isMethod() and not self.info.isConstructor()
- if self.call_type == self.INSTANCE_METHOD:
+ if self.call_type in [self.INSTANCE_METHOD, self.CLASS_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:
- args = args[1:]
totalInArgs = len(args) + len(kwargs)
@@ -126,7 +119,7 @@ class Callable(object):
raise AssertionError(
"Invoked constructor %s.%s.%s returned NULL " % (
self.__module__, self.className, self.info.getName()))
-
+ print "mec %r" % retval
return retval
if type(retval).__name__ == 'PyCObject':
@@ -248,10 +241,6 @@ def buildClass(info, bases):
setupConstructors(className, newType, constructors)
- def __init__(self, *args, **kw):
- pass
- newType.__init__ = new.instancemethod(__init__, None, newType)
-
_classDict[fullName] = newType
return newType
diff --git a/everything_unittest.py b/everything_unittest.py
index bfdd9dd..d2bb68a 100644
--- a/everything_unittest.py
+++ b/everything_unittest.py
@@ -269,6 +269,7 @@ class TestGIEverything(unittest.TestCase):
def __init__(self):
Everything.TestObj.__init__(self, 'foo')
s = TestSubclass()
+ self.assertEquals(s.do_matrix('matrix'), 42)
if __name__ == '__main__':
unittest.main()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]