[pygobject/gi-boxed-remove-del: 3/3] boxed: remove __del__ implementation and free in tp_dealloc
- From: Christoph Reiter <creiter src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject/gi-boxed-remove-del: 3/3] boxed: remove __del__ implementation and free in tp_dealloc
- Date: Tue, 15 Jan 2019 14:04:44 +0000 (UTC)
commit b6827f9715dc5f679c817195b868aa0c9642c331
Author: Christoph Reiter <reiter christoph gmail com>
Date: Tue Jan 15 14:45:55 2019 +0100
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.
gi/overrides/GLib.py | 5 ++++-
gi/overrides/GObject.py | 8 ++------
gi/pygi-boxed.c | 34 ++++++++++++++++++----------------
3 files changed, 24 insertions(+), 23 deletions(-)
---
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index e0ac233c..186902e8 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -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'):
diff --git a/gi/overrides/GObject.py b/gi/overrides/GObject.py
index a89ddc7d..4df27ab3 100644
--- a/gi/overrides/GObject.py
+++ b/gi/overrides/GObject.py
@@ -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
diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c
index 32fa477c..90c57c72 100644
--- a/gi/pygi-boxed.c
+++ b/gi/pygi-boxed.c
@@ -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 }
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]