[pygobject] Don't crash on multiple calls to GObject.Value.__del__. See !66



commit dd2a6c36b2a8960d05b81d46fb6b1cc063222497
Author: Christoph Reiter <reiter christoph gmail com>
Date:   Fri May 4 21:29:13 2018 +0200

    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..

 gi/overrides/GObject.py | 5 +++--
 gi/pygi-boxed.c         | 7 +++++++
 tests/test_gobject.py   | 6 ++++++
 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)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]