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

[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, ...@@ -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); Py_DECREF(py_user_data);
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"When passing None for a callback userdata must also be None"); "When passing None for a callback userdata must also be None");
...@@ -3432,10 +3432,8 @@ _pygi_marshal_out_interface_object (PyGIInvokeState *state, ...@@ -3432,10 +3432,8 @@ _pygi_marshal_out_interface_object (PyGIInvokeState *state,
PyGIArgCache *arg_cache, PyGIArgCache *arg_cache,
GIArgument *arg) GIArgument *arg)
{ {
PyObject *py_obj = NULL; PyObject *py_obj = pygobject_new (arg->v_pointer);
;
PyErr_Format(PyExc_NotImplementedError,
"Marshalling for this type is not implemented yet");
return py_obj; return py_obj;
} }
......
...@@ -797,7 +797,134 @@ _arg_cache_new_for_out_gerror(void) ...@@ -797,7 +797,134 @@ _arg_cache_new_for_out_gerror(void)
arg_cache->aux_type = PYGI_AUX_TYPE_IGNORE; arg_cache->aux_type = PYGI_AUX_TYPE_IGNORE;
return arg_cache; 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 * PyGIArgCache *
_arg_cache_out_new_from_type_info (GITypeInfo *type_info, _arg_cache_out_new_from_type_info (GITypeInfo *type_info,
...@@ -863,7 +990,6 @@ _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); transfer);
break; break;
case GI_TYPE_TAG_INTERFACE: case GI_TYPE_TAG_INTERFACE:
/*
{ {
GIInterfaceInfo *interface_info = g_type_info_get_interface(type_info); GIInterfaceInfo *interface_info = g_type_info_get_interface(type_info);
GIInfoType info_type = g_base_info_get_type( (GIBaseInfo *) interface_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, ...@@ -872,13 +998,11 @@ _arg_cache_out_new_from_type_info (GITypeInfo *type_info,
info_type, info_type,
transfer, transfer,
direction, direction,
c_arg_index, c_arg_index);
py_arg_index);
g_base_info_unref( (GIBaseInfo *) interface_info); g_base_info_unref( (GIBaseInfo *) interface_info);
return arg_cache; return arg_cache;
} }
*/
case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GLIST:
arg_cache = _arg_cache_new_for_out_glist(type_info, arg_cache = _arg_cache_new_for_out_glist(type_info,
transfer); transfer);
......
...@@ -1019,15 +1019,16 @@ _invoke_marshal_out_args(PyGIInvokeState *state, PyGIFunctionCache *cache) ...@@ -1019,15 +1019,16 @@ _invoke_marshal_out_args(PyGIInvokeState *state, PyGIFunctionCache *cache)
int total_out_args = cache->n_out_args; int total_out_args = cache->n_out_args;
gboolean has_return = FALSE; gboolean has_return = FALSE;
if (cache->return_cache) if (cache->return_cache) {
py_return = cache->return_cache->out_marshaller(state, py_return = cache->return_cache->out_marshaller(state,
cache, cache,
cache->return_cache, cache->return_cache,
&state->return_arg); &state->return_arg);
if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) { if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
total_out_args++; total_out_args++;
has_return = TRUE; has_return = TRUE;
}
} }
if (cache->n_out_args == 0) { if (cache->n_out_args == 0) {
......
...@@ -51,7 +51,7 @@ def Constructor(info): ...@@ -51,7 +51,7 @@ def Constructor(info):
cls_name = info.get_container().get_name() cls_name = info.get_container().get_name()
if cls.__name__ != cls_name: if cls.__name__ != cls_name:
raise TypeError('%s constructor cannot be used to create instances of a subclass' % 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.__info__ = info
constructor.__name__ = info.get_name() constructor.__name__ = info.get_name()
...@@ -62,23 +62,16 @@ def Constructor(info): ...@@ -62,23 +62,16 @@ def Constructor(info):
class MetaClassHelper(object): 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): def _setup_methods(cls):
for method_info in cls.__info__.get_methods(): for method_info in cls.__info__.get_methods():
name = method_info.get_name() name = method_info.get_name()
function = Function(method_info)
if method_info.is_constructor():
method = classmethod(Constructor(method_info))
if method_info.is_method(): if method_info.is_method():
method = function method = Function(method_info)
elif method_info.is_constructor():
continue
else: else:
method = staticmethod(function) method = staticmethod(Function(method_info))
setattr(cls, name, method) setattr(cls, name, method)
def _setup_fields(cls): def _setup_fields(cls):
...@@ -170,7 +163,6 @@ class GObjectMeta(gobject.GObjectMeta, MetaClassHelper): ...@@ -170,7 +163,6 @@ class GObjectMeta(gobject.GObjectMeta, MetaClassHelper):
if isinstance(cls.__info__, ObjectInfo): if isinstance(cls.__info__, ObjectInfo):
cls._setup_fields() cls._setup_fields()
cls._setup_constructors()
set_object_has_new_constructor(cls.__info__.get_g_type()) set_object_has_new_constructor(cls.__info__.get_g_type())
elif isinstance(cls.__info__, InterfaceInfo): elif isinstance(cls.__info__, InterfaceInfo):
register_interface_info(cls.__info__.get_g_type()) register_interface_info(cls.__info__.get_g_type())
...@@ -187,7 +179,6 @@ class StructMeta(type, MetaClassHelper): ...@@ -187,7 +179,6 @@ class StructMeta(type, MetaClassHelper):
cls._setup_fields() cls._setup_fields()
cls._setup_methods() cls._setup_methods()
cls._setup_constructors()
class Enum(int): class Enum(int):
__info__ = None __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