Permalink
Browse files

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
  • Loading branch information...
1 parent 618dbb0 commit 7284d2d4622978fc9ddfd00f2714b3a572b7ab56 @nud nud committed with John (J5) Palmieri Mar 6, 2011
Showing with 25 additions and 3 deletions.
  1. +2 −3 gobject/propertyhelper.py
  2. +23 −0 tests/test_properties.py
@@ -144,7 +144,6 @@ def __init__(self, getter=None, setter=None, type=None, default=None,
self.name = None
- self._values = {}
self._exc = None
def __repr__(self):
@@ -270,10 +269,10 @@ def _get_maximum(self):
#
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" % (
@@ -401,5 +401,28 @@ def test_float_min(self):
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()

0 comments on commit 7284d2d

Please sign in to comment.