Commit bbfcebdf authored by Owen W. Taylor's avatar Owen W. Taylor
Browse files

Handle GI_TRANSFER_EVERYTHING for returns of foreign structures

Any (transfer full) return of a cairo type other than a path
was leaked.

Pass the transfer type PyGIArgOverrideFromGIArgumentFunc and handle
it for the cairo foreign type. For paths we can only handle
(transfer full) so throw an error for (transfer none).

https://bugzilla.gnome.org/show_bug.cgi?id=726206
parent c5b641cb
...@@ -56,11 +56,14 @@ cairo_context_to_arg (PyObject *value, ...@@ -56,11 +56,14 @@ cairo_context_to_arg (PyObject *value,
} }
static PyObject * static PyObject *
cairo_context_from_arg (GIInterfaceInfo *interface_info, gpointer data) cairo_context_from_arg (GIInterfaceInfo *interface_info,
GITransfer transfer,
gpointer data)
{ {
cairo_t *context = (cairo_t*) data; cairo_t *context = (cairo_t*) data;
cairo_reference (context); if (transfer == GI_TRANSFER_NOTHING)
cairo_reference (context);
return PycairoContext_FromContext (context, &PycairoContext_Type, NULL); return PycairoContext_FromContext (context, &PycairoContext_Type, NULL);
} }
...@@ -95,11 +98,14 @@ cairo_surface_to_arg (PyObject *value, ...@@ -95,11 +98,14 @@ cairo_surface_to_arg (PyObject *value,
} }
static PyObject * static PyObject *
cairo_surface_from_arg (GIInterfaceInfo *interface_info, gpointer data) cairo_surface_from_arg (GIInterfaceInfo *interface_info,
GITransfer transfer,
gpointer data)
{ {
cairo_surface_t *surface = (cairo_surface_t*) data; cairo_surface_t *surface = (cairo_surface_t*) data;
cairo_surface_reference (surface); if (transfer == GI_TRANSFER_NOTHING)
cairo_surface_reference (surface);
return PycairoSurface_FromSurface (surface, NULL); return PycairoSurface_FromSurface (surface, NULL);
} }
...@@ -134,10 +140,17 @@ cairo_path_to_arg (PyObject *value, ...@@ -134,10 +140,17 @@ cairo_path_to_arg (PyObject *value,
} }
static PyObject * static PyObject *
cairo_path_from_arg (GIInterfaceInfo *interface_info, gpointer data) cairo_path_from_arg (GIInterfaceInfo *interface_info,
GITransfer transfer,
gpointer data)
{ {
cairo_path_t *path = (cairo_path_t*) data; cairo_path_t *path = (cairo_path_t*) data;
if (transfer == GI_TRANSFER_NOTHING) {
PyErr_SetString(PyExc_TypeError, "Unsupported annotation (transfer none) for cairo.Path return");
return NULL;
}
return PycairoPath_FromPath (path); return PycairoPath_FromPath (path);
} }
...@@ -170,11 +183,16 @@ cairo_font_options_to_arg (PyObject *value, ...@@ -170,11 +183,16 @@ cairo_font_options_to_arg (PyObject *value,
} }
static PyObject * static PyObject *
cairo_font_options_from_arg (GIInterfaceInfo *interface_info, gpointer data) cairo_font_options_from_arg (GIInterfaceInfo *interface_info,
GITransfer transfer,
gpointer data)
{ {
cairo_font_options_t *font_options = (cairo_font_options_t*) data; cairo_font_options_t *font_options = (cairo_font_options_t*) data;
return PycairoFontOptions_FromFontOptions (cairo_font_options_copy (font_options)); if (transfer == GI_TRANSFER_NOTHING)
font_options = cairo_font_options_copy (font_options);
return PycairoFontOptions_FromFontOptions (font_options);
} }
static PyObject * static PyObject *
......
...@@ -123,6 +123,7 @@ pygi_struct_foreign_convert_to_g_argument (PyObject *value, ...@@ -123,6 +123,7 @@ pygi_struct_foreign_convert_to_g_argument (PyObject *value,
PyObject * PyObject *
pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info, pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info,
GITransfer transfer,
GIArgument *arg) GIArgument *arg)
{ {
GIBaseInfo *base_info = (GIBaseInfo *) interface_info; GIBaseInfo *base_info = (GIBaseInfo *) interface_info;
...@@ -131,7 +132,7 @@ pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info, ...@@ -131,7 +132,7 @@ pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info,
if (foreign_struct == NULL) if (foreign_struct == NULL)
return NULL; return NULL;
return foreign_struct->from_func (interface_info, arg); return foreign_struct->from_func (interface_info, transfer, arg);
} }
PyObject * PyObject *
......
...@@ -35,6 +35,7 @@ PyObject *pygi_struct_foreign_convert_to_g_argument (PyObject *value, ...@@ -35,6 +35,7 @@ PyObject *pygi_struct_foreign_convert_to_g_argument (PyObject *value,
GITransfer transfer, GITransfer transfer,
GIArgument *arg); GIArgument *arg);
PyObject *pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info, PyObject *pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info,
GITransfer transfer,
GIArgument *arg); GIArgument *arg);
PyObject *pygi_struct_foreign_release (GITypeInfo *type_info, PyObject *pygi_struct_foreign_release (GITypeInfo *type_info,
gpointer struct_); gpointer struct_);
......
...@@ -401,6 +401,7 @@ _caller_alloc (PyGIArgCache *arg_cache, GIArgument *arg) ...@@ -401,6 +401,7 @@ _caller_alloc (PyGIArgCache *arg_cache, GIArgument *arg)
PyObject *foreign_struct = PyObject *foreign_struct =
pygi_struct_foreign_convert_from_g_argument ( pygi_struct_foreign_convert_from_g_argument (
iface_cache->interface_info, iface_cache->interface_info,
GI_TRANSFER_NOTHING,
NULL); NULL);
pygi_struct_foreign_convert_to_g_argument (foreign_struct, pygi_struct_foreign_convert_to_g_argument (foreign_struct,
......
...@@ -352,6 +352,7 @@ _pygi_marshal_to_py_interface_struct (GIArgument *arg, ...@@ -352,6 +352,7 @@ _pygi_marshal_to_py_interface_struct (GIArgument *arg,
py_obj = pyg_value_as_pyobject (arg->v_pointer, FALSE); py_obj = pyg_value_as_pyobject (arg->v_pointer, FALSE);
} else if (is_foreign) { } else if (is_foreign) {
py_obj = pygi_struct_foreign_convert_from_g_argument (interface_info, py_obj = pygi_struct_foreign_convert_from_g_argument (interface_info,
transfer,
arg->v_pointer); arg->v_pointer);
} else if (g_type_is_a (g_type, G_TYPE_BOXED)) { } else if (g_type_is_a (g_type, G_TYPE_BOXED)) {
if (py_type) { if (py_type) {
......
...@@ -85,6 +85,7 @@ typedef PyObject * (*PyGIArgOverrideToGIArgumentFunc) (PyObject *value, ...@@ -85,6 +85,7 @@ typedef PyObject * (*PyGIArgOverrideToGIArgumentFunc) (PyObject *value,
GITransfer transfer, GITransfer transfer,
GIArgument *arg); GIArgument *arg);
typedef PyObject * (*PyGIArgOverrideFromGIArgumentFunc) (GIInterfaceInfo *interface_info, typedef PyObject * (*PyGIArgOverrideFromGIArgumentFunc) (GIInterfaceInfo *interface_info,
GITransfer transfer,
gpointer data); gpointer data);
typedef PyObject * (*PyGIArgOverrideReleaseFunc) (GITypeInfo *type_info, typedef PyObject * (*PyGIArgOverrideReleaseFunc) (GITypeInfo *type_info,
gpointer struct_); gpointer struct_);
......
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