diff options
author | Christoph Reiter <reiter.christoph@gmail.com> | 2018-05-04 21:29:13 +0200 |
---|---|---|
committer | Christoph Reiter <reiter.christoph@gmail.com> | 2018-05-04 21:35:02 +0200 |
commit | dd2a6c36b2a8960d05b81d46fb6b1cc063222497 (patch) | |
tree | 4338f98aa096ed6a7e0eca2a8020dd5981aca4ef | |
parent | b4417a4432fe96ce545ecaf61fc7d2d745020614 (diff) | |
download | pygobject-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.py | 5 | ||||
-rw-r--r-- | gi/pygi-boxed.c | 7 | ||||
-rw-r--r-- | 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) |