Skip to content

Commit

Permalink
Construct structs using default API constructor
Browse files Browse the repository at this point in the history
If the struct has something that looks like a default constructor,
use it instead of trying to directly allocate it, as it will fail
if the struct fields are not exposed.

https://bugzilla.gnome.org/show_bug.cgi?id=627444
  • Loading branch information
tomeuv committed Jan 19, 2011
1 parent db7300e commit 7c2f48b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
37 changes: 37 additions & 0 deletions gi/pygi-info.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,45 @@ _pygi_object_get_gi_info (PyObject *object,
/* CallableInfo */
PYGLIB_DEFINE_TYPE ("gi.CallableInfo", PyGICallableInfo_Type, PyGIBaseInfo);

static PyObject *
_wrap_g_callable_info_get_arguments (PyGIBaseInfo *self)
{
gssize n_infos;
PyObject *infos;
gssize i;

n_infos = g_callable_info_get_n_args ( (GICallableInfo *) self->info);

infos = PyTuple_New (n_infos);
if (infos == NULL) {
return NULL;
}

for (i = 0; i < n_infos; i++) {
GIBaseInfo *info;
PyObject *py_info;

info = (GIBaseInfo *) g_callable_info_get_arg ( (GICallableInfo *) self->info, i);
g_assert (info != NULL);

py_info = _pygi_info_new (info);

g_base_info_unref (info);

if (py_info == NULL) {
Py_CLEAR (infos);
break;
}

PyTuple_SET_ITEM (infos, i, py_info);
}

return infos;
}

static PyMethodDef _PyGICallableInfo_methods[] = {
{ "invoke", (PyCFunction) _wrap_g_callable_info_invoke, METH_VARARGS | METH_KEYWORDS },
{ "get_arguments", (PyCFunction) _wrap_g_callable_info_get_arguments, METH_NOARGS },
{ NULL, NULL, 0 }
};

Expand Down
7 changes: 7 additions & 0 deletions gi/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,13 @@ def __init__(cls, name, bases, dict_):
cls._setup_methods()
cls._setup_constructors()

for method_info in cls.__info__.get_methods():
if method_info.is_constructor() and \
method_info.get_name() == 'new' and \
not method_info.get_arguments():
cls.__new__ = staticmethod(Constructor(method_info))
break

class Enum(int):
# Only subclasses of this type should be instantiated.
# Each subclass requires an __info__ attribute,
Expand Down

0 comments on commit 7c2f48b

Please sign in to comment.