Commit 22656c4b authored by Christoph Reiter's avatar Christoph Reiter 🐍

boxed: remove __del__ implementation and free in tp_dealloc

This allows us to assume that the wrapper is always valid and remove
the _is_valid attribute.

One difference now is that g_boxed_free() is called when the wrapper can no longer
be used and that breaks the custom glib sources where g_boxed_free() triggers
the finalize callback which tries to call into a method of the wrapper.

To work around this provide a _clear_boxed() method which allows the wrapper
to free the underlying boxed in __del__ where the wrapper is still usable.
parent 012973c4
......@@ -524,7 +524,10 @@ class Source(GLib.Source):
def __del__(self):
if hasattr(self, '__pygi_custom_source'):
self.destroy()
super(Source, self).__del__()
# XXX: We have to unref the underlying source while the Python
# wrapper is still valid, so the source can call into the
# wrapper methods for the finalized callback.
self._clear_boxed()
def set_callback(self, fn, user_data=None):
if hasattr(self, '__pygi_custom_source'):
......
......@@ -210,12 +210,8 @@ class Value(GObjectModule.Value):
self.set_value(py_value)
def __del__(self):
if self._is_valid:
if self._free_on_dealloc and self.g_type != TYPE_INVALID:
self.unset()
# We must call base class __del__() after unset.
super(Value, self).__del__()
if self._free_on_dealloc and self.g_type != TYPE_INVALID:
self.unset()
def set_boxed(self, boxed):
# Workaround the introspection marshalers inability to know
......
......@@ -35,13 +35,7 @@ struct _PyGIBoxed {
};
static void
boxed_dealloc (PyGIBoxed *self)
{
Py_TYPE (self)->tp_free ((PyObject *)self);
}
static PyObject *
boxed_del (PyGIBoxed *self)
boxed_clear (PyGIBoxed *self)
{
gpointer boxed = pyg_boxed_get_ptr (self);
......@@ -55,10 +49,25 @@ boxed_del (PyGIBoxed *self)
}
}
pyg_boxed_set_ptr (self, NULL);
}
static PyObject *
boxed_clear_wrapper (PyGIBoxed *self)
{
boxed_clear (self);
Py_RETURN_NONE;
}
static void
boxed_dealloc (PyGIBoxed *self)
{
boxed_clear (self);
Py_TYPE (self)->tp_free ((PyObject *)self);
}
void *
pygi_boxed_alloc (GIBaseInfo *info, gsize *size_out)
{
......@@ -197,12 +206,6 @@ boxed_get_free_on_dealloc(PyGIBoxed *self, void *closure)
return pygi_gboolean_to_py( ((PyGBoxed *)self)->free_on_dealloc );
}
static PyObject *
boxed_get_is_valid (PyGIBoxed *self, void *closure)
{
return pygi_gboolean_to_py (pyg_boxed_get_ptr (self) != NULL);
}
/**
* pygi_boxed_copy_in_place:
*
......@@ -222,19 +225,18 @@ pygi_boxed_copy_in_place (PyGIBoxed *self)
if (ptr)
copy = g_boxed_copy (pygboxed->gtype, ptr);
boxed_del (self);
boxed_clear (self);
pyg_boxed_set_ptr (pygboxed, copy);
pygboxed->free_on_dealloc = TRUE;
}
static PyGetSetDef pygi_boxed_getsets[] = {
{ "_free_on_dealloc", (getter)boxed_get_free_on_dealloc, (setter)0 },
{ "_is_valid", (getter)boxed_get_is_valid, (setter)0 },
{ NULL, 0, 0 }
};
static PyMethodDef boxed_methods[] = {
{ "__del__", (PyCFunction)boxed_del, METH_NOARGS },
{ "_clear_boxed", (PyCFunction)boxed_clear_wrapper, METH_NOARGS },
{ NULL, NULL, 0 }
};
......
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