summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Frécinaux <code@istique.net>2011-03-06 21:18:36 +0100
committerJohn (J5) Palmieri <johnp@redhat.com>2011-03-07 11:18:21 -0500
commit7bece91e83e3c72a7bd04d2096dcf9b31aa9d366 (patch)
tree4b7fe06a897b87b67990c5f62d1a9c2897e1b02b
parent030695cb4306d915044aea4fae7c7122ccde31b4 (diff)
downloadpygobject-7bece91e83e3c72a7bd04d2096dcf9b31aa9d366.tar.gz
Do not leak python references when using the gobject.property() helper.
Since this helper was storing plain references in a long-lived dict, the refcount for the instances would never drop to zero, and so they would never get finalized. https://bugzilla.gnome.org/show_bug.cgi?id=644039
-rw-r--r--gobject/propertyhelper.py5
-rw-r--r--tests/test_properties.py23
2 files changed, 25 insertions, 3 deletions
diff --git a/gobject/propertyhelper.py b/gobject/propertyhelper.py
index 745a13c4..9643c82b 100644
--- a/gobject/propertyhelper.py
+++ b/gobject/propertyhelper.py
@@ -144,7 +144,6 @@ class property(object):
self.name = None
- self._values = {}
self._exc = None
def __repr__(self):
@@ -270,10 +269,10 @@ class property(object):
#
def _default_setter(self, instance, value):
- self._values[instance] = value
+ setattr(instance, '_property_helper_'+self.name, value)
def _default_getter(self, instance):
- return self._values.get(instance, self.default)
+ return getattr(instance, '_property_helper_'+self.name, self.default)
def _readonly_setter(self, instance, value):
self._exc = TypeError("%s property of %s is read-only" % (
diff --git a/tests/test_properties.py b/tests/test_properties.py
index 90db3ac6..14999031 100644
--- a/tests/test_properties.py
+++ b/tests/test_properties.py
@@ -401,5 +401,28 @@ class TestProperty(unittest.TestCase):
gobject.property(type=gobject.TYPE_FLOAT, minimum=-1)
gobject.property(type=gobject.TYPE_DOUBLE, minimum=-1)
+ # Bug 644039
+ def testReferenceCount(self):
+ # We can check directly if an object gets finalized, so we will
+ # observe it indirectly through the refcount of a member object.
+
+ # We create our dummy object and store its current refcount
+ o = object()
+ rc = sys.getrefcount(o)
+
+ # We add our object as a member to our newly created object we
+ # want to observe. Its refcount is increased by one.
+ t = PropertyObject(normal="test")
+ t.o = o
+ self.assertEquals(sys.getrefcount(o), rc + 1)
+
+ # Now we want to ensure we do not leak any references to our
+ # object with properties. If no ref is leaked, then when deleting
+ # the local reference to this object, its reference count shoud
+ # drop to zero, and our dummy object should loose one reference.
+ del t
+ self.assertEquals(sys.getrefcount(o), rc)
+
+
if __name__ == '__main__':
unittest.main()