summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Reiter <reiter.christoph@gmail.com>2018-05-04 21:29:13 +0200
committerChristoph Reiter <reiter.christoph@gmail.com>2018-05-04 21:35:02 +0200
commitdd2a6c36b2a8960d05b81d46fb6b1cc063222497 (patch)
tree4338f98aa096ed6a7e0eca2a8020dd5981aca4ef
parentb4417a4432fe96ce545ecaf61fc7d2d745020614 (diff)
downloadpygobject-dd2a6c36b2a8960d05b81d46fb6b1cc063222497.tar.gz
Don't crash on multiple calls to GObject.Value.__del__. See !66
After chaining up accessing anything on the instance will crash like accessing self.g_type in this case. Guard against that by exposing if the wrapped boxed is still there. Ideally we shouldn't invalidate the object in __del__, but various things depend on it atm. For another time..
-rw-r--r--gi/overrides/GObject.py5
-rw-r--r--gi/pygi-boxed.c7
-rw-r--r--tests/test_gobject.py6
3 files changed, 16 insertions, 2 deletions
diff --git a/gi/overrides/GObject.py b/gi/overrides/GObject.py
index f758e6df..312119d5 100644
--- a/gi/overrides/GObject.py
+++ b/gi/overrides/GObject.py
@@ -218,8 +218,9 @@ class Value(GObjectModule.Value):
self.set_value(py_value)
def __del__(self):
- if self._free_on_dealloc and self.g_type != TYPE_INVALID:
- self.unset()
+ 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__()
diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c
index d4823263..6a48159f 100644
--- a/gi/pygi-boxed.c
+++ b/gi/pygi-boxed.c
@@ -193,6 +193,12 @@ 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:
*
@@ -219,6 +225,7 @@ pygi_boxed_copy_in_place (PyGIBoxed *self)
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 }
};
diff --git a/tests/test_gobject.py b/tests/test_gobject.py
index 5d817601..51256f8d 100644
--- a/tests/test_gobject.py
+++ b/tests/test_gobject.py
@@ -649,6 +649,12 @@ class TestGValue(unittest.TestCase):
value.set_value(42.0)
self.assertEqual(value.get_value(), 42)
+ def test_multi_del(self):
+ value = GObject.Value(str, 'foo_bar')
+ value.__del__()
+ value.__del__()
+ del value
+
def test_string(self):
value = GObject.Value(str, 'foo_bar')
self.assertEqual(value.g_type, GObject.TYPE_STRING)