[pygobject] tests: Add reference count test for signal connection arguments
- From: Simon Feltman <sfeltman src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] tests: Add reference count test for signal connection arguments
- Date: Sun, 17 Aug 2014 05:35:30 +0000 (UTC)
commit c607f07f5ae3ca62ee3a2649f84330eaaa8801c6
Author: Simon Feltman <sfeltman src gnome org>
Date: Sat Aug 16 22:34:29 2014 -0700
tests: Add reference count test for signal connection arguments
Add tests for ensuring reference counts are what we expect for
connect() callback, user_data, and swap object (currently broken
due to bug 688064).
https://bugzilla.gnome.org/show_bug.cgi?id=727004
tests/test_signal.py | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 133 insertions(+), 0 deletions(-)
---
diff --git a/tests/test_signal.py b/tests/test_signal.py
index fea5c6f..b4c9082 100644
--- a/tests/test_signal.py
+++ b/tests/test_signal.py
@@ -3,6 +3,7 @@
import gc
import unittest
import sys
+import weakref
from gi.repository import GObject, GLib
from gi import _signalhelper as signalhelper
@@ -1323,5 +1324,137 @@ class TestConnectPyObjectIntrospected(unittest.TestCase, _ConnectObjectTestBase)
SwapObject = object
+class _RefCountTestBase(object):
+ # NOTE: ref counts are always one more than expected because the getrefcount()
+ # function adds a ref for the input argument.
+
+ # Sub-classes set this
+ Object = None
+
+ class PyData(object):
+ pass
+
+ def test_callback_ref_count_del(self):
+ def callback(obj, value):
+ return value // 2
+
+ callback_ref = weakref.ref(callback)
+ self.assertEqual(sys.getrefcount(callback), 2)
+
+ obj = self.Object()
+ obj.connect('sig-with-int64-prop', callback)
+ self.assertEqual(sys.getrefcount(callback), 3)
+
+ del callback
+ self.assertEqual(sys.getrefcount(callback_ref()), 2)
+
+ res = obj.emit('sig-with-int64-prop', 42)
+ self.assertEqual(res, 21)
+ self.assertEqual(sys.getrefcount(callback_ref), 2)
+
+ del obj
+ self.assertIsNone(callback_ref())
+
+ def test_callback_ref_count_disconnect(self):
+ def callback(obj, value):
+ return value // 2
+
+ callback_ref = weakref.ref(callback)
+ self.assertEqual(sys.getrefcount(callback), 2)
+
+ obj = self.Object()
+ handler_id = obj.connect('sig-with-int64-prop', callback)
+ self.assertEqual(sys.getrefcount(callback), 3)
+
+ del callback
+ self.assertEqual(sys.getrefcount(callback_ref()), 2)
+
+ res = obj.emit('sig-with-int64-prop', 42)
+ self.assertEqual(res, 21)
+ self.assertEqual(sys.getrefcount(callback_ref), 2)
+
+ obj.disconnect(handler_id)
+ self.assertIsNone(callback_ref())
+
+ def test_callback_ref_count_disconnect_by_func(self):
+ def callback(obj, value):
+ return value // 2
+
+ callback_ref = weakref.ref(callback)
+ self.assertEqual(sys.getrefcount(callback), 2)
+
+ obj = self.Object()
+ obj.connect('sig-with-int64-prop', callback)
+ self.assertEqual(sys.getrefcount(callback), 3)
+
+ del callback
+ self.assertEqual(sys.getrefcount(callback_ref()), 2)
+
+ res = obj.emit('sig-with-int64-prop', 42)
+ self.assertEqual(res, 21)
+ self.assertEqual(sys.getrefcount(callback_ref), 2)
+
+ obj.disconnect_by_func(callback_ref())
+ self.assertIsNone(callback_ref())
+
+ def test_user_data_ref_count(self):
+ def callback(obj, value, data):
+ return value // 2
+
+ data = self.PyData()
+ data_ref = weakref.ref(data)
+ self.assertEqual(sys.getrefcount(data), 2)
+
+ obj = self.Object()
+ obj.connect('sig-with-int64-prop', callback, data)
+ self.assertEqual(sys.getrefcount(data), 3)
+
+ del data
+ self.assertEqual(sys.getrefcount(data_ref()), 2)
+
+ res = obj.emit('sig-with-int64-prop', 42)
+ self.assertEqual(res, 21)
+ self.assertEqual(sys.getrefcount(data_ref()), 2)
+
+ del obj
+ self.assertIsNone(data_ref())
+
+ @unittest.expectedFailure # https://bugzilla.gnome.org/show_bug.cgi?id=688064
+ def test_object_ref_count(self):
+ # connect_object() should only weakly reference the object passed in
+ # and auto-disconnect the signal when the object is destroyed.
+ def callback(data, value):
+ return value // 2
+
+ data = GObject.Object()
+ data_ref = weakref.ref(data)
+ self.assertEqual(sys.getrefcount(data), 2)
+
+ obj = self.Object()
+ handler_id = obj.connect_object('sig-with-int64-prop', callback, data)
+ self.assertEqual(sys.getrefcount(data), 2)
+
+ res = obj.emit('sig-with-int64-prop', 42)
+ self.assertEqual(res, 21)
+ self.assertEqual(sys.getrefcount(data), 2)
+
+ del data
+
+ self.assertIsNone(data_ref())
+ self.assertFalse(obj.handler_is_connected(handler_id))
+
+
+class TestRefCountsNonIntrospected(unittest.TestCase, _RefCountTestBase):
+ class Object(GObject.Object):
+ sig_with_int64_prop = GObject.Signal(return_type=GObject.TYPE_INT64,
+ arg_types=[GObject.TYPE_INT64],
+ flags=GObject.SignalFlags.RUN_LAST)
+
+
+ unittest skipUnless(has_cairo, 'built without cairo support')
+class TestRefCountsIntrospected(unittest.TestCase, _RefCountTestBase):
+ Object = Regress.TestObj
+
+
if __name__ == '__main__':
unittest.main()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]