Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 5f0e130026
Fetching contributors…

Cannot retrieve contributors at this time

file 186 lines (144 sloc) 7.292 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
# -*- Mode: Python -*-

import unittest

import gobject
import sys
import testhelper


class TestGObjectAPI(unittest.TestCase):
    def testGObjectModule(self):
        obj = gobject.GObject()
        self.assertEquals(obj.__module__,
                          'gobject._gobject')


class TestReferenceCounting(unittest.TestCase):
    def testRegularObject(self):
        obj = gobject.GObject()
        self.assertEquals(obj.__grefcount__, 1)

        obj = gobject.new(gobject.GObject)
        self.assertEquals(obj.__grefcount__, 1)

    def testFloatingWithSinkFunc(self):
        obj = testhelper.FloatingWithSinkFunc()
        self.assertEquals(obj.__grefcount__, 1)

        obj = gobject.new(testhelper.FloatingWithSinkFunc)
        self.assertEquals(obj.__grefcount__, 1)

    def testFloatingWithoutSinkFunc(self):
        obj = testhelper.FloatingWithoutSinkFunc()
        self.assertEquals(obj.__grefcount__, 1)

        obj = gobject.new(testhelper.FloatingWithoutSinkFunc)
        self.assertEquals(obj.__grefcount__, 1)

    def testOwnedByLibrary(self):
        # Upon creation, the refcount of the object should be 2:
        # - someone already has a reference on the new object.
        # - the python wrapper should hold its own reference.
        obj = testhelper.OwnedByLibrary()
        self.assertEquals(obj.__grefcount__, 2)

        # We ask the library to release its reference, so the only
        # remaining ref should be our wrapper's. Once the wrapper
        # will run out of scope, the object will get finalized.
        obj.release()
        self.assertEquals(obj.__grefcount__, 1)

    def testOwnedByLibraryOutOfScope(self):
        obj = testhelper.OwnedByLibrary()
        self.assertEquals(obj.__grefcount__, 2)

        # We are manually taking the object out of scope. This means
        # that our wrapper has been freed, and its reference dropped. We
        # cannot check it but the refcount should now be 1 (the ref held
        # by the library is still there, we didn't call release()
        obj = None

        # When we get the object back from the lib, the wrapper is
        # re-created, so our refcount will be 2 once again.
        obj = testhelper.owned_by_library_get_instance_list()[0]
        self.assertEquals(obj.__grefcount__, 2)

        obj.release()
        self.assertEquals(obj.__grefcount__, 1)

    def testOwnedByLibraryUsingGObjectNew(self):
        # Upon creation, the refcount of the object should be 2:
        # - someone already has a reference on the new object.
        # - the python wrapper should hold its own reference.
        obj = gobject.new(testhelper.OwnedByLibrary)
        self.assertEquals(obj.__grefcount__, 2)

        # We ask the library to release its reference, so the only
        # remaining ref should be our wrapper's. Once the wrapper
        # will run out of scope, the object will get finalized.
        obj.release()
        self.assertEquals(obj.__grefcount__, 1)

    def testOwnedByLibraryOutOfScopeUsingGobjectNew(self):
        obj = gobject.new(testhelper.OwnedByLibrary)
        self.assertEquals(obj.__grefcount__, 2)

        # We are manually taking the object out of scope. This means
        # that our wrapper has been freed, and its reference dropped. We
        # cannot check it but the refcount should now be 1 (the ref held
        # by the library is still there, we didn't call release()
        obj = None

        # When we get the object back from the lib, the wrapper is
        # re-created, so our refcount will be 2 once again.
        obj = testhelper.owned_by_library_get_instance_list()[0]
        self.assertEquals(obj.__grefcount__, 2)

        obj.release()
        self.assertEquals(obj.__grefcount__, 1)

    def testFloatingAndSunk(self):
        # Upon creation, the refcount of the object should be 2:
        # - someone already has a reference on the new object.
        # - the python wrapper should hold its own reference.
        obj = testhelper.FloatingAndSunk()
        self.assertEquals(obj.__grefcount__, 2)

        # We ask the library to release its reference, so the only
        # remaining ref should be our wrapper's. Once the wrapper
        # will run out of scope, the object will get finalized.
        obj.release()
        self.assertEquals(obj.__grefcount__, 1)

    def testFloatingAndSunkOutOfScope(self):
        obj = testhelper.FloatingAndSunk()
        self.assertEquals(obj.__grefcount__, 2)

        # We are manually taking the object out of scope. This means
        # that our wrapper has been freed, and its reference dropped. We
        # cannot check it but the refcount should now be 1 (the ref held
        # by the library is still there, we didn't call release()
        obj = None

        # When we get the object back from the lib, the wrapper is
        # re-created, so our refcount will be 2 once again.
        obj = testhelper.floating_and_sunk_get_instance_list()[0]
        self.assertEquals(obj.__grefcount__, 2)

        obj.release()
        self.assertEquals(obj.__grefcount__, 1)

 
    def testFloatingAndSunkUsingGObjectNew(self):
        # Upon creation, the refcount of the object should be 2:
        # - someone already has a reference on the new object.
        # - the python wrapper should hold its own reference.
        obj = gobject.new(testhelper.FloatingAndSunk)
        self.assertEquals(obj.__grefcount__, 2)

        # We ask the library to release its reference, so the only
        # remaining ref should be our wrapper's. Once the wrapper
        # will run out of scope, the object will get finalized.
        obj.release()
        self.assertEquals(obj.__grefcount__, 1)

    def testFloatingAndSunkOutOfScopeUsingGObjectNew(self):
        obj = gobject.new(testhelper.FloatingAndSunk)
        self.assertEquals(obj.__grefcount__, 2)

        # We are manually taking the object out of scope. This means
        # that our wrapper has been freed, and its reference dropped. We
        # cannot check it but the refcount should now be 1 (the ref held
        # by the library is still there, we didn't call release()
        obj = None

        # When we get the object back from the lib, the wrapper is
        # re-created, so our refcount will be 2 once again.
        obj = testhelper.floating_and_sunk_get_instance_list()[0]
        self.assertEquals(obj.__grefcount__, 2)

        obj.release()
        self.assertEquals(obj.__grefcount__, 1)

class A(gobject.GObject):
    def __init__(self):
        super(A, self).__init__()

class TestPythonReferenceCounting(unittest.TestCase):
    # Newly created instances should alwayshave two references: one for
    # the GC, and one for the bound variable in the local scope.

    def testNewInstanceHasTwoRefs(self):
        obj = gobject.GObject()
        self.assertEquals(sys.getrefcount(obj), 2)

    def testNewInstanceHasTwoRefsUsingGObjectNew(self):
        obj = gobject.new(gobject.GObject)
        self.assertEquals(sys.getrefcount(obj), 2)

    def testNewSubclassInstanceHasTwoRefs(self):
        obj = A()
        self.assertEquals(sys.getrefcount(obj), 2)

    def testNewSubclassInstanceHasTwoRefsUsingGObjectNew(self):
        obj = gobject.new(A)
        self.assertEquals(sys.getrefcount(obj), 2)
Something went wrong with that request. Please try again.