Commit 1006df19 authored by John (J5) Palmieri's avatar John (J5) Palmieri

[gi] fix constructor invoking and add some support for interface out values

* constructors are now simplified and are treated like normal static methods
  which happen to return an instance
parent c96ca383
......@@ -2914,7 +2914,7 @@ _pygi_marshal_in_interface_callback (PyGIInvokeState *state,
}
}
if (py_arg == Py_None && py_user_data != Py_None) {
if (py_arg == Py_None && !(py_user_data == Py_None || py_user_data == NULL)) {
Py_DECREF(py_user_data);
PyErr_Format(PyExc_TypeError,
"When passing None for a callback userdata must also be None");
......@@ -3432,10 +3432,8 @@ _pygi_marshal_out_interface_object (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
PyObject *py_obj = NULL;
PyErr_Format(PyExc_NotImplementedError,
"Marshalling for this type is not implemented yet");
PyObject *py_obj = pygobject_new (arg->v_pointer);
;
return py_obj;
}
......
......@@ -797,7 +797,134 @@ _arg_cache_new_for_out_gerror(void)
arg_cache->aux_type = PYGI_AUX_TYPE_IGNORE;
return arg_cache;
}
static inline PyGIArgCache *
_arg_cache_new_for_out_interface_struct(GIInterfaceInfo *iface_info,
GITransfer transfer)
{
PyErr_Format(PyExc_NotImplementedError,
"Caching for this type is not fully implemented yet");
return FALSE;
PyGIInterfaceCache *iface_cache = _interface_cache_new_from_interface_info(iface_info);
PyGIArgCache *arg_cache = (PyGIArgCache *)iface_cache;
iface_cache->is_foreign = g_struct_info_is_foreign( (GIStructInfo*)iface_info);
arg_cache->in_marshaller = _pygi_marshal_in_interface_struct;
if (iface_cache->g_type == G_TYPE_VALUE)
arg_cache->cleanup = _g_slice_free_gvalue_func;
if (iface_cache->g_type == G_TYPE_CLOSURE)
arg_cache->cleanup = g_closure_unref;
return arg_cache;
}
static inline PyGIArgCache *
_arg_cache_new_for_out_interface_object(GIInterfaceInfo *iface_info,
GITransfer transfer)
{
PyGIArgCache *arg_cache = (PyGIArgCache *)_interface_cache_new_from_interface_info(iface_info);
arg_cache->out_marshaller = _pygi_marshal_out_interface_object;
return arg_cache;
}
static inline PyGIArgCache *
_arg_cache_new_for_out_interface_boxed(GIInterfaceInfo *iface_info,
GITransfer transfer)
{
PyErr_Format(PyExc_NotImplementedError,
"Caching for this type is not fully implemented yet");
return FALSE;
PyGIArgCache *arg_cache = (PyGIArgCache *)_interface_cache_new_from_interface_info(iface_info);
arg_cache->in_marshaller = _pygi_marshal_in_interface_boxed;
return arg_cache;
}
static inline PyGIArgCache *
_arg_cache_new_for_out_interface_callback(void)
{
PyErr_Format(PyExc_NotImplementedError,
"Callback returns are not supported");
return FALSE;
}
static inline PyGIArgCache *
_arg_cache_new_for_out_interface_enum(void)
{
PyGIArgCache *arg_cache = NULL;
/*arg_cache->in_marshaller = _pygi_marshal_in_enum;*/
PyErr_Format(PyExc_NotImplementedError,
"Caching for this type is not fully implemented yet");
return arg_cache;
}
static inline PyGIArgCache *
_arg_cache_new_for_out_interface_union(void)
{
PyGIArgCache *arg_cache = NULL;
/*arg_cache->in_marshaller = _pygi_marshal_in_enum;*/
PyErr_Format(PyExc_NotImplementedError,
"Caching for this type is not fully implemented yet");
return arg_cache;
}
static inline PyGIArgCache *
_arg_cache_new_for_out_interface_flags(void)
{
PyGIArgCache *arg_cache = NULL;
/*arg_cache->in_marshaller = _pygi_marshal_in_flags;*/
PyErr_Format(PyExc_NotImplementedError,
"Caching for this type is not fully implemented yet");
return arg_cache;
}
PyGIArgCache *
_arg_cache_out_new_from_interface_info (GIInterfaceInfo *iface_info,
PyGIFunctionCache *function_cache,
GIInfoType info_type,
GITransfer transfer,
GIDirection direction,
gint c_arg_index)
{
PyGIArgCache *arg_cache = NULL;
switch (info_type) {
case GI_INFO_TYPE_UNION:
arg_cache = _arg_cache_new_for_out_interface_union();
break;
case GI_INFO_TYPE_STRUCT:
arg_cache = _arg_cache_new_for_out_interface_struct(iface_info,
transfer);
break;
case GI_INFO_TYPE_OBJECT:
case GI_INFO_TYPE_INTERFACE:
arg_cache = _arg_cache_new_for_out_interface_object(iface_info,
transfer);
break;
case GI_INFO_TYPE_BOXED:
arg_cache = _arg_cache_new_for_out_interface_boxed(iface_info,
transfer);
break;
case GI_INFO_TYPE_CALLBACK:
arg_cache = _arg_cache_new_for_out_interface_callback();
break;
case GI_INFO_TYPE_ENUM:
arg_cache = _arg_cache_new_for_out_interface_enum();
break;
case GI_INFO_TYPE_FLAGS:
arg_cache = _arg_cache_new_for_out_interface_flags();
break;
default:
g_assert_not_reached();
}
if (arg_cache != NULL) {
arg_cache->direction = direction;
arg_cache->transfer = transfer;
arg_cache->type_tag = GI_TYPE_TAG_INTERFACE;
arg_cache->c_arg_index = c_arg_index;
}
return arg_cache;
}
PyGIArgCache *
_arg_cache_out_new_from_type_info (GITypeInfo *type_info,
......@@ -863,7 +990,6 @@ _arg_cache_out_new_from_type_info (GITypeInfo *type_info,
transfer);
break;
case GI_TYPE_TAG_INTERFACE:
/*
{
GIInterfaceInfo *interface_info = g_type_info_get_interface(type_info);
GIInfoType info_type = g_base_info_get_type( (GIBaseInfo *) interface_info);
......@@ -872,13 +998,11 @@ _arg_cache_out_new_from_type_info (GITypeInfo *type_info,
info_type,
transfer,
direction,
c_arg_index,
py_arg_index);
c_arg_index);
g_base_info_unref( (GIBaseInfo *) interface_info);
return arg_cache;
}
*/
case GI_TYPE_TAG_GLIST:
arg_cache = _arg_cache_new_for_out_glist(type_info,
transfer);
......
......@@ -1019,15 +1019,16 @@ _invoke_marshal_out_args(PyGIInvokeState *state, PyGIFunctionCache *cache)
int total_out_args = cache->n_out_args;
gboolean has_return = FALSE;
if (cache->return_cache)
if (cache->return_cache) {
py_return = cache->return_cache->out_marshaller(state,
cache,
cache->return_cache,
&state->return_arg);
if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
total_out_args++;
has_return = TRUE;
if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
total_out_args++;
has_return = TRUE;
}
}
if (cache->n_out_args == 0) {
......
......@@ -51,7 +51,7 @@ def Constructor(info):
cls_name = info.get_container().get_name()
if cls.__name__ != cls_name:
raise TypeError('%s constructor cannot be used to create instances of a subclass' % cls_name)
return info.invoke(cls, *args)
return info.invoke(*args)
constructor.__info__ = info
constructor.__name__ = info.get_name()
......@@ -62,23 +62,16 @@ def Constructor(info):
class MetaClassHelper(object):
def _setup_constructors(cls):
for method_info in cls.__info__.get_methods():
if method_info.is_constructor():
name = method_info.get_name()
constructor = classmethod(Constructor(method_info))
setattr(cls, name, constructor)
def _setup_methods(cls):
for method_info in cls.__info__.get_methods():
name = method_info.get_name()
function = Function(method_info)
if method_info.is_constructor():
method = classmethod(Constructor(method_info))
if method_info.is_method():
method = function
elif method_info.is_constructor():
continue
method = Function(method_info)
else:
method = staticmethod(function)
method = staticmethod(Function(method_info))
setattr(cls, name, method)
def _setup_fields(cls):
......@@ -170,7 +163,6 @@ class GObjectMeta(gobject.GObjectMeta, MetaClassHelper):
if isinstance(cls.__info__, ObjectInfo):
cls._setup_fields()
cls._setup_constructors()
set_object_has_new_constructor(cls.__info__.get_g_type())
elif isinstance(cls.__info__, InterfaceInfo):
register_interface_info(cls.__info__.get_g_type())
......@@ -187,7 +179,6 @@ class StructMeta(type, MetaClassHelper):
cls._setup_fields()
cls._setup_methods()
cls._setup_constructors()
class Enum(int):
__info__ = None
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment