Add unit tests, fix a C++ object refcount leak.

This commit is contained in:
Gustavo J. A. M. Carneiro committed 2008-08-20 15:26:33 +01:00
1 parent 02bbd782a8
commit 3c15d022a9
4 files changed
+83 -2

No files matched your search

+7
View File
@@ -780,6 +780,13 @@ class CppClassPtrReturnValue(CppClassReturnValueBase):
self.cpp_class.helper_class.name, const_cast_value))
wrapper.after_call.write_code("%s->obj = %s;" % (py_name, const_cast_value))
# We are already referencing the existing python wrapper,
# so we do not need a reference to the C++ object as well.
if self.caller_owns_return and \
isinstance(self.cpp_class.memory_policy, cppclass.ReferenceCountingPolicy):
self.cpp_class.memory_policy.write_decref(wrapper.after_call, value)
wrapper.after_call.write_code("Py_INCREF(%s);" % py_name)
wrapper.after_call.unindent()
wrapper.after_call.write_code("} else {")
+15 -2
View File
@@ -225,6 +225,7 @@ private:
Foo *m_foo_ptr;
Foo *m_foo_shared_ptr;
Zbr *m_zbr;
Zbr *m_internal_zbr;
public:
@@ -235,18 +236,24 @@ public:
delete m_foo_ptr;
if (m_zbr)
m_zbr->Unref ();
if (m_internal_zbr) {
m_internal_zbr->Unref ();
m_internal_zbr = NULL;
}
}
SomeObject (std::string const prefix)
: m_prefix (prefix), m_foo_ptr (0),
m_foo_shared_ptr (0), m_zbr (0)
m_foo_shared_ptr (0), m_zbr (0),
m_internal_zbr (new Zbr)
{
SomeObject::instance_count++;
}
SomeObject (int prefix_len)
: m_prefix (prefix_len, 'X'), m_foo_ptr (0),
m_foo_shared_ptr (0), m_zbr (0)
m_foo_shared_ptr (0), m_zbr (0),
m_internal_zbr (new Zbr)
{
SomeObject::instance_count++;
}
@@ -351,6 +358,12 @@ public:
return NULL;
}
// -#- @return(caller_owns_return=true) -#-
Zbr* get_internal_zbr () {
m_internal_zbr->Ref ();
return m_internal_zbr;
}
// return reference counted object, caller does not own return
// -#- @return(caller_owns_return=false) -#-
Zbr* peek_zbr () { return m_zbr; }
+2
View File
@@ -74,6 +74,7 @@ int %s::custom_method_added_by_a_hook(int x)
helper_class.add_post_generation_code("// this comment was written by a helper class hook function")
Zbr.add_helper_class_hook(helper_class_hook)
Zbr.add_constructor([])
Zbr.add_constructor([Parameter.new('std::string', 'datum')])
Zbr.add_method('get_datum', ReturnValue.new('std::string'), [])
Zbr.add_method('get_int', ReturnValue.new('int'), [Parameter.new('int', 'x')],
@@ -219,6 +220,7 @@ int %s::custom_method_added_by_a_hook(int x)
## get/set recfcounted object Zbr
SomeObject.add_method('get_zbr', ReturnValue.new('Zbr*', caller_owns_return=True), [])
SomeObject.add_method('get_internal_zbr', ReturnValue.new('Zbr*', caller_owns_return=True), [])
SomeObject.add_method('peek_zbr', ReturnValue.new('Zbr*', caller_owns_return=False), [])
SomeObject.add_method('set_zbr_transfer', ReturnValue.new('void'),
[Parameter.new('Zbr*', 'zbr', transfer_ownership=True)])
+59
View File
@@ -909,5 +909,64 @@ class TestFoo(unittest.TestCase):
self.assertEqual(s1.xpto, 123)
def test_refcounting_v2(self):
zbr_count_before = foo.Zbr.instance_count
obj = foo.SomeObject("")
z1 = obj.get_internal_zbr()
z2 = obj.get_internal_zbr()
del obj, z1, z2
while gc.collect():
pass
zbr_count_after = foo.Zbr.instance_count
self.assertEqual(zbr_count_after, zbr_count_before)
def test_refcounting_v3(self):
zbr_count_before = foo.Zbr.instance_count
class MyZbr(foo.Zbr):
pass
z_in = MyZbr()
obj = foo.SomeObject("")
obj.set_zbr_transfer(z_in)
del z_in
z1 = obj.get_zbr()
z2 = obj.get_zbr()
self.assert_(z1 is z2)
del obj, z1, z2
while gc.collect():
pass
zbr_count_after = foo.Zbr.instance_count
self.assertEqual(zbr_count_after, zbr_count_before)
def test_refcounting_v4(self): # same as v3 but using peek_zbr instead of get_zbr
zbr_count_before = foo.Zbr.instance_count
class MyZbr(foo.Zbr):
pass
z_in = MyZbr()
obj = foo.SomeObject("")
obj.set_zbr_transfer(z_in)
del z_in
z1 = obj.peek_zbr()
z2 = obj.peek_zbr()
self.assert_(z1 is z2)
del obj, z1, z2
while gc.collect():
pass
zbr_count_after = foo.Zbr.instance_count
self.assertEqual(zbr_count_after, zbr_count_before)
if __name__ == '__main__':
unittest.main()