2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-25 06:22:15 +00:00

Initial pointer adoption tests

Have instances actually dispose of their held C++ objects!


[SVN r12652]
This commit is contained in:
Dave Abrahams
2002-02-02 20:48:37 +00:00
parent 6e5fc91885
commit 8cc9080d36
5 changed files with 126 additions and 5 deletions

20
Jamfile
View File

@@ -29,17 +29,20 @@ PYTHON_PROPERTIES
<define>BOOST_PYTHON_SOURCE
;
extension m1 : test/m1.cpp <lib>bpl # <define>BOOST_PYTHON_TRACE
# -------- general test -------
extension m1 : test/m1.cpp <lib>bpl
:
: debug-python
;
extension m2 : test/m2.cpp <lib>bpl # <define>BOOST_PYTHON_TRACE
extension m2 : test/m2.cpp <lib>bpl
:
: debug-python ;
boost-python-runtest try : test/newtest.py <lib>m1 <lib>m2 : : debug-python ;
# ----------- builtin converters -----------
extension builtin_converters_ext : test/test_builtin_converters.cpp <lib>bpl
:
: debug-python
@@ -50,4 +53,17 @@ PYTHON_PROPERTIES
:
: debug-python
;
# ----------- pointer adoption -----------
extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp <lib>bpl
:
: debug-python
;
boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py
<lib>test_pointer_adoption_ext
:
: debug-python
;
}

View File

@@ -81,6 +81,22 @@ BOOST_PYTHON_DECL ref class_metatype()
return ref((PyObject*)&class_metatype_object, ref::increment_count);
}
extern "C"
{
static void instance_dealloc(PyObject* inst)
{
instance* kill_me = (instance*)inst;
for (instance_holder* p = kill_me->objects, *next; p != 0; p = next)
{
next = p->next();
delete p;
}
inst->ob_type->tp_free(inst);
}
}
// Do we really need this? I'm beginning to think we don't!
PyTypeObject class_type_object = {
PyObject_HEAD_INIT(0) //&class_metatype_object)
@@ -88,7 +104,7 @@ PyTypeObject class_type_object = {
"Boost.Python.instance",
sizeof(instance),
0,
0, /* tp_dealloc */
instance_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
@@ -206,6 +222,7 @@ namespace
m_impl.insert(
boost::detail::lower_bound(start, finish, id)
, entry(id, object));
converter::registry::class_object(id) = (PyTypeObject*)object.get();
}
}

View File

@@ -5,8 +5,6 @@
// to its suitability for any purpose.
#include <string>
#include <boost/python/module.hpp>
#include <boost/mpl/type_list.hpp>
#include <boost/mpl/for_each.hpp>
template <class T>

View File

@@ -0,0 +1,61 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/module.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/manage_new_object.hpp>
#include <boost/python/class.hpp>
#include <boost/mpl/type_list.hpp>
using namespace boost::python;
using boost::mpl::type_list;
int a_instances = 0;
int num_a_instances() { return a_instances; }
struct A
{
A(std::string const& s)
: s(s)
{
++a_instances;
}
~A()
{
--a_instances;
}
std::string content() const
{
return s;
}
std::string s;
};
A* create(std::string const& s)
{
return new A(s);
}
BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext)
{
boost::python::module("test_pointer_adoption_ext")
.def("num_a_instances", num_a_instances)
// Specify the manage_new_object return policy to take
// ownership of create's result
.def("create", create, return_value_policy<manage_new_object>())
.add(
class_<A>()
.def("content", &A::content)
)
;
}

View File

@@ -0,0 +1,29 @@
"""
>>> from test_pointer_adoption_ext import *
>>> num_a_instances()
0
>>> a = create('dynamically allocated')
>>> num_a_instances()
1
>>> a.content()
'dynamically allocated'
>>> a = None
>>> num_a_instances()
0
"""
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])