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:
20
Jamfile
20
Jamfile
@@ -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
|
||||
;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
61
test/test_pointer_adoption.cpp
Normal file
61
test/test_pointer_adoption.cpp
Normal 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)
|
||||
)
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
29
test/test_pointer_adoption.py
Normal file
29
test/test_pointer_adoption.py
Normal 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])
|
||||
Reference in New Issue
Block a user