[DEV] add v1.66.0

This commit is contained in:
2018-01-12 21:47:58 +01:00
parent 87059bb1af
commit a97e9ae7d4
49032 changed files with 7668950 additions and 0 deletions

250
libs/python/test/Jamfile Normal file
View File

@@ -0,0 +1,250 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import python ;
import os ;
import ../../config/checks/config : requires ;
lib socket ;
use-project /boost/python : ../build ;
project /boost/python/test
: requirements
<toolset>gcc:<cxxflags>-Wextra
<target-os>qnxnto:<library>socket
;
local PY = ;
if [ python.configured ]
{
PY = /python//python ;
}
rule py-run ( sources * : input-file ? )
{
return [ run $(sources) /boost/python//boost_python $(PY)
: # args
: $(input-file)
: #requirements
<define>BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
] ;
}
rule py-compile ( sources * )
{
return [ compile $(sources) /boost/python//boost_python ] ;
}
rule py-compile-fail ( sources * )
{
return [ compile-fail $(sources) /boost/python//boost_python ] ;
}
rule require-windows ( properties * )
{
if ! <target-os>windows in $(properties)
{
return <build>no ;
}
}
test-suite python
:
[
run exec.cpp /boost/python//boost_python/<link>static $(PY)
: # program args
: exec.py # input files
: # requirements
: # target-name
]
[
run exec.cpp ../build//boost_python/<link>shared /python//python
: # program args
: exec.py
: # requirements
: exec-dynamic # target-name
]
# [
# run import_.cpp ../build//boost_python /python//python
# : # program args
# : import_.py # input files
# : # requirements
# : # target-name
# ]
[
bpl-test crossmod_exception
: crossmod_exception.py crossmod_exception_a.cpp crossmod_exception_b.cpp
]
[ bpl-test injected ]
[ bpl-test properties ]
[ bpl-test return_arg ]
[ bpl-test staticmethod ]
[ bpl-test boost_shared_ptr ]
[ bpl-test shared_ptr
: # sources
: [ requires cxx11_smart_ptr ]
]
[ bpl-test enable_shared_from_this ]
[ bpl-test andreas_beyer ]
[ bpl-test wrapper_held_type ]
[ bpl-test polymorphism2_auto_ptr
: polymorphism2_auto_ptr.py polymorphism2.py polymorphism2_auto_ptr.cpp
]
[ bpl-test polymorphism ]
[ bpl-test polymorphism2 ]
[ bpl-test auto_ptr ]
[ bpl-test minimal ]
[ bpl-test args ]
[ bpl-test raw_ctor ]
[ bpl-test enum : test_enum.py enum_ext.cpp ]
[ bpl-test exception_translator ]
[ bpl-test pearu1 : test_cltree.py cltree.cpp ]
[ bpl-test try : newtest.py m1.cpp m2.cpp ]
[ bpl-test const_argument ]
[ bpl-test keywords : keywords.cpp keywords_test.py ]
[ python-extension builtin_converters_ext : builtin_converters.cpp /boost/python//boost_python ]
[ bpl-test builtin_converters : test_builtin_converters.py builtin_converters_ext ]
[ bpl-test test_pointer_adoption ]
[ bpl-test operators ]
[ bpl-test operators_wrapper ]
[ bpl-test callbacks ]
[ bpl-test defaults ]
[ bpl-test object ]
[ bpl-test class ]
[ bpl-test list ]
[ bpl-test long ]
[ bpl-test dict ]
[ bpl-test tuple ]
[ bpl-test str ]
[ bpl-test slice ]
[ bpl-test virtual_functions ]
[ bpl-test back_reference ]
[ bpl-test implicit ]
[ bpl-test data_members ]
[ bpl-test ben_scott1 ]
[ bpl-test bienstman1 ]
[ bpl-test bienstman2 ]
[ bpl-test bienstman3 ]
[ bpl-test multi_arg_constructor
: # files
: # requirements
# A bug in the Win32 intel compilers causes compilation of one of our
# tests to take forever when debug symbols are enabled. This rule
# turns them off when added to the requirements section
<toolset>intel-win:<debug-symbols>off
]
[ bpl-test iterator : iterator.py iterator.cpp input_iterator.cpp ]
[ bpl-test stl_iterator : stl_iterator.py stl_iterator.cpp ]
[ bpl-test extract ]
[
bpl-test crossmod_opaque
: crossmod_opaque.py crossmod_opaque_a.cpp crossmod_opaque_b.cpp
]
[ bpl-test opaque ]
[ bpl-test voidptr ]
[ bpl-test pickle1 ]
[ bpl-test pickle2 ]
[ bpl-test pickle3 ]
[ bpl-test pickle4 ]
[ bpl-test nested ]
[ bpl-test docstring ]
[ bpl-test pytype_function ]
[ bpl-test vector_indexing_suite ]
[ bpl-test pointer_vector
: # files
: # requirements
# Turn off this test on HP CXX, as the test hangs when executing.
# Whenever the cause for the failure of the polymorphism test is found
# and fixed, this should be retested.
<toolset>hp_cxx:<build>no ]
[ python-extension map_indexing_suite_ext
: map_indexing_suite.cpp int_map_indexing_suite.cpp a_map_indexing_suite.cpp
/boost/python//boost_python ]
[ bpl-test
map_indexing_suite : map_indexing_suite.py map_indexing_suite_ext ]
[ run import_.cpp /boost/python//boost_python $(PY) : : import_.py ]
# if $(TEST_BIENSTMAN_NON_BUGS)
# {
# bpl-test bienstman4 ;
# bpl-test bienstman5 ;
# }
[ bpl-test calling_conventions : : <conditional>@require-windows ]
[ bpl-test calling_conventions_mf : : <conditional>@require-windows ]
# --- unit tests of library components ---
[ compile indirect_traits_test.cpp ]
[ run destroy_test.cpp ]
[ py-run pointer_type_id_test.cpp ]
[ py-run bases.cpp ]
[ run if_else.cpp ]
[ py-run pointee.cpp ]
[ run result.cpp ]
[ compile string_literal.cpp ]
[ py-compile borrowed.cpp ]
[ py-compile object_manager.cpp ]
[ py-compile copy_ctor_mutates_rhs.cpp ]
[ py-run upcast.cpp ]
[ py-compile select_holder.cpp ]
[ run select_from_python_test.cpp ../src/converter/type_id.cpp
:
:
: <define>BOOST_PYTHON_STATIC_LIB
<use>$(PY)
]
[ py-compile select_arg_to_python_test.cpp ]
[ py-compile-fail ./raw_pyobject_fail1.cpp ]
[ py-compile-fail ./raw_pyobject_fail2.cpp ]
[ py-compile-fail ./as_to_python_function.cpp ]
[ py-compile-fail ./object_fail1.cpp ]
# --- NumPy tests ---
[ numpy-test numpy/dtype ]
[ numpy-test numpy/ufunc ]
[ numpy-test numpy/templates ]
[ numpy-test numpy/ndarray ]
[ numpy-test numpy/indexing ]
[ numpy-test numpy/shapes ]
;

169
libs/python/test/SConscript Normal file
View File

@@ -0,0 +1,169 @@
# -*- python -*-
#
# Copyright (c) 2016 Stefan Seefeld
# All rights reserved.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
import platform
import sys
Import('env')
if sys.platform == 'win32':
# HACK: This works around a bug in SCons.
# subprocess.check_output will complain unless all environment
# variables are strings.
system_root = env['ENV']['SystemRoot']
env['ENV']['SystemRoot'] = str(system_root)
# libs needed for embedding
ELIBS=env['LIBS'] + env['PYTHONLIBS']
def BPLTest(env, name, sources = None, deps = None):
run = env.BoostRunPythonScript(name + '.py')
if sources:
for source in sources:
Depends(run,
env.PythonExtension(source != name and source or (source + '_ext'), source + '.cpp')
)
else:
Depends(run, env.PythonExtension(name + '_ext', name + '.cpp'))
if deps:
Depends(run, deps)
return run
env.AddMethod(BPLTest)
env.AppendENVPath('PYTHONPATH', Dir('.').path)
tests=[]
tests+=env.BPLTest('crossmod_exception', ['crossmod_exception_a', 'crossmod_exception_b'])
for test in [('injected',),
('properties',),
('return_arg',),
('staticmethod',),
('boost_shared_ptr',),
('enable_shared_from_this',),
('andreas_beyer',),
('polymorphism',),
('polymorphism2',),
('wrapper_held_type',),
('minimal',),
('args',),
('raw_ctor',),
('exception_translator',),
('test_enum', ['enum_ext']),
('test_cltree', ['cltree']),
('newtest', ['m1', 'm2']),
('const_argument',),
('keywords_test', ['keywords']),
('test_pointer_adoption',),
('operators',),
('operators_wrapper',),
('callbacks',),
('defaults',),
('object',),
('list',),
('long',),
('dict',),
('tuple',),
('str',),
('slice',),
('virtual_functions',),
('back_reference',),
('implicit',),
('data_members',),
('ben_scott1',),
('bienstman1',),
('bienstman2',),
('bienstman3',),
('multi_arg_constructor',),
('iterator', ['iterator', 'input_iterator']),
('stl_iterator',),
('extract',),
('crossmod_opaque', ['crossmod_opaque_a', 'crossmod_opaque_b']),
('opaque',),
# ('voidptr',),
('pickle1',),
('pickle2',),
('pickle3',),
('pickle4',),
('nested',),
('docstring',),
('pytype_function',),
('vector_indexing_suite',),
('pointer_vector',)]:
tests+=env.BPLTest(*test)
if env['CXX11']:
for test in [
('shared_ptr',),
]:
tests+=env.BPLTest(*test)
else:
for test in [
('polymorphism2_auto_ptr',),
('auto_ptr',),
]:
tests+=env.BPLTest(*test)
test = env.BoostRunPythonScript('test_builtin_converters.py')
Depends(
test,
env.PythonExtension('builtin_converters_ext', ['builtin_converters.cpp'])
)
tests+=test
test = env.BoostRunPythonScript('map_indexing_suite.py')
Depends(
test,
env.PythonExtension('map_indexing_suite_ext', [
'map_indexing_suite.cpp',
'int_map_indexing_suite.cpp',
'a_map_indexing_suite.cpp'])
)
tests+=test
tests+=env.BoostRunTest('import_', 'import_.cpp', '${SOURCES[0]} ${SOURCES[1]}', 'import_.py', LIBS=ELIBS)
tests+=env.BoostCompileTest('indirect_traits_test')
tests+=env.BoostRunTests(['destroy_test',
'pointer_type_id_test',
'bases',
'if_else',
'pointee',
'result'], LIBS=ELIBS)
tests+=env.BoostCompileTests(['string_literal',
'borrowed',
'object_manager',
'copy_ctor_mutates_rhs'])
tests+=env.BoostRunTest('upcast', LIBS=ELIBS)
tests+=env.BoostCompileTest('select_holder')
tests+=env.BoostRunTest('select_from_python_test', LIBS=ELIBS)
tests+=env.BoostCompileTest('select_arg_to_python_test')
if platform.system() == 'Windows':
tests+=env.BPLTest('calling_conventions')
tests+=env.BPLTest('calling_conventions_mf')
if env['NUMPY']:
numpy_env = env.Clone()
numpy_env.BoostUseLib('numpy')
for test in [('numpy/dtype',),
('numpy/ufunc',),
('numpy/templates',),
('numpy/ndarray',),
('numpy/indexing',),
('numpy/shapes',),]:
tests+=numpy_env.BPLTest(*test)
env.BoostTestSummary(tests)
AlwaysBuild(tests)

View File

@@ -0,0 +1,92 @@
// Copyright Joel de Guzman 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/implicit.hpp>
using namespace boost::python;
struct A
{
int value;
A() : value(0){};
A(int v) : value(v) {};
};
bool operator==(const A& v1, const A& v2)
{
return (v1.value == v2.value);
}
struct B
{
A a;
};
// Converter from A to python int
struct AToPython
{
static PyObject* convert(const A& s)
{
return boost::python::incref(boost::python::object((int)s.value).ptr());
}
};
// Conversion from python int to A
struct AFromPython
{
AFromPython()
{
boost::python::converter::registry::push_back(
&convertible,
&construct,
boost::python::type_id< A >());
}
static void* convertible(PyObject* obj_ptr)
{
#if PY_VERSION_HEX >= 0x03000000
if (!PyLong_Check(obj_ptr)) return 0;
#else
if (!PyInt_Check(obj_ptr)) return 0;
#endif
return obj_ptr;
}
static void construct(
PyObject* obj_ptr,
boost::python::converter::rvalue_from_python_stage1_data* data)
{
void* storage = (
(boost::python::converter::rvalue_from_python_storage< A >*)
data)-> storage.bytes;
#if PY_VERSION_HEX >= 0x03000000
new (storage) A((int)PyLong_AsLong(obj_ptr));
#else
new (storage) A((int)PyInt_AsLong(obj_ptr));
#endif
data->convertible = storage;
}
};
void a_map_indexing_suite()
{
to_python_converter< A , AToPython >();
AFromPython();
class_< std::map<int, A> >("AMap")
.def(map_indexing_suite<std::map<int, A>, true >())
;
class_< B >("B")
.add_property("a", make_getter(&B::a, return_value_policy<return_by_value>()),
make_setter(&B::a, return_value_policy<return_by_value>()))
;
}

View File

@@ -0,0 +1,61 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
using namespace boost;
class A : public enable_shared_from_this<A> {
public:
A() : val(0) {};
int val;
typedef shared_ptr<A> A_ptr;
A_ptr self() {
A_ptr self;
self = shared_from_this();
return self;
}
};
class B {
public:
B() {
a = A::A_ptr(new A());
}
void set(A::A_ptr _a) {
this->a = _a;
}
A::A_ptr get() {
return a;
}
A::A_ptr a;
};
template <class T>
void hold_python(shared_ptr<T>& x)
{
x = python::extract<shared_ptr<T> >( python::object(x) );
}
A::A_ptr get_b_a(shared_ptr<B> b)
{
hold_python(b->a);
return b->get();
}
BOOST_PYTHON_MODULE(andreas_beyer_ext) {
python::class_<A, noncopyable> ("A")
.def("self", &A::self)
.def_readwrite("val", &A::val)
;
python::register_ptr_to_python< A::A_ptr >();
python::class_<B>("B")
.def("set", &B::set)
// .def("get", &B::get)
.def("get", get_b_a)
;
}

View File

@@ -0,0 +1,24 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from andreas_beyer_ext import *
>>> b=B()
>>> a=b.get() # let b create an A
>>> a2=b.get()
>>> assert id(a) == id(a2)
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

99
libs/python/test/args.cpp Normal file
View File

@@ -0,0 +1,99 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include "test_class.hpp"
#include <boost/python/def.hpp>
#include <boost/python/args.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/class.hpp>
#include <boost/python/overloads.hpp>
#include <boost/python/raw_function.hpp>
#include <boost/python/return_internal_reference.hpp>
using namespace boost::python;
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
# define make_tuple boost::python::make_tuple
#endif
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
{
return make_tuple(x, y, z);
}
BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3)
typedef test_class<> Y;
struct X
{
X(int a0 = 0, int a1 = 1) : inner0(a0), inner1(a1) {}
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
{
return make_tuple(x, y, z);
}
Y const& inner(bool n) const { return n ? inner1 : inner0; }
Y inner0;
Y inner1;
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3)
tuple raw_func(tuple args, dict kw)
{
return make_tuple(args, kw);
}
BOOST_PYTHON_MODULE(args_ext)
{
def("f", f, (arg("x")=1, arg("y")=4.25, arg("z")="wow")
, "This is f's docstring"
);
def("raw", raw_function(raw_func));
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1200
// MSVC6 gives a fatal error LNK1179: invalid or corrupt file:
// duplicate comdat error if we try to re-use the exact type of f
// here, so substitute long for int.
tuple (*f)(long,double,char const*) = 0;
#endif
def("f1", f, f_overloads("f1's docstring", args("x", "y", "z")));
def("f2", f, f_overloads(args("x", "y", "z")));
def("f3", f, f_overloads(args("x", "y", "z"), "f3's docstring"));
class_<Y>("Y", init<int>(args("value"), "Y's docstring"))
.def("value", &Y::value)
.def("raw", raw_function(raw_func))
;
class_<X>("X", "This is X's docstring", init<>(args("self")))
.def(init<int, optional<int> >(args("self", "a0", "a1")))
.def("f", &X::f
, "This is X.f's docstring"
, args("self","x", "y", "z"))
// Just to prove that all the different argument combinations work
.def("inner0", &X::inner, return_internal_reference<>(), args("self", "n"), "docstring")
.def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("self", "n"))
.def("inner2", &X::inner, args("self", "n"), return_internal_reference<>(), "docstring")
.def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("self", "n"))
.def("inner4", &X::inner, args("self", "n"), "docstring", return_internal_reference<>())
.def("inner5", &X::inner, "docstring", args("self", "n"), return_internal_reference<>())
.def("f1", &X::f, X_f_overloads(args("self", "x", "y", "z")))
.def("f2", &X::f, X_f_overloads(args("self", "x", "y", "z"), "f2's docstring"))
.def("f2", &X::f, X_f_overloads(args("x", "y", "z"), "f2's docstring"))
;
def("inner", &X::inner, "docstring", args("self", "n"), return_internal_reference<>());
}
#include "module_tail.cpp"

148
libs/python/test/args.py Normal file
View File

@@ -0,0 +1,148 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
"""
>>> from args_ext import *
>>> raw(3, 4, foo = 'bar', baz = 42)
((3, 4), {'foo': 'bar', 'baz': 42})
Prove that we can handle empty keywords and non-keywords
>>> raw(3, 4)
((3, 4), {})
>>> raw(foo = 'bar')
((), {'foo': 'bar'})
>>> f(x= 1, y = 3, z = 'hello')
(1, 3.0, 'hello')
>>> f(z = 'hello', x = 3, y = 2.5)
(3, 2.5, 'hello')
>>> f(1, z = 'hi', y = 3)
(1, 3.0, 'hi')
>>> try: f(1, 2, 'hello', bar = 'baz')
... except TypeError: pass
... else: print('expected an exception: unknown keyword')
Exercise the functions using default stubs
>>> f1(z = 'nix', y = .125, x = 2)
(2, 0.125, 'nix')
>>> f1(y = .125, x = 2)
(2, 0.125, 'wow')
>>> f1(x = 2)
(2, 4.25, 'wow')
>>> f1()
(1, 4.25, 'wow')
>>> f2(z = 'nix', y = .125, x = 2)
(2, 0.125, 'nix')
>>> f2(y = .125, x = 2)
(2, 0.125, 'wow')
>>> f2(x = 2)
(2, 4.25, 'wow')
>>> f2()
(1, 4.25, 'wow')
>>> f3(z = 'nix', y = .125, x = 2)
(2, 0.125, 'nix')
>>> f3(y = .125, x = 2)
(2, 0.125, 'wow')
>>> f3(x = 2)
(2, 4.25, 'wow')
>>> f3()
(1, 4.25, 'wow')
Member function tests
>>> q = X()
>>> q.f(x= 1, y = 3, z = 'hello')
(1, 3.0, 'hello')
>>> q.f(z = 'hello', x = 3, y = 2.5)
(3, 2.5, 'hello')
>>> q.f(1, z = 'hi', y = 3)
(1, 3.0, 'hi')
>>> try: q.f(1, 2, 'hello', bar = 'baz')
... except TypeError: pass
... else: print('expected an exception: unknown keyword')
Exercise member functions using default stubs
>>> q.f1(z = 'nix', y = .125, x = 2)
(2, 0.125, 'nix')
>>> q.f1(y = .125, x = 2)
(2, 0.125, 'wow')
>>> q.f1(x = 2)
(2, 4.25, 'wow')
>>> q.f1()
(1, 4.25, 'wow')
>>> q.f2.__doc__.splitlines()[1]
'f2( (X)self [, (int)x [, (float)y [, (str)z]]]) -> tuple :'
>>> q.f2.__doc__.splitlines()[2]
" f2's docstring"
>>> X.f.__doc__.splitlines()[1:5]
['f( (X)self, (int)x, (float)y, (str)z) -> tuple :', " This is X.f's docstring", '', ' C++ signature :']
>>> xfuncs = (X.inner0, X.inner1, X.inner2, X.inner3, X.inner4, X.inner5)
>>> for f in xfuncs:
... print(f(q,1).value(), end=' ')
... print(f(q, n = 1).value(), end=' ')
... print(f(q, n = 0).value(), end=' ')
... print(f.__doc__.splitlines()[1:5])
1 1 0 ['inner0( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
1 1 0 ['inner1( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
1 1 0 ['inner2( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
1 1 0 ['inner3( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
1 1 0 ['inner4( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
1 1 0 ['inner5( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
>>> x = X(a1 = 44, a0 = 22)
>>> x.inner0(0).value()
22
>>> x.inner0(1).value()
44
>>> x = X(a0 = 7)
>>> x.inner0(0).value()
7
>>> x.inner0(1).value()
1
>>> inner(n = 1, self = q).value()
1
>>> y = Y(value = 33)
>>> y.raw(this = 1, that = 'the other')[1]
{'this': 1, 'that': 'the other'}
"""
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
status = run()[0]
if (status == 0): print("Done.")
import args_ext
help(args_ext)
sys.exit(status)

View File

@@ -0,0 +1,13 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/converter/as_to_python_function.hpp>
struct hopefully_illegal
{
static PyObject* convert(int&);
};
PyObject* x = boost::python::converter::as_to_python_function<int, hopefully_illegal>::convert(0);

View File

@@ -0,0 +1,90 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include "test_class.hpp"
#include <boost/python/class.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/def.hpp>
#include <boost/python/implicit.hpp>
#include <boost/detail/workaround.hpp>
#include <memory>
using namespace boost::python;
typedef test_class<> X;
struct Y : X
{
Y(int n) : X(n) {};
};
int look(std::auto_ptr<X> const& x)
{
return (x.get()) ? x->value() : -1;
}
int steal(std::auto_ptr<X> x)
{
return x->value();
}
int maybe_steal(std::auto_ptr<X>& x, bool doit)
{
int n = x->value();
if (doit)
x.release();
return n;
}
std::auto_ptr<X> make()
{
return std::auto_ptr<X>(new X(77));
}
std::auto_ptr<X> callback(object f)
{
std::auto_ptr<X> x(new X(77));
return call<std::auto_ptr<X> >(f.ptr(), x);
}
std::auto_ptr<X> extract_(object o)
{
return extract<std::auto_ptr<X>&>(o)
#if BOOST_MSVC <= 1300
()
#endif
;
}
BOOST_PYTHON_MODULE(auto_ptr_ext)
{
class_<X, std::auto_ptr<X>, boost::noncopyable>("X", init<int>())
.def("value", &X::value)
;
class_<Y, std::auto_ptr<Y>, bases<X>, boost::noncopyable>("Y", init<int>())
;
// VC6 auto_ptrs do not have converting constructors
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 306)
scope().attr("broken_auto_ptr") = 1;
#else
scope().attr("broken_auto_ptr") = 0;
implicitly_convertible<std::auto_ptr<Y>, std::auto_ptr<X> >();
#endif
def("look", look);
def("steal", steal);
def("maybe_steal", maybe_steal);
def("make", make);
def("callback", callback);
def("extract", extract_);
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,100 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from auto_ptr_ext import *
>>> x = X(42)
>>> x.value()
42
>>> look(x), look(x)
(42, 42)
>>> maybe_steal(x, 0)
42
>>> look(x)
42
>>> maybe_steal(x, 1)
42
>>> broken_auto_ptr and -1 or look(x)
-1
>>> x = X(69)
>>> steal(x)
69
>>> broken_auto_ptr and -1 or look(x)
-1
>>> if not broken_auto_ptr:
... try: x.value()
... except TypeError: pass
... else: print('expected a TypeError exception')
>>> x = make()
>>> look(x)
77
>>> z = callback(lambda z: z)
>>> z.value()
77
>>> extract(x).value()
77
#
# Test derived to base conversions
#
>>> y = Y(42)
>>> y.value()
42
>>> try: maybe_steal(y, 0)
... except TypeError: pass
... else: print('expected a TypeError exception')
>>> y.value()
42
>>> broken_auto_ptr and 42 or steal(y)
42
>>> if not broken_auto_ptr:
... try: y.value()
... except TypeError: pass
... else: print('expected a TypeError exception')
>>> print(look.__doc__.splitlines()[1])
look( (X)arg1) -> int :
>>> print(steal.__doc__.splitlines()[1])
steal( (X)arg1) -> int :
>>> print(maybe_steal.__doc__.splitlines()[1])
maybe_steal( (X)arg1, (bool)arg2) -> int :
>>> print(make.__doc__.splitlines()[1])
make() -> X :
>>> print(callback.__doc__.splitlines()[1])
callback( (object)arg1) -> X :
>>> print(extract.__doc__.splitlines()[1])
extract( (object)arg1) -> X :
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,112 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/has_back_reference.hpp>
#include <boost/python/back_reference.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>
#include <memory>
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/mpl/bool.hpp>
// This test shows that a class can be wrapped "as itself" but also
// acquire a back-reference iff has_back_reference<> is appropriately
// specialized.
using namespace boost::python;
struct X
{
explicit X(int x) : x(x), magic(7654321) { ++counter; }
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
virtual ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
static int count() { return counter; }
private:
void operator=(X const&);
private:
int x;
long magic;
static int counter;
};
int X::counter;
struct Y : X
{
Y(PyObject* self, int x) : X(x), self(self) {}
Y(PyObject* self, Y const& rhs) : X(rhs), self(self) {}
private:
Y(Y const&);
PyObject* self;
};
struct Z : X
{
Z(PyObject* self, int x) : X(x), self(self) {}
Z(PyObject* self, Z const& rhs) : X(rhs), self(self) {}
private:
Z(Z const&);
PyObject* self;
};
Y const& copy_Y(Y const& y) { return y; }
Z const& copy_Z(Z const& z) { return z; }
namespace boost { namespace python
{
template <>
struct has_back_reference<Y>
: mpl::true_
{
};
template <>
struct has_back_reference<Z>
: mpl::true_
{
};
}}
// prove that back_references get initialized with the right PyObject*
object y_identity(back_reference<Y const&> y)
{
return y.source();
}
// prove that back_references contain the right value
bool y_equality(back_reference<Y const&> y1, Y const& y2)
{
return &y1.get() == &y2;
}
BOOST_PYTHON_MODULE(back_reference_ext)
{
def("copy_Y", copy_Y, return_value_policy<copy_const_reference>());
def("copy_Z", copy_Z, return_value_policy<copy_const_reference>());
def("x_instances", &X::count);
class_<Y>("Y", init<int>())
.def("value", &Y::value)
.def("set", &Y::set)
;
class_<Z,std::auto_ptr<Z> >("Z", init<int>())
.def("value", &Z::value)
.def("set", &Z::set)
;
def("y_identity", y_identity);
def("y_equality", y_equality);
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,37 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from back_reference_ext import *
>>> y = Y(3)
>>> z = Z(4)
>>> x_instances()
2
>>> y2 = copy_Y(y)
>>> x_instances()
3
>>> z2 = copy_Z(z)
>>> x_instances()
4
>>> assert y_identity(y) is y
>>> y_equality(y, y)
1
>>> print(y_identity.__doc__.splitlines()[1])
y_identity( (Y)arg1) -> object :
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,62 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/bases.hpp>
#include <boost/static_assert.hpp>
#include <boost/python/detail/type_traits.hpp>
struct A;
struct B;
template <class X, class Y, class Z>
struct choose_bases
: boost::python::detail::select_bases<
X
, typename boost::python::detail::select_bases<
Y
, typename boost::python::detail::select_bases<Z>::type
>::type>
{
};
int main()
{
BOOST_STATIC_ASSERT((boost::python::detail::specifies_bases<
boost::python::bases<A,B> >::value));
BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases<
boost::python::bases<A,B>& >::value));
BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases<
void* >::value));
BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases<
int >::value));
BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases<
int[5] >::value));
typedef boost::python::detail::select_bases<
int
, boost::python::detail::select_bases<char*>::type > collected1;
BOOST_STATIC_ASSERT((boost::python::detail::is_same<collected1::type,boost::python::bases<> >::value));
BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose_bases<int,char*,long>::type,boost::python::bases<> >::value));
typedef boost::python::detail::select_bases<
int
, boost::python::detail::select_bases<
boost::python::bases<A,B>
, boost::python::detail::select_bases<
A
>::type
>::type
> collected2;
BOOST_STATIC_ASSERT((boost::python::detail::is_same<collected2::type,boost::python::bases<A,B> >::value));
BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose_bases<int,boost::python::bases<A,B>,long>::type,boost::python::bases<A,B> >::value));
return 0;
}

View File

@@ -0,0 +1,54 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python.hpp>
#include <iostream>
using namespace boost::python;
using namespace boost;
struct Product {};
typedef shared_ptr<Product> ProductPtr;
struct Creator
{
virtual ~Creator() {}
virtual ProductPtr create() = 0;
};
struct Factory
{
void reg(Creator* c) { mC = c; }
ProductPtr create()
{
std::cout << "Name: " << (typeid(*mC)).name() << std::endl;
return mC->create();
}
private:
Creator* mC;
};
struct CreatorWrap : public Creator
{
CreatorWrap(PyObject* self) : mSelf(self) {}
ProductPtr create() { return call_method<ProductPtr>(mSelf, "create"); }
PyObject* mSelf;
};
BOOST_PYTHON_MODULE(ben_scott1_ext)
{
class_<Product, ProductPtr>("Product");
class_<Creator, CreatorWrap, noncopyable>("Creator")
.def("create", &CreatorWrap::create)
;
class_<Factory>("Factory")
.def("reg", &Factory::reg, with_custodian_and_ward<1,2>())
.def("create", &Factory::create)
;
}
#include "../test/module_tail.cpp"

View File

@@ -0,0 +1,17 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# This regression test checks that call_method<T>(...) where T is a
# non-reference, non-pointer type that happens to be held inside the
# result object (and thus is found as an lvalue) works.
from ben_scott1_ext import *
class CreatorImpl(Creator):
def create(self):
return Product()
factory = Factory()
c = CreatorImpl()
factory.reg(c)
a = factory.create()

View File

@@ -0,0 +1,40 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/return_value_policy.hpp>
struct A {};
struct V
{
virtual ~V() {}; // silence compiler warningsa
virtual void f() = 0;
const A* inside() {return &a;}
A a;
};
const A* outside(const V& v) {return &v.a;}
BOOST_PYTHON_MODULE(bienstman1_ext)
{
using namespace boost::python;
using boost::shared_ptr;
using boost::python::return_value_policy;
using boost::python::reference_existing_object;
class_<A>("A");
class_<V, boost::noncopyable>("V", no_init)
.def("inside", &V::inside,
return_value_policy<reference_existing_object>())
.def("outside", outside,
return_value_policy<reference_existing_object>())
;
}

View File

@@ -0,0 +1,23 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
# Try to reproduce a Numeric interaction bug if Numeric is installed.
>>> from bienstman1_ext import *
>>> try: from Numeric import *
... except: pass
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,28 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
struct C {};
struct D {};
struct E
{
const D fe (const C&) {return D();}
const D fe2(const C&, const C&) {return D();}
};
BOOST_PYTHON_MODULE(bienstman2_ext)
{
using namespace boost::python;
class_<C>("C");
class_<D>("D");
class_<E>("E")
.def("fe", &E::fe) // this compiles.
.def("fe2", &E::fe2) // this doesn't... well, now it does ;-)
;
}

View File

@@ -0,0 +1,20 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> import bienstman2_ext
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,26 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
struct V
{
virtual ~V() {}; // silence compiler warningsa
virtual void f() = 0;
};
struct B
{
B(const V&) {}
};
BOOST_PYTHON_MODULE(bienstman3_ext)
{
using namespace boost::python;
class_<V, boost::noncopyable>("V", no_init);
class_<B>("B", init<const V&>());
}

View File

@@ -0,0 +1,30 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from bienstman3_ext import *
>>> try:
... V()
... except RuntimeError as x:
... print(x)
... else:
... print('expected an exception')
...
This class cannot be instantiated from Python
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,39 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/implicit.hpp>
#include <boost/mpl/list.hpp>
struct Type1 {};
struct Term {Term(Type1 const&) {} };
struct Expression {void add(Term const&) {} };
BOOST_PYTHON_MODULE(bienstman4_ext)
{
using namespace boost::python;
using boost::mpl::list;
implicitly_convertible<Type1,Term>();
class_<Expression>("Expression")
.def("add", &Expression::add)
;
class_<Type1>("T1")
;
class_<Term>("Term", init<Type1&>())
;
Type1 t1;
Expression e;
e.add(t1);
}

View File

@@ -0,0 +1,23 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from bienstman4_ext import *
>>> t1 = T1()
>>> e = Expression()
>>> e.add(t1)
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,23 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/mpl/list.hpp>
#include <complex>
struct M {M(const std::complex<double>&) {} };
BOOST_PYTHON_MODULE(bienstman5_ext)
{
using namespace boost::python;
class_<M>("M", init<std::complex<double> const&>())
;
}

View File

@@ -0,0 +1,21 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from bienstman5_ext import *
>>> m = M(1j)
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,20 @@
// Copyright David Abrahams 2002.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/def.hpp>
#include <boost/shared_ptr.hpp>
#include <memory>
using boost::shared_ptr;
#define MODULE boost_shared_ptr_ext
#include "shared_ptr.hpp"
#include "module_tail.cpp"

View File

@@ -0,0 +1,130 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from boost_shared_ptr_ext import *
Test that shared_ptr<Derived> can be converted to shared_ptr<Base>
>>> Y.store(YYY(42))
>>> x = X(17)
>>> null_x = null(x)
>>> null_x # should be None
>>> identity(null_x) # should also be None
>>> a = New(1)
>>> A.call_f(a)
1
>>> New(0)
>>> type(factory(3))
<class 'boost_shared_ptr_ext.Y'>
>>> type(factory(42))
<class 'boost_shared_ptr_ext.YY'>
>>> class P(Z):
... def v(self):
... return -Z.v(self);
... def __del__(self):
... print('bye')
...
>>> p = P(12)
>>> p.value()
12
>>> p.v()
-12
>>> look(p)
12
>>> try: modify(p)
... except TypeError: pass
... else: 'print(expected a TypeError)'
>>> look(None)
-1
>>> store(p)
>>> del p
>>> Z.get().v()
-12
>>> Z.count()
1
>>> Z.look_store()
12
>>> Z.release()
bye
>>> Z.count()
0
>>> z = Z(13)
>>> z.value()
13
>>> z.v()
13
>>> try: modify(z)
... except TypeError: pass
... else: 'print(expected a TypeError)'
>>> Z.get() # should be None
>>> store(z)
>>> assert Z.get() is z # show that deleter introspection works
>>> del z
>>> Z.get().value()
13
>>> Z.count()
1
>>> Z.look_store()
13
>>> Z.release()
>>> Z.count()
0
>>> x = X(17)
>>> x.value()
17
>>> look(x)
17
>>> try: modify(x)
... except TypeError: pass
... else: 'print(expected a TypeError)'
>>> look(None)
-1
>>> store(x)
>>> del x
>>> X.count()
1
>>> X.look_store()
17
>>> X.release()
>>> X.count()
0
>>> y = Y(19)
>>> y.value()
19
>>> modify(y)
>>> look(y)
-1
>>> store(Y(23))
>>> Y.count()
1
>>> Y.look_store()
23
>>> Y.release()
>>> Y.count()
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,33 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/detail/wrap_python.hpp>
#include <boost/python/borrowed.hpp>
#include <boost/static_assert.hpp>
using namespace boost::python;
template <class T>
void assert_borrowed_ptr(T const&)
{
BOOST_STATIC_ASSERT(boost::python::detail::is_borrowed_ptr<T>::value);
}
template <class T>
void assert_not_borrowed_ptr(T const&)
{
BOOST_STATIC_ASSERT(!boost::python::detail::is_borrowed_ptr<T>::value);
}
int main()
{
assert_borrowed_ptr(borrowed((PyObject*)0));
assert_borrowed_ptr(borrowed((PyTypeObject*)0));
assert_borrowed_ptr((detail::borrowed<PyObject> const*)0);
assert_borrowed_ptr((detail::borrowed<PyObject> volatile*)0);
assert_borrowed_ptr((detail::borrowed<PyObject> const volatile*)0);
assert_not_borrowed_ptr((PyObject*)0);
assert_not_borrowed_ptr(0);
return 0;
}

View File

@@ -0,0 +1,152 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <complex>
#include <boost/python/handle.hpp>
#include <boost/python/cast.hpp>
#include <boost/python/object.hpp>
#include <boost/python/detail/wrap_python.hpp>
template <class T>
struct by_value
{
static T rewrap(T x)
{
return x;
}
static int size(void)
{
return sizeof(T);
}
};
template <class T>
struct by_const_reference
{
static T rewrap(T const& x)
{
return x;
}
};
template <class T>
struct by_reference
{
static T rewrap(T& x)
{
return x;
}
};
using boost::python::def;
using boost::python::handle;
using boost::python::object;
using boost::python::borrowed;
// Used to test that arbitrary handle<>s can be returned
handle<PyTypeObject> get_type(handle<> x)
{
return handle<PyTypeObject>(borrowed(x->ob_type));
}
handle<> return_null_handle()
{
return handle<>();
}
char const* rewrap_value_mutable_cstring(char* x) { return x; }
object identity_(object x) { return x; }
BOOST_PYTHON_MODULE(builtin_converters_ext)
{
def("get_type", get_type);
def("return_null_handle", return_null_handle);
// These methods are used solely for getting some C++ type sizes
def("bool_size", by_value<bool>::size);
def("char_size", by_value<char>::size);
def("int_size", by_value<int>::size);
def("short_size", by_value<short>::size);
def("long_size", by_value<long>::size);
#ifdef HAVE_LONG_LONG
def("long_long_size", by_value<BOOST_PYTHON_LONG_LONG>::size);
#endif
def("rewrap_value_bool", by_value<bool>::rewrap);
def("rewrap_value_char", by_value<char>::rewrap);
def("rewrap_value_signed_char", by_value<signed char>::rewrap);
def("rewrap_value_unsigned_char", by_value<unsigned char>::rewrap);
def("rewrap_value_int", by_value<int>::rewrap);
def("rewrap_value_unsigned_int", by_value<unsigned int>::rewrap);
def("rewrap_value_short", by_value<short>::rewrap);
def("rewrap_value_unsigned_short", by_value<unsigned short>::rewrap);
def("rewrap_value_long", by_value<long>::rewrap);
def("rewrap_value_unsigned_long", by_value<unsigned long>::rewrap);
// using Python's macro instead of Boost's - we don't seem to get the
// config right all the time.
#ifdef HAVE_LONG_LONG
def("rewrap_value_long_long", by_value<BOOST_PYTHON_LONG_LONG>::rewrap);
def("rewrap_value_unsigned_long_long", by_value<unsigned BOOST_PYTHON_LONG_LONG>::rewrap);
# endif
def("rewrap_value_float", by_value<float>::rewrap);
def("rewrap_value_double", by_value<double>::rewrap);
def("rewrap_value_long_double", by_value<long double>::rewrap);
def("rewrap_value_complex_float", by_value<std::complex<float> >::rewrap);
def("rewrap_value_complex_double", by_value<std::complex<double> >::rewrap);
def("rewrap_value_complex_long_double", by_value<std::complex<long double> >::rewrap);
def("rewrap_value_wstring",
# if defined(BOOST_NO_STD_WSTRING) || !defined(Py_USING_UNICODE)
identity_
# else
by_value<std::wstring>::rewrap
# endif
);
def("rewrap_value_string",
# if defined(BOOST_NO_STD_WSTRING) || !defined(Py_USING_UNICODE)
identity_
# else
by_value<std::wstring>::rewrap
# endif
);
def("rewrap_value_string", by_value<std::string>::rewrap);
def("rewrap_value_cstring", by_value<char const*>::rewrap);
def("rewrap_value_handle", by_value<handle<> >::rewrap);
def("rewrap_value_object", by_value<object>::rewrap);
// Expose this to illustrate our failings ;-). See test_builtin_converters.py
def("rewrap_value_mutable_cstring", rewrap_value_mutable_cstring);
def("rewrap_const_reference_bool", by_const_reference<bool>::rewrap);
def("rewrap_const_reference_char", by_const_reference<char>::rewrap);
def("rewrap_const_reference_signed_char", by_const_reference<signed char>::rewrap);
def("rewrap_const_reference_unsigned_char", by_const_reference<unsigned char>::rewrap);
def("rewrap_const_reference_int", by_const_reference<int>::rewrap);
def("rewrap_const_reference_unsigned_int", by_const_reference<unsigned int>::rewrap);
def("rewrap_const_reference_short", by_const_reference<short>::rewrap);
def("rewrap_const_reference_unsigned_short", by_const_reference<unsigned short>::rewrap);
def("rewrap_const_reference_long", by_const_reference<long>::rewrap);
def("rewrap_const_reference_unsigned_long", by_const_reference<unsigned long>::rewrap);
// using Python's macro instead of Boost's - we don't seem to get the
// config right all the time.
# ifdef HAVE_LONG_LONG
def("rewrap_const_reference_long_long", by_const_reference<BOOST_PYTHON_LONG_LONG>::rewrap);
def("rewrap_const_reference_unsigned_long_long", by_const_reference<unsigned BOOST_PYTHON_LONG_LONG>::rewrap);
# endif
def("rewrap_const_reference_float", by_const_reference<float>::rewrap);
def("rewrap_const_reference_double", by_const_reference<double>::rewrap);
def("rewrap_const_reference_long_double", by_const_reference<long double>::rewrap);
def("rewrap_const_reference_complex_float", by_const_reference<std::complex<float> >::rewrap);
def("rewrap_const_reference_complex_double", by_const_reference<std::complex<double> >::rewrap);
def("rewrap_const_reference_complex_long_double", by_const_reference<std::complex<long double> >::rewrap);
def("rewrap_const_reference_string", by_const_reference<std::string>::rewrap);
def("rewrap_const_reference_cstring", by_const_reference<char const*>::rewrap);
def("rewrap_const_reference_handle", by_const_reference<handle<> >::rewrap);
def("rewrap_const_reference_object", by_const_reference<object>::rewrap);
def("rewrap_reference_object", by_reference<object>::rewrap);
}

View File

@@ -0,0 +1,150 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/ref.hpp>
#include <boost/python/ptr.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/call.hpp>
#include <boost/python/object.hpp>
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>
using namespace boost::python;
BOOST_STATIC_ASSERT(converter::is_object_manager<handle<> >::value);
int apply_int_int(PyObject* f, int x)
{
return call<int>(f, x);
}
void apply_void_int(PyObject* f, int x)
{
call<void>(f, x);
}
struct X
{
explicit X(int x) : x(x), magic(7654321) { ++counter; }
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
int value() const { BOOST_ASSERT(magic == 7654321); return x; }
static int count() { return counter; }
private:
void operator=(X const&);
private:
int x;
long magic;
static int counter;
};
X apply_X_X(PyObject* f, X x)
{
return call<X>(f, x);
}
void apply_void_X_ref(PyObject* f, X& x)
{
call<void>(f, boost::ref(x));
}
X& apply_X_ref_handle(PyObject* f, handle<> obj)
{
return call<X&>(f, obj);
}
X* apply_X_ptr_handle_cref(PyObject* f, handle<> const& obj)
{
return call<X*>(f, obj);
}
void apply_void_X_cref(PyObject* f, X const& x)
{
call<void>(f, boost::cref(x));
}
void apply_void_X_ptr(PyObject* f, X* x)
{
call<void>(f, ptr(x));
}
void apply_void_X_deep_ptr(PyObject* f, X* x)
{
call<void>(f, x);
}
char const* apply_cstring_cstring(PyObject* f, char const* s)
{
return call<char const*>(f, s);
}
char const* apply_cstring_pyobject(PyObject* f, PyObject* s)
{
return call<char const*>(f, borrowed(s));
}
char apply_char_char(PyObject* f, char c)
{
return call<char>(f, c);
}
char const* apply_to_string_literal(PyObject* f)
{
return call<char const*>(f, "hello, world");
}
handle<> apply_to_own_type(handle<> x)
{
// Tests that we can return handle<> from a callback and that we
// can pass arbitrary handle<T>.
return call<handle<> >(x.get(), type_handle(borrowed(x->ob_type)));
}
object apply_object_object(PyObject* f, object x)
{
return call<object>(f, x);
}
int X::counter;
BOOST_PYTHON_MODULE(callbacks_ext)
{
def("apply_object_object", apply_object_object);
def("apply_to_own_type", apply_to_own_type);
def("apply_int_int", apply_int_int);
def("apply_void_int", apply_void_int);
def("apply_X_X", apply_X_X);
def("apply_void_X_ref", apply_void_X_ref);
def("apply_void_X_cref", apply_void_X_cref);
def("apply_void_X_ptr", apply_void_X_ptr);
def("apply_void_X_deep_ptr", apply_void_X_deep_ptr);
def("apply_X_ptr_handle_cref", apply_X_ptr_handle_cref
, return_value_policy<reference_existing_object>());
def("apply_X_ref_handle", apply_X_ref_handle
, return_value_policy<reference_existing_object>());
def("apply_cstring_cstring", apply_cstring_cstring);
def("apply_cstring_pyobject", apply_cstring_pyobject);
def("apply_char_char", apply_char_char);
def("apply_to_string_literal", apply_to_string_literal);
class_<X>("X", init<int>())
.def(init<X const&>())
.def("value", &X::value)
.def("set", &X::set)
;
def("x_count", &X::count);
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,147 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from callbacks_ext import *
>>> def double(x):
... return x + x
...
>>> apply_int_int(double, 42)
84
>>> apply_void_int(double, 42)
>>> def identity(x):
... return x
Once we have array conversion support, this test will fail. Er,
succeed<wink>:
>>> try: apply_to_string_literal(identity)
... except ReferenceError: pass # expected
... else: print('expected an exception!')
>>> try: apply_X_ref_handle(lambda ignored:X(42), None)
... except ReferenceError: pass # expected
... else: print('expected an exception!')
>>> x = X(42)
>>> x.y = X(7)
>>> apply_X_ref_handle(lambda z:z.y, x).value()
7
>>> x = apply_X_X(identity, X(42))
>>> x.value()
42
>>> x_count()
1
>>> del x
>>> x_count()
0
>>> def increment(x):
... x.set(x.value() + 1)
...
>>> x = X(42)
>>> apply_void_X_ref(increment, x)
>>> x.value()
43
>>> apply_void_X_cref(increment, x)
>>> x.value() # const-ness is not respected, sorry!
44
>>> last_x = 1
>>> def decrement(x):
... global last_x
... last_x = x
... if x is not None:
... x.set(x.value() - 1)
>>> apply_void_X_ptr(decrement, x)
>>> x.value()
43
>>> last_x.value()
43
>>> increment(last_x)
>>> x.value()
44
>>> last_x.value()
44
>>> apply_void_X_ptr(decrement, None)
>>> assert last_x is None
>>> x.value()
44
>>> last_x = 1
>>> apply_void_X_deep_ptr(decrement, None)
>>> assert last_x is None
>>> x.value()
44
>>> apply_void_X_deep_ptr(decrement, x)
>>> x.value()
44
>>> last_x.value()
43
>>> y = apply_X_ref_handle(identity, x)
>>> assert y.value() == x.value()
>>> increment(x)
>>> assert y.value() == x.value()
>>> y = apply_X_ptr_handle_cref(identity, x)
>>> assert y.value() == x.value()
>>> increment(x)
>>> assert y.value() == x.value()
>>> y = apply_X_ptr_handle_cref(identity, None)
>>> y
>>> def new_x(ignored):
... return X(666)
...
>>> try: apply_X_ref_handle(new_x, 1)
... except ReferenceError: pass
... else: print('no error')
>>> try: apply_X_ptr_handle_cref(new_x, 1)
... except ReferenceError: pass
... else: print('no error')
>>> try: apply_cstring_cstring(identity, 'hello')
... except ReferenceError: pass
... else: print('no error')
>>> apply_char_char(identity, 'x')
'x'
>>> apply_cstring_pyobject(identity, 'hello')
'hello'
>>> apply_cstring_pyobject(identity, None)
>>> apply_char_char(identity, 'x')
'x'
>>> assert apply_to_own_type(identity) is type(identity)
>>> assert apply_object_object(identity, identity) is identity
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,158 @@
//
// adapted from bind_stdcall_test.cpp - test for bind.hpp + __stdcall (free functions)
// The purpose of this simple test is to determine if a function can be
// called from Python with the various existing calling conventions
//
// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#if !defined(TEST_INCLUDE_RECURSION)
#define TEST_INCLUDE_RECURSION
//------------------------------------------------------------------------------
// this section is the main body of the test extension module
#define BOOST_PYTHON_ENABLE_CDECL
#define BOOST_PYTHON_ENABLE_STDCALL
#define BOOST_PYTHON_ENABLE_FASTCALL
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/python.hpp>
using namespace boost::python;
// first define test functions for every calling convention
#define TEST_DECLARE_FUNCTIONS
#define TESTED_CALLING_CONVENTION __cdecl
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __stdcall
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __fastcall
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#undef TEST_DECLARE_FUNCTIONS
// then create a module wrapping the defined functions for every calling convention
BOOST_PYTHON_MODULE( calling_conventions_ext )
{
#define TEST_WRAP_FUNCTIONS
#define TESTED_CALLING_CONVENTION __cdecl
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __stdcall
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __fastcall
#include "calling_conventions.cpp"
#undef TESTED_CALLING_CONVENTION
#undef TEST_WRAP_FUNCTIONS
}
#else // !defined(TEST_INCLUDE_RECURSION)
//------------------------------------------------------------------------------
// this section defines the functions to be wrapped
# if defined(TEST_DECLARE_FUNCTIONS)
# if !defined(TESTED_CALLING_CONVENTION)
# error "One calling convention must be defined"
# endif // !defined(TESTED_CALLING_CONVENTION)
namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION) {
long TESTED_CALLING_CONVENTION f_0()
{
return 17041L;
}
long TESTED_CALLING_CONVENTION f_1(long a)
{
return a;
}
long TESTED_CALLING_CONVENTION f_2(long a, long b)
{
return a + 10 * b;
}
long TESTED_CALLING_CONVENTION f_3(long a, long b, long c)
{
return a + 10 * b + 100 * c;
}
long TESTED_CALLING_CONVENTION f_4(long a, long b, long c, long d)
{
return a + 10 * b + 100 * c + 1000 * d;
}
long TESTED_CALLING_CONVENTION f_5(long a, long b, long c, long d, long e)
{
return a + 10 * b + 100 * c + 1000 * d + 10000 * e;
}
long TESTED_CALLING_CONVENTION f_6(long a, long b, long c, long d, long e, long f)
{
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f;
}
long TESTED_CALLING_CONVENTION f_7(long a, long b, long c, long d, long e, long f, long g)
{
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g;
}
long TESTED_CALLING_CONVENTION f_8(long a, long b, long c, long d, long e, long f, long g, long h)
{
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h;
}
long TESTED_CALLING_CONVENTION f_9(long a, long b, long c, long d, long e, long f, long g, long h, long i)
{
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h + 100000000 * i;
}
} // namespace test##TESTED_CALLING_CONVENTION
# endif // defined(TEST_DECLARE_FUNCTIONS)
//------------------------------------------------------------------------------
// this section wraps the functions
# if defined(TEST_WRAP_FUNCTIONS)
# if !defined(TESTED_CALLING_CONVENTION)
# error "One calling convention must be defined"
# endif // !defined(TESTED_CALLING_CONVENTION)
def("f_0" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_0);
def("f_1" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_1);
def("f_2" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_2);
def("f_3" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_3);
def("f_4" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_4);
def("f_5" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_5);
def("f_6" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_6);
def("f_7" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_7);
def("f_8" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_8);
def("f_9" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_9);
# endif // defined(TEST_WRAP_FUNCTIONS)
#endif // !defined(TEST_INCLUDE_RECURSION)

View File

@@ -0,0 +1,81 @@
# Copyright Nicolas Lelong, 2010. Distributed under the Boost
# Software License, Version 1.0 (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
"""
>>> from calling_conventions_ext import *
>>> f_0__cdecl()
17041
>>> f_1__cdecl(1)
1
>>> f_2__cdecl(1, 2)
21
>>> f_3__cdecl(1, 2, 3)
321
>>> f_4__cdecl(1, 2, 3, 4)
4321
>>> f_5__cdecl(1, 2, 3, 4, 5)
54321
>>> f_6__cdecl(1, 2, 3, 4, 5, 6)
654321
>>> f_7__cdecl(1, 2, 3, 4, 5, 6, 7)
7654321
>>> f_8__cdecl(1, 2, 3, 4, 5, 6, 7, 8)
87654321
>>> f_9__cdecl(1, 2, 3, 4, 5, 6, 7, 8, 9)
987654321
>>> f_0__stdcall()
17041
>>> f_1__stdcall(1)
1
>>> f_2__stdcall(1, 2)
21
>>> f_3__stdcall(1, 2, 3)
321
>>> f_4__stdcall(1, 2, 3, 4)
4321
>>> f_5__stdcall(1, 2, 3, 4, 5)
54321
>>> f_6__stdcall(1, 2, 3, 4, 5, 6)
654321
>>> f_7__stdcall(1, 2, 3, 4, 5, 6, 7)
7654321
>>> f_8__stdcall(1, 2, 3, 4, 5, 6, 7, 8)
87654321
>>> f_9__stdcall(1, 2, 3, 4, 5, 6, 7, 8, 9)
987654321
>>> f_0__fastcall()
17041
>>> f_1__fastcall(1)
1
>>> f_2__fastcall(1, 2)
21
>>> f_3__fastcall(1, 2, 3)
321
>>> f_4__fastcall(1, 2, 3, 4)
4321
>>> f_5__fastcall(1, 2, 3, 4, 5)
54321
>>> f_6__fastcall(1, 2, 3, 4, 5, 6)
654321
>>> f_7__fastcall(1, 2, 3, 4, 5, 6, 7)
7654321
>>> f_8__fastcall(1, 2, 3, 4, 5, 6, 7, 8)
87654321
>>> f_9__fastcall(1, 2, 3, 4, 5, 6, 7, 8, 9)
987654321
"""
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,159 @@
//
// adapted from bind_stdcall_mf_test.cpp - test for bind.hpp + __stdcall (free functions)
// The purpose of this simple test is to determine if a function can be
// called from Python with the various existing calling conventions
//
// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#if !defined(TEST_INCLUDE_RECURSION)
#define TEST_INCLUDE_RECURSION
//------------------------------------------------------------------------------
// this section is the main body of the test extension module
#define BOOST_PYTHON_ENABLE_CDECL
#define BOOST_PYTHON_ENABLE_STDCALL
#define BOOST_PYTHON_ENABLE_FASTCALL
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/python.hpp>
using namespace boost::python;
// first define test functions for every calling convention
#define TEST_DECLARE_FUNCTIONS
#define TESTED_CALLING_CONVENTION __cdecl
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __stdcall
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __fastcall
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#undef TEST_DECLARE_FUNCTIONS
// then create a module wrapping the defined functions for every calling convention
BOOST_PYTHON_MODULE( calling_conventions_mf_ext )
{
#define TEST_WRAP_FUNCTIONS
#define TESTED_CALLING_CONVENTION __cdecl
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __stdcall
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#define TESTED_CALLING_CONVENTION __fastcall
#include "calling_conventions_mf.cpp"
#undef TESTED_CALLING_CONVENTION
#undef TEST_WRAP_FUNCTIONS
}
#else // !defined(TEST_INCLUDE_RECURSION)
//------------------------------------------------------------------------------
// this section defines the functions to be wrapped
# if defined(TEST_DECLARE_FUNCTIONS)
# if !defined(TESTED_CALLING_CONVENTION)
# error "One calling convention must be defined"
# endif // !defined(TESTED_CALLING_CONVENTION)
namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION) {
struct X
{
mutable unsigned int hash;
X(): hash(0) {}
void TESTED_CALLING_CONVENTION f0() { f1(17); }
void TESTED_CALLING_CONVENTION g0() const { g1(17); }
void TESTED_CALLING_CONVENTION f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
void TESTED_CALLING_CONVENTION g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
void TESTED_CALLING_CONVENTION f2(int a1, int a2) { f1(a1); f1(a2); }
void TESTED_CALLING_CONVENTION g2(int a1, int a2) const { g1(a1); g1(a2); }
void TESTED_CALLING_CONVENTION f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); }
void TESTED_CALLING_CONVENTION g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); }
void TESTED_CALLING_CONVENTION f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); }
void TESTED_CALLING_CONVENTION g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); }
void TESTED_CALLING_CONVENTION f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); }
void TESTED_CALLING_CONVENTION g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); }
void TESTED_CALLING_CONVENTION f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); }
void TESTED_CALLING_CONVENTION g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); }
void TESTED_CALLING_CONVENTION f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); }
void TESTED_CALLING_CONVENTION g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); }
void TESTED_CALLING_CONVENTION f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); }
void TESTED_CALLING_CONVENTION g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); }
};
} // namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)
# endif // defined(TEST_DECLARE_FUNCTIONS)
//------------------------------------------------------------------------------
// this section wraps the functions
# if defined(TEST_WRAP_FUNCTIONS)
# if !defined(TESTED_CALLING_CONVENTION)
# error "One calling convention must be defined"
# endif // !defined(TESTED_CALLING_CONVENTION)
{
typedef BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::X X;
class_<X>("X" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION))
.def("f0", &X::f0)
.def("g0", &X::g0)
.def("f1", &X::f1)
.def("g1", &X::g1)
.def("f2", &X::f2)
.def("g2", &X::g2)
.def("f3", &X::f3)
.def("g3", &X::g3)
.def("f4", &X::f4)
.def("g4", &X::g4)
.def("f5", &X::f5)
.def("g5", &X::g5)
.def("f6", &X::f6)
.def("g6", &X::g6)
.def("f7", &X::f7)
.def("g7", &X::g7)
.def("f8", &X::f8)
.def("g8", &X::g8)
.def_readonly("hash", &X::hash)
;
}
# endif // defined(TEST_WRAP_FUNCTIONS)
#endif // !defined(TEST_INCLUDE_RECURSION)

View File

@@ -0,0 +1,84 @@
# Copyright Nicolas Lelong, 2010. Distributed under the Boost
# Software License, Version 1.0 (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
"""
>>> from calling_conventions_mf_ext import *
>>> x = X__cdecl()
>>> x.f0()
>>> x.g0()
>>> x.f1(1)
>>> x.g1(1)
>>> x.f2(1, 2)
>>> x.g2(1, 2)
>>> x.f3(1, 2, 3)
>>> x.g3(1, 2, 3)
>>> x.f4(1, 2, 3, 4)
>>> x.g4(1, 2, 3, 4)
>>> x.f5(1, 2, 3, 4, 5)
>>> x.g5(1, 2, 3, 4, 5)
>>> x.f6(1, 2, 3, 4, 5, 6)
>>> x.g6(1, 2, 3, 4, 5, 6)
>>> x.f7(1, 2, 3, 4, 5, 6, 7)
>>> x.g7(1, 2, 3, 4, 5, 6, 7)
>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.hash
2155
>>> x = X__stdcall()
>>> x.f0()
>>> x.g0()
>>> x.f1(1)
>>> x.g1(1)
>>> x.f2(1, 2)
>>> x.g2(1, 2)
>>> x.f3(1, 2, 3)
>>> x.g3(1, 2, 3)
>>> x.f4(1, 2, 3, 4)
>>> x.g4(1, 2, 3, 4)
>>> x.f5(1, 2, 3, 4, 5)
>>> x.g5(1, 2, 3, 4, 5)
>>> x.f6(1, 2, 3, 4, 5, 6)
>>> x.g6(1, 2, 3, 4, 5, 6)
>>> x.f7(1, 2, 3, 4, 5, 6, 7)
>>> x.g7(1, 2, 3, 4, 5, 6, 7)
>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.hash
2155
>>> x = X__fastcall()
>>> x.f0()
>>> x.g0()
>>> x.f1(1)
>>> x.g1(1)
>>> x.f2(1, 2)
>>> x.g2(1, 2)
>>> x.f3(1, 2, 3)
>>> x.g3(1, 2, 3)
>>> x.f4(1, 2, 3, 4)
>>> x.g4(1, 2, 3, 4)
>>> x.f5(1, 2, 3, 4, 5)
>>> x.g5(1, 2, 3, 4, 5)
>>> x.f6(1, 2, 3, 4, 5, 6)
>>> x.g6(1, 2, 3, 4, 5, 6)
>>> x.f7(1, 2, 3, 4, 5, 6, 7)
>>> x.g7(1, 2, 3, 4, 5, 6, 7)
>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8)
>>> x.hash
2155
"""
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,28 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/object.hpp>
#include <boost/python/class.hpp>
using namespace boost::python;
struct X
{
int x;
X(int n) : x(n) { }
};
int x_function(X& x)
{ return x.x;
}
BOOST_PYTHON_MODULE(class_ext)
{
class_<X>("X", init<int>());
def("x_function", x_function);
}
#include "module_tail.cpp"

40
libs/python/test/class.py Normal file
View File

@@ -0,0 +1,40 @@
# Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from class_ext import *
Ensure sanity:
>>> x = X(42)
>>> x_function(x)
42
Demonstrate extraction in the presence of metaclass changes:
>>> class MetaX(X.__class__):
... def __new__(cls, *args):
... return super(MetaX, cls).__new__(cls, *args)
>>> class XPlusMetatype(X):
... __metaclass__ = MetaX
>>> x = XPlusMetatype(42)
>>> x_function(x)
42
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,74 @@
// Copyright David Abrahams 2005. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/utility.hpp>
/* Non-modifiable definitions */
class basic {
public:
basic() { name = "cltree.basic"; }
std::string repr() { return name+"()"; }
protected:
std::string name;
};
class constant: public basic {
public:
constant() { name = "cltree.constant"; }
};
class symbol: public basic {
public:
symbol() { name = "cltree.symbol"; }
};
class variable: public basic {
public:
variable() { name = "cltree.variable"; }
};
/* EOF: Non-modifiable definitions */
class symbol_wrapper: public symbol {
public:
symbol_wrapper(PyObject* /*self*/): symbol() {
name = "cltree.wrapped_symbol";
}
};
class variable_wrapper: public variable {
public:
variable_wrapper(PyObject* /*self*/): variable() {
name = "cltree.wrapped_variable";
}
// This constructor is introduced only because cannot use
// boost::noncopyable, see below.
variable_wrapper(PyObject* /*self*/,variable v): variable(v) {}
};
BOOST_PYTHON_MODULE(cltree)
{
boost::python::class_<basic>("basic")
.def("__repr__",&basic::repr)
;
boost::python::class_<constant, boost::python::bases<basic>, boost::noncopyable>("constant")
;
boost::python::class_<symbol, symbol_wrapper, boost::noncopyable>("symbol")
;
boost::python::class_<variable, boost::python::bases<basic>, variable_wrapper>("variable")
;
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,38 @@
// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef COMPLICATED_DWA20011215_HPP
# define COMPLICATED_DWA20011215_HPP
# include <iostream>
# include "simple_type.hpp"
struct complicated
{
complicated(simple const&, int = 0);
~complicated();
int get_n() const;
char* s;
int n;
};
inline complicated::complicated(simple const&s, int _n)
: s(s.s), n(_n)
{
std::cout << "constructing complicated: " << this->s << ", " << _n << std::endl;
}
inline complicated::~complicated()
{
std::cout << "destroying complicated: " << this->s << ", " << n << std::endl;
}
inline int complicated::get_n() const
{
return n;
}
#endif // COMPLICATED_DWA20011215_HPP

View File

@@ -0,0 +1,28 @@
/* Copyright 2004 Jonathan Brandmeyer
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
* The purpose of this test is to determine if a function can be called from
* Python with a const value type as an argument, and whether or not the
* presence of a prototype without the cv-qualifier will work around the
* compiler's bug.
*/
#include <boost/python.hpp>
using namespace boost::python;
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
bool accept_const_arg( object );
#endif
bool accept_const_arg( const object )
{
return true;
}
BOOST_PYTHON_MODULE( const_argument_ext )
{
def( "accept_const_arg", accept_const_arg );
}

View File

@@ -0,0 +1,23 @@
# Copyright Jonathan Brandmeyer, 2004. Distributed under the Boost
# Software License, Version 1.0 (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
"""
>>> from const_argument_ext import *
>>> accept_const_arg(1)
1
"""
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,23 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
#include <boost/static_assert.hpp>
#include <memory>
#include <string>
struct foo
{
operator std::auto_ptr<int>&() const;
};
int main()
{
using namespace boost::python::detail;
BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<int>::value);
BOOST_STATIC_ASSERT(copy_ctor_mutates_rhs<std::auto_ptr<int> >::value);
BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<std::string>::value);
BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<foo>::value);
return 0;
}

View File

@@ -0,0 +1,19 @@
# Copyright (C) 2003 Rational Discovery LLC. Distributed under the Boost
# Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
# at http://www.boost.org/LICENSE_1_0.txt)
print("running...")
import crossmod_exception_a
import crossmod_exception_b
try:
crossmod_exception_b.tossit()
except IndexError:
pass
try:
crossmod_exception_a.tossit()
except IndexError:
pass
print("Done.")

View File

@@ -0,0 +1,18 @@
// Copyright (C) 2003 Rational Discovery LLC
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python.hpp>
namespace python = boost::python;
void tossit(){
PyErr_SetString(PyExc_IndexError,"a-blah!");
throw python::error_already_set();
}
BOOST_PYTHON_MODULE(crossmod_exception_a)
{
python::def("tossit",tossit);
}

View File

@@ -0,0 +1,18 @@
// Copyright (C) 2003 Rational Discovery LLC
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python.hpp>
namespace python = boost::python;
void tossit(){
PyErr_SetString(PyExc_IndexError,"b-blah!");
throw python::error_already_set();
}
BOOST_PYTHON_MODULE(crossmod_exception_b)
{
python::def("tossit",tossit);
}

View File

@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Copyright Gottfried Ganßauge 2006.
# Distributed under the Boost Software License, Version 1.0. (See
# accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if __name__ == '__main__':
print("running...")
import crossmod_opaque_a
import crossmod_opaque_b
crossmod_opaque_a.get()
crossmod_opaque_b.get()
print("Done.")

View File

@@ -0,0 +1,26 @@
// Copyright Gottfried Ganßauge 2006.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
# include <boost/python/return_opaque_pointer.hpp>
# include <boost/python/def.hpp>
# include <boost/python/module.hpp>
# include <boost/python/return_value_policy.hpp>
typedef struct opaque_ *opaque;
opaque the_op = ((opaque) 0x47110815);
opaque get() { return the_op; }
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_)
namespace bpl = boost::python;
BOOST_PYTHON_MODULE(crossmod_opaque_a)
{
bpl::def (
"get",
&::get,
bpl::return_value_policy<bpl::return_opaque_pointer>());
}

View File

@@ -0,0 +1,26 @@
// Copyright Gottfried Ganßauge 2006.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
# include <boost/python/return_opaque_pointer.hpp>
# include <boost/python/def.hpp>
# include <boost/python/module.hpp>
# include <boost/python/return_value_policy.hpp>
typedef struct opaque_ *opaque;
opaque the_op = ((opaque) 0x47110815);
opaque get() { return the_op; }
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_)
namespace bpl = boost::python;
BOOST_PYTHON_MODULE(crossmod_opaque_b)
{
bpl::def (
"get",
&::get,
bpl::return_value_policy<bpl::return_opaque_pointer>());
}

View File

@@ -0,0 +1,132 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/return_by_value.hpp>
#include "test_class.hpp"
#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
# include <iostream> // works around a KCC intermediate code generation bug
#endif
using namespace boost::python;
typedef test_class<> X;
struct Y : test_class<1>
{
Y(int v) : test_class<1>(v) {}
Y& operator=(Y const& rhs) { x = rhs.x; return *this; }
bool q;
};
double get_fair_value(X const& x) { return x.value(); }
struct VarBase
{
VarBase(std::string name_) : name(name_) {}
std::string const name;
std::string get_name1() const { return name; }
};
struct Var : VarBase
{
Var(std::string name_) : VarBase(name_), value(), name2(name.c_str()), y(6) {}
std::string const& get_name2() const { return name; }
float value;
char const* name2;
Y y;
static int static1;
static Y static2;
};
int Var::static1 = 0;
Y Var::static2(0);
// Compilability regression tests
namespace boost_python_test
{
struct trivial
{
trivial() : value(123) {}
double value;
};
struct Color3
{
static const Color3 black;
};
const Color3 Color3::black
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
= {}
#endif
;
void compilability_test()
{
class_<trivial>("trivial")
.add_property("property", make_getter(&trivial::value, return_value_policy<return_by_value>()))
.def_readonly("readonly", &trivial::value)
;
class_< Color3 >("Color3", init< const Color3 & >())
.def_readonly("BLACK", &Color3::black) // line 17
;
}
}
BOOST_PYTHON_MODULE(data_members_ext)
{
using namespace boost_python_test;
class_<X>("X", init<int>())
.def("value", &X::value)
.def("set", &X::set)
.def_readonly("x", &X::x)
.add_property("fair_value", get_fair_value)
;
class_<Y>("Y", init<int>())
.def("value", &Y::value)
.def("set", &Y::set)
.def_readwrite("x", &Y::x)
.def_readwrite("q", &Y::q)
;
class_<Var>("Var", init<std::string>())
.def_readonly("name", &Var::name)
.def_readonly("name2", &Var::name2)
.def_readwrite("value", &Var::value)
.def_readonly("y", &Var::y)
// Test return_by_value for plain values and for
// pointers... return_by_value was implemented as a
// side-effect of implementing data member support, so it made
// sense to add the test here.
.def("get_name1", &Var::get_name1, return_value_policy<return_by_value>())
.def("get_name2", &Var::get_name2, return_value_policy<return_by_value>())
.add_property("name3", &Var::get_name1)
// Test static data members
.def_readonly("ro1a", &Var::static1)
.def_readonly("ro1b", Var::static1)
.def_readwrite("rw1a", &Var::static1)
.def_readwrite("rw1b", Var::static1)
.def_readonly("ro2a", &Var::static2)
.def_readonly("ro2b", Var::static2)
.def_readwrite("rw2a", &Var::static2)
.def_readwrite("rw2b", Var::static2)
;
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,215 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from data_members_ext import *
---- Test static data members ---
>>> v = Var('slim shady')
>>> Var.ro2a.x
0
>>> Var.ro2b.x
0
>>> Var.rw2a.x
0
>>> Var.rw2b.x
0
>>> v.ro2a.x
0
>>> v.ro2b.x
0
>>> v.rw2a.x
0
>>> v.rw2b.x
0
>>> Var.rw2a.x = 777
>>> Var.ro2a.x
777
>>> Var.ro2b.x
777
>>> Var.rw2a.x
777
>>> Var.rw2b.x
777
>>> v.ro2a.x
777
>>> v.ro2b.x
777
>>> v.rw2a.x
777
>>> v.rw2b.x
777
>>> Var.rw2b = Y(888)
>>> y = Y(99)
>>> y.q = True
>>> y.q
True
>>> y.q = False
>>> y.q
False
>>> Var.ro2a.x
888
>>> Var.ro2b.x
888
>>> Var.rw2a.x
888
>>> Var.rw2b.x
888
>>> v.ro2a.x
888
>>> v.ro2b.x
888
>>> v.rw2a.x
888
>>> v.rw2b.x
888
>>> v.rw2b.x = 999
>>> Var.ro2a.x
999
>>> Var.ro2b.x
999
>>> Var.rw2a.x
999
>>> Var.rw2b.x
999
>>> v.ro2a.x
999
>>> v.ro2b.x
999
>>> v.rw2a.x
999
>>> v.rw2b.x
999
>>> Var.ro1a
0
>>> Var.ro1b
0
>>> Var.rw1a
0
>>> Var.rw1b
0
>>> v.ro1a
0
>>> v.ro1b
0
>>> v.rw1a
0
>>> v.rw1b
0
>>> Var.rw1a = 777
>>> Var.ro1a
777
>>> Var.ro1b
777
>>> Var.rw1a
777
>>> Var.rw1b
777
>>> v.ro1a
777
>>> v.ro1b
777
>>> v.rw1a
777
>>> v.rw1b
777
>>> Var.rw1b = 888
>>> Var.ro1a
888
>>> Var.ro1b
888
>>> Var.rw1a
888
>>> Var.rw1b
888
>>> v.ro1a
888
>>> v.ro1b
888
>>> v.rw1a
888
>>> v.rw1b
888
>>> v.rw1b = 999
>>> Var.ro1a
999
>>> Var.ro1b
999
>>> Var.rw1a
999
>>> Var.rw1b
999
>>> v.ro1a
999
>>> v.ro1b
999
>>> v.rw1a
999
>>> v.rw1b
999
-----------------
>>> x = X(42)
>>> x.x
42
>>> try: x.x = 77
... except AttributeError: pass
... else: print('no error')
>>> x.fair_value
42.0
>>> y = Y(69)
>>> y.x
69
>>> y.x = 77
>>> y.x
77
>>> v = Var("pi")
>>> v.value = 3.14
>>> v.name
'pi'
>>> v.name2
'pi'
>>> v.get_name1()
'pi'
>>> v.get_name2()
'pi'
>>> v.y.x
6
>>> v.y.x = -7
>>> v.y.x
-7
>>> v.name3
'pi'
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,173 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/def.hpp>
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/list.hpp>
#include <boost/python/overloads.hpp>
#include <boost/python/return_internal_reference.hpp>
#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
# include <iostream> // works around a KCC intermediate code generation bug
#endif
using namespace boost::python;
namespace bpl = boost::python;
char const* const format = "int(%s); char(%s); string(%s); double(%s); ";
///////////////////////////////////////////////////////////////////////////////
//
// Overloaded functions
//
///////////////////////////////////////////////////////////////////////////////
object
bar(int a, char b, std::string c, double d)
{
return format % bpl::make_tuple(a, b, c, d);
}
object
bar(int a, char b, std::string c)
{
return format % bpl::make_tuple(a, b, c, 0.0);
}
object
bar(int a, char b)
{
return format % bpl::make_tuple(a, b, "default", 0.0);
}
object
bar(int a)
{
return format % bpl::make_tuple(a, 'D', "default", 0.0);
}
BOOST_PYTHON_FUNCTION_OVERLOADS(bar_stubs, bar, 1, 4)
///////////////////////////////////////////////////////////////////////////////
//
// Functions with default arguments
//
///////////////////////////////////////////////////////////////////////////////
object
foo(int a, char b = 'D', std::string c = "default", double d = 0.0)
{
return format % bpl::make_tuple(a, b, c, d);
}
BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4)
///////////////////////////////////////////////////////////////////////////////
//
// Overloaded member functions with default arguments
//
///////////////////////////////////////////////////////////////////////////////
struct Y {
Y() {}
object
get_state() const
{
return format % bpl::make_tuple(a, b, c, d);
}
int a; char b; std::string c; double d;
};
struct X {
X() {}
X(int a, char b = 'D', std::string c = "constructor", double d = 0.0)
: state(format % bpl::make_tuple(a, b, c, d))
{}
X(std::string s, bool b)
: state("Got exactly two arguments from constructor: string(%s); bool(%s); " % bpl::make_tuple(s, b*1))
{}
object
bar(int a, char b = 'D', std::string c = "default", double d = 0.0) const
{
return format % bpl::make_tuple(a, b, c, d);
}
Y const&
bar2(int a = 0, char b = 'D', std::string c = "default", double d = 0.0)
{
// tests zero arg member function and return_internal_reference policy
y.a = a;
y.b = b;
y.c = c;
y.d = d;
return y;
}
object
foo(int a, bool b=false) const
{
return "int(%s); bool(%s); " % bpl::make_tuple(a, b*1);
}
object
foo(std::string a, bool b=false) const
{
return "string(%s); bool(%s); " % bpl::make_tuple(a, b*1);
}
object
foo(list a, list b, bool c=false) const
{
return "list(%s); list(%s); bool(%s); " % bpl::make_tuple(a, b, c*1);
}
object
get_state() const
{
return state;
}
Y y;
object state;
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar_stubs, bar, 1, 4)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar_stubs2, bar2, 0, 4)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_2_stubs, foo, 1, 2)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_3_stubs, foo, 2, 3)
///////////////////////////////////////////////////////////////////////////////
BOOST_PYTHON_MODULE(defaults_ext)
{
def("foo", foo, foo_stubs());
def("bar", (object(*)(int, char, std::string, double))0, bar_stubs());
class_<Y>("Y", init<>("doc of Y init")) // this should work
.def("get_state", &Y::get_state)
;
class_<X>("X",no_init)
.def(init<optional<int, char, std::string, double> >("doc of init", args("self", "a", "b", "c", "d")))
.def(init<std::string, bool>(args("self", "s", "b"))[default_call_policies()]) // what's a good policy here?
.def("get_state", &X::get_state)
.def("bar", &X::bar, X_bar_stubs())
.def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()])
.def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs())
.def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs())
.def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs())
;
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,140 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
"""
>>> from defaults_ext import *
>>> bar(1)
'int(1); char(D); string(default); double(0.0); '
>>> bar(2, 'X')
'int(2); char(X); string(default); double(0.0); '
>>> bar(3, 'Y', "Hello World")
'int(3); char(Y); string(Hello World); double(0.0); '
>>> bar(4, 'Z', "Hi There", 3.3)
'int(4); char(Z); string(Hi There); double(3.3); '
>>> foo(1)
'int(1); char(D); string(default); double(0.0); '
>>> foo(2, 'X')
'int(2); char(X); string(default); double(0.0); '
>>> foo(3, 'Y', "Hello World")
'int(3); char(Y); string(Hello World); double(0.0); '
>>> foo(4, 'Z', "Hi There", 3.3)
'int(4); char(Z); string(Hi There); double(3.3); '
>>> x = X()
>>> x.bar(1)
'int(1); char(D); string(default); double(0.0); '
>>> x.bar(2, 'X')
'int(2); char(X); string(default); double(0.0); '
>>> x.bar(3, 'Y', "Hello World")
'int(3); char(Y); string(Hello World); double(0.0); '
>>> x.bar(4, 'Z', "Hi There", 3.3)
'int(4); char(Z); string(Hi There); double(3.3); '
>>> x.foo(5)
'int(5); bool(0); '
>>> x.foo(6, 0)
'int(6); bool(0); '
>>> x.foo(7, 1)
'int(7); bool(1); '
>>> x.foo("A")
'string(A); bool(0); '
>>> x.foo("B", False)
'string(B); bool(0); '
>>> x.foo("C", True)
'string(C); bool(1); '
>>> x.foo([0,1,2], [2,3,4])
'list([0, 1, 2]); list([2, 3, 4]); bool(0); '
>>> x.foo([0,1,2], [2,3,4], False)
'list([0, 1, 2]); list([2, 3, 4]); bool(0); '
>>> x.foo([0,1,2], [2,3,4], True)
'list([0, 1, 2]); list([2, 3, 4]); bool(1); '
>>> x = X(1)
>>> x.get_state()
'int(1); char(D); string(constructor); double(0.0); '
>>> x = X(1, 'X')
>>> x.get_state()
'int(1); char(X); string(constructor); double(0.0); '
>>> x = X(1, 'X', "Yabadabadoo")
>>> x.get_state()
'int(1); char(X); string(Yabadabadoo); double(0.0); '
>>> x = X(1, 'X', "Phoenix", 3.65)
>>> x.get_state()
'int(1); char(X); string(Phoenix); double(3.65); '
>>> x.bar2().get_state()
'int(0); char(D); string(default); double(0.0); '
>>> x.bar2(1).get_state()
'int(1); char(D); string(default); double(0.0); '
>>> x.bar2(1, 'K').get_state()
'int(1); char(K); string(default); double(0.0); '
>>> x.bar2(1, 'K', "Kim").get_state()
'int(1); char(K); string(Kim); double(0.0); '
>>> x.bar2(1, 'K', "Kim", 9.9).get_state()
'int(1); char(K); string(Kim); double(9.9); '
>>> x = X("Phoenix", 1)
>>> x.get_state()
'Got exactly two arguments from constructor: string(Phoenix); bool(1); '
>>> def selected_doc(obj, *args):
... doc = obj.__doc__.splitlines()
... return "\\n".join(["|"+doc[i] for i in args])
>>> print(selected_doc(X.__init__, 1, 2, 4, 7, 9))
|__init__( (object)self [, (int)a [, (str)b [, (str)c [, (float)d]]]]) -> None :
| doc of init
| C++ signature :
|__init__( (object)self, (str)s, (bool)b) -> None :
| C++ signature :
>>> print(selected_doc(Y.__init__, 1, 2, 4))
|__init__( (object)arg1) -> None :
| doc of Y init
| C++ signature :
>>> print(selected_doc(X.bar2, 1, 2, 4))
|bar2( (X)arg1 [, (int)arg2 [, (str)arg3 [, (str)arg4 [, (float)arg5]]]]) -> Y :
| doc of X::bar2
| C++ signature :
"""
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,58 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/detail/destroy.hpp>
#include <boost/detail/lightweight_test.hpp>
int count;
int marks[] = {
-1
, -1, -1
, -1, -1, -1, -1
, -1
};
int* kills = marks;
struct foo
{
foo() : n(count++) {}
~foo()
{
*kills++ = n;
}
int n;
// This used to cause compiler errors with MSVC 9.0.
foo& operator~();
foo& T();
};
void assert_destructions(int n)
{
for (int i = 0; i < n; ++i)
BOOST_TEST(marks[i] == i);
BOOST_TEST(marks[n] == -1);
}
int main()
{
assert_destructions(0);
foo* f1 = new foo;
boost::python::detail::destroy_referent<foo const volatile&>(f1);
assert_destructions(1);
foo* f2 = new foo[2];
typedef foo x[2];
boost::python::detail::destroy_referent<x const&>(f2);
assert_destructions(3);
typedef foo y[2][2];
x* f3 = new y;
boost::python::detail::destroy_referent<y&>(f3);
assert_destructions(7);
return boost::report_errors();
}

91
libs/python/test/dict.cpp Normal file
View File

@@ -0,0 +1,91 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/dict.hpp>
#include <exception>
#include <string>
using namespace boost::python;
object new_dict()
{
return dict();
}
object data_dict()
{
dict tmp1;
tmp1["key1"] = "value1";
dict tmp2;
tmp2["key2"] = "value2";
tmp1[1] = tmp2;
return tmp1;
}
object dict_from_sequence(object sequence)
{
return dict(sequence);
}
object dict_keys(dict data)
{
return data.keys();
}
object dict_values(dict data)
{
return data.values();
}
object dict_items(dict data)
{
return data.items();
}
void work_with_dict(dict data1, dict data2)
{
if (!data1.has_key("k1")) {
throw std::runtime_error("dict does not have key 'k1'");
}
data1.update(data2);
}
void test_templates(object print)
{
std::string key = "key";
dict tmp;
tmp[1] = "a test string";
print(tmp.get(1));
//print(tmp[1]);
tmp[1.5] = 13;
print(tmp.get(1.5));
print(tmp.get(44));
print(tmp);
print(tmp.get(2,"default"));
print(tmp.setdefault(3,"default"));
BOOST_ASSERT(!tmp.has_key(key));
//print(tmp[3]);
}
BOOST_PYTHON_MODULE(dict_ext)
{
def("new_dict", new_dict);
def("data_dict", data_dict);
def("dict_keys", dict_keys);
def("dict_values", dict_values);
def("dict_items", dict_items);
def("dict_from_sequence", dict_from_sequence);
def("work_with_dict", work_with_dict);
def("test_templates", test_templates);
}
#include "module_tail.cpp"

46
libs/python/test/dict.py Normal file
View File

@@ -0,0 +1,46 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
"""
>>> from dict_ext import *
>>> def printer(*args):
... for x in args: print(x, end='')
... print('')
...
>>> print(new_dict())
{}
>>> print(data_dict())
{1: {'key2': 'value2'}, 'key1': 'value1'}
>>> tmp = data_dict()
>>> print(dict_keys(tmp))
[1, 'key1']
>>> print(dict_values(tmp))
[{'key2': 'value2'}, 'value1']
>>> print(dict_items(tmp))
[(1, {'key2': 'value2'}), ('key1', 'value1')]
>>> print(dict_from_sequence([(1,1),(2,2),(3,3)]))
{1: 1, 2: 2, 3: 3}
>>> test_templates(printer) #doctest: +NORMALIZE_WHITESPACE
a test string
13
None
{1.5: 13, 1: 'a test string'}
default
default
"""
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,116 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/operators.hpp>
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/docstring_options.hpp>
#include <boost/python/scope.hpp>
#include <boost/python/manage_new_object.hpp>
#include "test_class.hpp"
// Just use math.h here; trying to use std::pow() causes too much
// trouble for non-conforming compilers and libraries.
#include <math.h>
using namespace boost::python;
typedef test_class<> X;
X* create(int x)
{
return new X(x);
}
unsigned long fact(unsigned long n)
{
return n <= 1 ? n : n * fact(n - 1);
}
BOOST_PYTHON_MODULE(docstring_ext)
{
scope().attr("__doc__") =
"A simple test module for documentation strings\n"
"Exercised by docstring.py"
;
class_<X>("X",
"A simple class wrapper around a C++ int\n"
"includes some error-checking"
, init<int>(
"this is the __init__ function\n"
"its documentation has two lines."
, args("self", "value")
)
)
.def("value", &X::value,
"gets the value of the object"
, args("self"))
.def( "value", &X::value,
"also gets the value of the object"
, args("self"))
;
def("create", create, return_value_policy<manage_new_object>(),
"creates a new X object", args("value"));
def("fact", fact, "compute the factorial", args("n"));
{
docstring_options doc_options;
doc_options.disable_user_defined();
def("fact_usr_off_1", fact, "usr off 1", args("n"));
doc_options.enable_user_defined();
def("fact_usr_on_1", fact, "usr on 1", args("n"));
doc_options.disable_user_defined();
def("fact_usr_off_2", fact, "usr off 2", args("n"));
}
def("fact_usr_on_2", fact, "usr on 2", args("n"));
{
docstring_options doc_options(true, false);
def("fact_sig_off_1", fact, "sig off 1", args("n"));
doc_options.enable_signatures();
def("fact_sig_on_1", fact, "sig on 1", args("n"));
doc_options.disable_signatures();
def("fact_sig_off_2", fact, "sig off 2", args("n"));
}
def("fact_sig_on_2", fact, "sig on 2", args("n"));
{
docstring_options doc_options(false);
def("fact_usr_off_sig_off_1", fact, "usr off sig off 1", args("n"));
{
docstring_options nested_doc_options;
def("fact_usr_on_sig_on_1", fact, "usr on sig on 1", args("n"));
nested_doc_options.disable_all();
nested_doc_options.enable_user_defined();
def("fact_usr_on_sig_off_1", fact, "usr on sig off 1", args("n"));
nested_doc_options.enable_all();
def("fact_usr_on_sig_on_2", fact, "usr on sig on 2", args("n"));
}
def("fact_usr_off_sig_off_2", fact, "usr off sig off 2", args("n"));
}
{
docstring_options doc_options(true);
doc_options.disable_cpp_signatures();
def("fact_usr_on_psig_on_csig_off_1", fact, "usr on psig on csig off 1", args("n"));
doc_options.enable_cpp_signatures();
doc_options.disable_py_signatures();
def("fact_usr_on_psig_off_csig_on_1", fact, "usr on psig off csig on 1", args("n"));
doc_options.enable_py_signatures();
doc_options.disable_user_defined();
doc_options.disable_cpp_signatures();
def("fact_usr_off_psig_on_csig_off_1", fact, "usr off psig on csig off 1", args("n"));
doc_options.enable_cpp_signatures();
doc_options.disable_py_signatures();
def("fact_usr_off_psig_off_csig_on_1", fact, "usr off psig off csig on 1", args("n"));
}
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,153 @@
# Copyright David Abrahams & Ralf W. Grosse-Kunsteve 2004-2006.
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from docstring_ext import *
>>> def selected_doc(obj, *args):
... doc = obj.__doc__.splitlines()
... return "\\n".join(["|"+doc[i] for i in args])
>>> print(selected_doc(X.__init__, 1, 2, 3, 4, 5))
|__init__( (object)self, (int)value) -> None :
| this is the __init__ function
| its documentation has two lines.
|
| C++ signature :
>>> print(selected_doc(X.value, 1, 2, 4, 7, 8, 10))
|value( (X)self) -> int :
| gets the value of the object
| C++ signature :
|value( (X)self) -> int :
| also gets the value of the object
| C++ signature :
>>> print(selected_doc(create, 1, 2, 3, 4))
|create( (int)value) -> X :
| creates a new X object
|
| C++ signature :
>>> print(selected_doc(fact, 1, 2, 3, 4))
|fact( (int)n) -> int :
| compute the factorial
|
| C++ signature :
>>> len(fact_usr_off_1.__doc__.splitlines())
5
>>> print(selected_doc(fact_usr_off_1, 1, 3))
|fact_usr_off_1( (int)n) -> int :
| C++ signature :
>>> len(fact_usr_on_1.__doc__.splitlines())
6
>>> print(selected_doc(fact_usr_on_1, 1, 2, 4))
|fact_usr_on_1( (int)n) -> int :
| usr on 1
| C++ signature :
>>> len(fact_usr_off_2.__doc__.splitlines())
5
>>> print(selected_doc(fact_usr_off_2, 1, 3))
|fact_usr_off_2( (int)n) -> int :
| C++ signature :
>>> len(fact_usr_on_2.__doc__.splitlines())
6
>>> print(selected_doc(fact_usr_on_2, 1, 2, 4))
|fact_usr_on_2( (int)n) -> int :
| usr on 2
| C++ signature :
>>> len(fact_sig_off_1.__doc__.splitlines())
2
>>> print(selected_doc(fact_sig_off_1, 1))
|sig off 1
>>> len(fact_sig_on_1.__doc__.splitlines())
6
>>> print(selected_doc(fact_sig_on_1, 1, 2, 4))
|fact_sig_on_1( (int)n) -> int :
| sig on 1
| C++ signature :
>>> len(fact_sig_off_2.__doc__.splitlines())
2
>>> print(selected_doc(fact_sig_off_2, 1))
|sig off 2
>>> len(fact_sig_on_2.__doc__.splitlines())
6
>>> print(selected_doc(fact_sig_on_2, 1, 2, 4))
|fact_sig_on_2( (int)n) -> int :
| sig on 2
| C++ signature :
>>> print(fact_usr_off_sig_off_1.__doc__)
None
>>> len(fact_usr_on_sig_on_1.__doc__.splitlines())
6
>>> print(selected_doc(fact_usr_on_sig_on_1, 1, 2, 4))
|fact_usr_on_sig_on_1( (int)n) -> int :
| usr on sig on 1
| C++ signature :
>>> len(fact_usr_on_sig_off_1.__doc__.splitlines())
2
>>> print(selected_doc(fact_usr_on_sig_off_1, 1))
|usr on sig off 1
>>> len(fact_usr_on_sig_on_2.__doc__.splitlines())
6
>>> print(selected_doc(fact_usr_on_sig_on_2, 1, 2, 4))
|fact_usr_on_sig_on_2( (int)n) -> int :
| usr on sig on 2
| C++ signature :
>>> print(selected_doc(fact_usr_on_psig_on_csig_off_1, 1, 2))
|fact_usr_on_psig_on_csig_off_1( (int)n) -> int :
| usr on psig on csig off 1
>>> print(selected_doc(fact_usr_on_psig_off_csig_on_1, 1, 3))
|usr on psig off csig on 1
|C++ signature :
>>> print(fact_usr_off_psig_on_csig_off_1.__doc__.splitlines()[1])
fact_usr_off_psig_on_csig_off_1( (int)n) -> int
>>> print(selected_doc(fact_usr_off_psig_off_csig_on_1,1))
|C++ signature :
'''
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
import docstring_ext
result = doctest.testmod(sys.modules.get(__name__))
import pydoc
import re
docmodule = lambda m: re.sub(".\10", "", pydoc.text.docmodule(m))
try:
print('printing module help:')
print(docmodule(docstring_ext))
except object as x:
print('********* failed **********')
print(x)
result = list(result)
result[0] += 1
return tuple(result)
return result
if __name__ == '__main__':
print("running...")
import sys
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,48 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/def.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include "test_class.hpp"
#include <memory>
using namespace boost::python;
using boost::shared_ptr;
class Test;
typedef shared_ptr<Test> TestPtr;
class Test : public boost::enable_shared_from_this<Test> {
public:
static TestPtr construct() {
return TestPtr(new Test);
}
void act() {
TestPtr kungFuDeathGrip(shared_from_this());
}
void take(TestPtr t) {
}
};
BOOST_PYTHON_MODULE(enable_shared_from_this_ext)
{
class_<Test, TestPtr, boost::noncopyable>("Test")
.def("construct", &Test::construct).staticmethod("construct")
.def("act", &Test::act)
.def("take", &Test::take)
;
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,26 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from enable_shared_from_this_ext import *
>>> x = Test.construct()
>>> x.take(x)
>>> x.act()
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,55 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/enum.hpp>
#include <boost/python/def.hpp>
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
#include <boost/python/detail/type_traits.hpp>
# include <boost/mpl/bool.hpp>
#endif
using namespace boost::python;
enum color { red = 1, green = 2, blue = 4, blood = 1 };
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
namespace boost // Pro7 has a hard time detecting enums
{
template <> struct boost::python::detail::is_enum<color> : boost::mpl::true_ {};
}
#endif
color identity_(color x) { return x; }
struct colorized {
colorized() : x(red) {}
color x;
};
BOOST_PYTHON_MODULE(enum_ext)
{
enum_<color>("color")
.value("red", red)
.value("green", green)
.value("blue", blue)
.value("blood", blood)
.export_values()
;
def("identity", identity_);
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
color colorized::*px = &colorized::x;
class_<colorized>("colorized")
.def_readwrite("x", px)
;
#else
class_<colorized>("colorized")
.def_readwrite("x", &colorized::x)
;
#endif
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,28 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/exception_translator.hpp>
struct error {};
void translate(error const& /*e*/)
{
PyErr_SetString(PyExc_RuntimeError, "!!!error!!!");
}
void throw_error()
{
throw error();
}
BOOST_PYTHON_MODULE(exception_translator_ext)
{
using namespace boost::python;
register_exception_translator<error>(&translate);
def("throw_error", throw_error);
}

View File

@@ -0,0 +1,27 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from exception_translator_ext import *
>>> try:
... throw_error();
... except RuntimeError as x:
... print(x)
... else:
... print('Expected a RuntimeError!')
!!!error!!!
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

197
libs/python/test/exec.cpp Normal file
View File

@@ -0,0 +1,197 @@
// Copyright Stefan Seefeld 2005.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <iostream>
namespace python = boost::python;
// An abstract base class
class Base : public boost::noncopyable
{
public:
virtual ~Base() {};
virtual std::string hello() = 0;
};
// C++ derived class
class CppDerived : public Base
{
public:
virtual ~CppDerived() {}
virtual std::string hello() { return "Hello from C++!";}
};
// Familiar Boost.Python wrapper class for Base
struct BaseWrap : Base, python::wrapper<Base>
{
virtual std::string hello()
{
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// workaround for VC++ 6.x or 7.0, see
// http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions
return python::call<std::string>(this->get_override("hello").ptr());
#else
return this->get_override("hello")();
#endif
}
};
// Pack the Base class wrapper into a module
BOOST_PYTHON_MODULE(embedded_hello)
{
python::class_<BaseWrap, boost::noncopyable> base("Base");
}
void eval_test()
{
python::object result = python::eval("'abcdefg'.upper()");
std::string value = python::extract<std::string>(result) BOOST_EXTRACT_WORKAROUND;
BOOST_TEST(value == "ABCDEFG");
}
void exec_test()
{
// Retrieve the main module
python::object main = python::import("__main__");
// Retrieve the main module's namespace
python::object global(main.attr("__dict__"));
// Define the derived class in Python.
python::object result = python::exec(
"from embedded_hello import * \n"
"class PythonDerived(Base): \n"
" def hello(self): \n"
" return 'Hello from Python!' \n",
global, global);
python::object PythonDerived = global["PythonDerived"];
// Creating and using instances of the C++ class is as easy as always.
CppDerived cpp;
BOOST_TEST(cpp.hello() == "Hello from C++!");
// But now creating and using instances of the Python class is almost
// as easy!
python::object py_base = PythonDerived();
Base& py = python::extract<Base&>(py_base) BOOST_EXTRACT_WORKAROUND;
// Make sure the right 'hello' method is called.
BOOST_TEST(py.hello() == "Hello from Python!");
}
void exec_file_test(std::string const &script)
{
// Run a python script in an empty environment.
python::dict global;
python::object result = python::exec_file(script.c_str(), global, global);
// Extract an object the script stored in the global dictionary.
BOOST_TEST(python::extract<int>(global["number"]) == 42);
}
void exec_test_error()
{
// Execute a statement that raises a python exception.
python::dict global;
python::object result = python::exec("print(unknown) \n", global, global);
}
void exercise_embedding_html()
{
using namespace boost::python;
/* code from: libs/python/doc/tutorial/doc/tutorial.qbk
(generates libs/python/doc/tutorial/doc/html/python/embedding.html)
*/
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
object ignored = exec("hello = file('hello.txt', 'w')\n"
"hello.write('Hello world!')\n"
"hello.close()",
main_namespace);
}
void check_pyerr(bool pyerr_expected=false)
{
if (PyErr_Occurred())
{
if (!pyerr_expected) {
BOOST_ERROR("Python Error detected");
PyErr_Print();
}
else {
PyErr_Clear();
}
}
else
{
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception handler registered.");
}
}
int main(int argc, char **argv)
{
BOOST_TEST(argc == 2 || argc == 3);
std::string script = argv[1];
// Register the module with the interpreter
if (PyImport_AppendInittab(const_cast<char*>("embedded_hello"),
#if PY_VERSION_HEX >= 0x03000000
PyInit_embedded_hello
#else
initembedded_hello
#endif
) == -1)
{
BOOST_ERROR("Failed to add embedded_hello to the interpreter's "
"builtin modules");
}
// Initialize the interpreter
Py_Initialize();
if (python::handle_exception(eval_test)) {
check_pyerr();
}
else if(python::handle_exception(exec_test)) {
check_pyerr();
}
else if (python::handle_exception(boost::bind(exec_file_test, script))) {
check_pyerr();
}
if (python::handle_exception(exec_test_error))
{
check_pyerr(/*pyerr_expected*/ true);
}
else
{
BOOST_ERROR("Python exception expected, but not seen.");
}
if (argc > 2) {
// The main purpose is to test compilation. Since this test generates
// a file and I (rwgk) am uncertain about the side-effects, run it only
// if explicitly requested.
exercise_embedding_html();
}
// Boost.Python doesn't support Py_Finalize yet.
// Py_Finalize();
return boost::report_errors();
}
// Including this file makes sure
// that on Windows, any crashes (e.g. null pointer dereferences) invoke
// the debugger immediately, rather than being translated into structured
// exceptions that can interfere with debugging.
#include "module_tail.cpp"

6
libs/python/test/exec.py Normal file
View File

@@ -0,0 +1,6 @@
# Copyright Stefan Seefeld 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
if 1:
number = 42

View File

@@ -0,0 +1,143 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/extract.hpp>
#include <boost/python/list.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/implicit.hpp>
#include <string>
#include <boost/lexical_cast.hpp>
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>
#include "test_class.hpp"
using namespace boost::python;
typedef test_class<> X;
bool extract_bool(object x) { return extract<bool>(x); }
boost::python::list extract_list(object x)
{
extract<list> get_list((x));
// Make sure we always have the right idea about whether it's a list
bool is_list_1 = get_list.check();
bool is_list_2 = PyObject_IsInstance(x.ptr(), (PyObject*)&PyList_Type);
if (is_list_1 != is_list_2) {
throw std::runtime_error("is_list_1 == is_list_2 failure.");
}
return get_list();
}
char const* extract_cstring(object x)
{
return extract<char const*>(x);
}
std::string extract_string(object x)
{
std::string s = extract<std::string>(x);
return s;
}
std::string const& extract_string_cref(object x)
{
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
# pragma warning(push)
# pragma warning(disable:4172) // msvc lies about returning a reference to temporary
#elif defined(_MSC_VER) && defined(__ICL) && __ICL <= 900
# pragma warning(push)
# pragma warning(disable:473) // intel/win32 does too
#endif
return extract<std::string const&>(x);
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 800
# pragma warning(pop)
#endif
}
X extract_X(object x)
{
return extract<X>(x);
}
X* extract_X_ptr(object x) { return extract<X*>(x); }
X& extract_X_ref(object x)
{
extract<X&> get_x(x);
return get_x;
}
int double_X(object n)
{
extract<X> x(n);
return x().value() + x().value();
}
bool check_bool(object x) { return extract<bool>(x).check(); }
bool check_list(object x) { return extract<list>(x).check(); }
bool check_cstring(object x) { return extract<char const*>(x).check(); }
bool check_string(object x) { return extract<std::string>(x).check(); }
bool check_string_cref(object x) { return extract<std::string const&>(x).check(); }
bool check_X(object x) { return extract<X>(x).check(); }
bool check_X_ptr(object x) { return extract<X*>(x).check(); }
bool check_X_ref(object x) { return extract<X&>(x).check(); }
std::string x_rep(X const& x)
{
return "X(" + boost::lexical_cast<std::string>(x.value()) + ")";
}
BOOST_PYTHON_MODULE(extract_ext)
{
implicitly_convertible<int, X>();
def("extract_bool", extract_bool);
def("extract_list", extract_list);
def("extract_cstring", extract_cstring);
def("extract_string", extract_string);
def("extract_string_cref", extract_string_cref, return_value_policy<reference_existing_object>());
def("extract_X", extract_X);
def("extract_X_ptr", extract_X_ptr, return_value_policy<reference_existing_object>());
def("extract_X_ref", extract_X_ref, return_value_policy<reference_existing_object>());
def("check_bool", check_bool);
def("check_list", check_list);
def("check_cstring", check_cstring);
def("check_string", check_string);
def("check_string_cref", check_string_cref);
def("check_X", check_X);
def("check_X_ptr", check_X_ptr);
def("check_X_ref", check_X_ref);
def("double_X", double_X);
def("count_Xs", &X::count);
;
object x_class(
class_<X>("X", init<int>())
.def( "__repr__", x_rep));
// Instantiate an X object through the Python interface
object x_obj = x_class(3);
// Get the C++ object out of the Python object
X const& x = extract<X&>(x_obj);
if (x.value() != 3) {
throw std::runtime_error("x.value() == 3 failure.");
}
}
#include "module_tail.cpp"

107
libs/python/test/extract.py Normal file
View File

@@ -0,0 +1,107 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from extract_ext import *
Just about anything has a truth value in Python
>>> assert check_bool(None)
>>> extract_bool(None)
0
>>> assert check_bool(2)
>>> extract_bool(2)
1
>>> assert not check_bool('')
Check that object manager types work properly. These are a different
case because they wrap Python objects instead of being wrapped by them.
>>> assert not check_list(2)
>>> try: x = extract_list(2)
... except TypeError as x:
... if str(x) != 'Expecting an object of type list; got an object of type int instead':
... print(x)
... else:
... print('expected an exception, got', x, 'instead')
Can't extract a list from a tuple. Use list(x) to convert a sequence
to a list:
>>> assert not check_list((1, 2, 3))
>>> assert check_list([1, 2, 3])
>>> extract_list([1, 2, 3])
[1, 2, 3]
Can get a char const* from a Python string:
>>> assert check_cstring('hello')
>>> extract_cstring('hello')
'hello'
Can't get a char const* from a Python int:
>>> assert not check_cstring(1)
>>> try: x = extract_cstring(1)
... except TypeError: pass
... else:
... print('expected an exception, got', x, 'instead')
Extract an std::string (class) rvalue from a native Python type
>>> assert check_string('hello')
>>> extract_string('hello')
'hello'
Constant references are not treated as rvalues for the purposes of
extract:
>>> assert not check_string_cref('hello')
We can extract lvalues where appropriate:
>>> x = X(42)
>>> check_X(x)
1
>>> extract_X(x)
X(42)
>>> check_X_ptr(x)
1
>>> extract_X_ptr(x)
X(42)
>>> extract_X_ref(x)
X(42)
Demonstrate that double-extraction of an rvalue works, and all created
copies of the object are destroyed:
>>> n = count_Xs()
>>> double_X(333)
666
>>> count_Xs() - n
0
General check for cleanliness:
>>> del x
>>> count_Xs()
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

173
libs/python/test/fabscript Normal file
View File

@@ -0,0 +1,173 @@
# -*- python -*-
#
# Copyright (c) 2016 Stefan Seefeld
# All rights reserved.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
from faber import platform
from faber.feature import set
from faber.tools.compiler import runpath
from faber.tools.python import python, pythonpath
from faber.artefacts.object import object
from faber.artefacts.binary import binary
from faber.artefacts.python import extension
from faber.test import test, report, fail
src = module('..src')
python_libs=python.instance().libs
features |= runpath(src.bpl.path, base='')
def extension_test(name, ext=[], script=None, np=False,
features=features, condition=None):
"""Create a Python extension test `name`.
Arguments:
* name: the name of the test.
* ext: extensions to be compiled, <name> if none are given.
* script: the test script to execute, <name>.py if none is given.
* np: if true, add boost_numpy to sources
* features: pre-defined features
* condition: any condition under which to run the test
Return:
* the test artefact"""
features=features.copy()
extensions = []
libs = [src.bnl, src.bpl] if np else [src.bpl]
for e in ext or [name]:
if type(e) is str: # build from a single source file
n = e if e != name else e + '_ext'
s = [e + '.cpp']
else: # build from a list of source files
n = e[0] if e[0] != name else e[0] + '_ext'
s = [n + '.cpp' for n in e]
e = extension(n, s + libs, features=features)
features |= pythonpath(e.path, base='')
extensions.append(e)
if not script:
script = name+'.py'
return test(name, script, run=python.run, dependencies=extensions,
features=features, condition=condition)
tests = []
for t in [('injected',),
('properties',),
('return_arg',),
('staticmethod',),
('boost_shared_ptr',),
('enable_shared_from_this',),
('andreas_beyer',),
('polymorphism',),
('polymorphism2',),
('wrapper_held_type',),
('minimal',),
('args',),
('raw_ctor',),
('exception_translator',),
('test_enum', ['enum_ext']),
('test_cltree', ['cltree']),
('newtest', ['m1', 'm2']),
('const_argument',),
('keywords_test', ['keywords']),
('test_pointer_adoption',),
('operators',),
('operators_wrapper',),
('callbacks',),
('defaults',),
('object',),
('list',),
('long',),
('dict',),
('tuple',),
('str',),
('slice',),
('virtual_functions',),
('back_reference',),
('implicit',),
('data_members',),
('ben_scott1',),
('bienstman1',),
('bienstman2',),
('bienstman3',),
('multi_arg_constructor',),
('iterator', ['iterator', 'input_iterator']),
('stl_iterator',),
('extract',),
('crossmod_opaque', ['crossmod_opaque_a', 'crossmod_opaque_b']),
('opaque',),
('voidptr',),
('pickle1',),
('pickle2',),
('pickle3',),
('pickle4',),
('nested',),
('docstring',),
('pytype_function',),
('vector_indexing_suite',),
('pointer_vector',),
('builtin_converters', [], 'test_builtin_converters.py'),
('map_indexing_suite',
[['map_indexing_suite', 'int_map_indexing_suite', 'a_map_indexing_suite']])]:
tests.append(extension_test(*t))
tests.append(extension_test('shared_ptr',
condition=set.define.contains('HAS_CXX11')))
tests.append(extension_test('polymorphism2_auto_ptr',
condition=set.define.contains('HAS_CXX11').not_()))
tests.append(extension_test('auto_ptr',
condition=set.define.contains('HAS_CXX11')))
import_ = binary('import_', ['import_.cpp', src.bpl], features=features|python_libs)
if platform.os == 'Windows':
command = """set PATH=$(runpath);%PATH%
$(>[1]) $(>[2])"""
else:
command = 'LD_LIBRARY_PATH=$(runpath) $(>[1]) $(>[2])'
tests.append(test('import', [import_, 'import_.py'],
run=action('run', command),
features=features))
tests.append(extension_test('calling_conventions',
condition=platform.os == 'Windows'))
tests.append(extension_test('calling_conventions_mf',
condition=platform.os == 'Windows'))
for t in ['destroy_test',
'pointer_type_id_test',
'bases',
'pointee',
'if_else',
'pointee',
'result',
'upcast',
'select_from_python_test']:
tests.append(test(t, binary(t, [t + '.cpp', src.bpl], features=features), features=features, run=True))
for t in ['indirect_traits_test',
'string_literal',
'borrowed',
'object_manager',
'copy_ctor_mutates_rhs',
'select_holder',
'select_arg_to_python_test']:
tests.append(test(t, object(t, [t + '.cpp'], features=features)))
for t in ['raw_pyobject_fail1',
'raw_pyobject_fail2',
'as_to_python_function',
'object_fail1']:
tests.append(test(t, object(t, [t + '.cpp'], features=features), expected=fail))
for t in ['numpy/dtype',
'numpy/ufunc',
'numpy/templates',
'numpy/ndarray',
'numpy/indexing',
'numpy/shapes']:
tests.append(extension_test(t, np=True,
condition=set.define.contains('HAS_NUMPY')))
default = report('report', tests, fail_on_failures=True)

View File

@@ -0,0 +1,44 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/static_assert.hpp>
#include <boost/python/detail/if_else.hpp>
#include <boost/python/detail/type_traits.hpp>
typedef char c1;
typedef char c2[2];
typedef char c3[3];
typedef char c4[4];
template <unsigned size>
struct choose
{
typedef typename boost::python::detail::if_<
(sizeof(c1) == size)
>::template then<
c1
>::template elif<
(sizeof(c2) == size)
>::template then<
c2
>::template elif<
(sizeof(c3) == size)
>::template then<
c3
>::template elif<
(sizeof(c4) == size)
>::template then<
c4
>::template else_<void*>::type type;
};
int main()
{
BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose<1>::type,c1>::value));
BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose<2>::type,c2>::value));
BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose<3>::type,c3>::value));
BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose<4>::type,c4>::value));
BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose<5>::type,void*>::value));
return 0;
}

View File

@@ -0,0 +1,48 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/class.hpp>
#include <boost/python/implicit.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include "test_class.hpp"
using namespace boost::python;
typedef test_class<> X;
int x_value(X const& x)
{
return x.value();
}
X make_x(int n) { return X(n); }
// foo/bar -- a regression for a vc7 bug workaround
struct bar {};
struct foo
{
virtual ~foo() {}; // silence compiler warnings
virtual void f() = 0;
operator bar() const { return bar(); }
};
BOOST_PYTHON_MODULE(implicit_ext)
{
implicitly_convertible<foo,bar>();
implicitly_convertible<int,X>();
def("x_value", x_value);
def("make_x", make_x);
class_<X>("X", init<int>())
.def("value", &X::value)
.def("set", &X::set)
;
implicitly_convertible<X,int>();
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,44 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from implicit_ext import *
>>> x_value(X(42))
42
>>> x_value(42)
42
>>> x = make_x(X(42))
>>> x.value()
42
>>> try: make_x('fool')
... except TypeError: pass
... else: print('no error')
>>> print(x_value.__doc__.splitlines()[1])
x_value( (X)arg1) -> int :
>>> print(make_x.__doc__.splitlines()[1])
make_x( (object)arg1) -> X :
>>> print(X.value.__doc__.splitlines()[1])
value( (X)arg1) -> int :
>>> print(X.set.__doc__.splitlines()[1])
set( (X)arg1, (object)arg2) -> None :
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,70 @@
// Copyright Stefan Seefeld 2007.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <sstream>
namespace bpl = boost::python;
void import_test(char const *py_file_path)
{
// Retrieve the main module
bpl::object main = bpl::import("__main__");
// Retrieve the main module's namespace
bpl::object global(main.attr("__dict__"));
// Inject search path for import_ module
bpl::str script(
"import sys, os.path\n"
"path = os.path.dirname(%r)\n"
"sys.path.insert(0, path)"
% bpl::str(py_file_path));
bpl::object result = bpl::exec(script, global, global);
// Retrieve the main module
bpl::object import_ = bpl::import("import_");
int value = bpl::extract<int>(import_.attr("value")) BOOST_EXTRACT_WORKAROUND;
std::cout << value << std::endl;
BOOST_TEST(value == 42);
}
int main(int argc, char **argv)
{
BOOST_TEST(argc == 2);
// Initialize the interpreter
Py_Initialize();
if (bpl::handle_exception(boost::bind(import_test,argv[1])))
{
if (PyErr_Occurred())
{
BOOST_ERROR("Python Error detected");
PyErr_Print();
}
else
{
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception handler registered.");
}
}
// Boost.Python doesn't support Py_Finalize yet.
// Py_Finalize();
return boost::report_errors();
}
// Including this file makes sure
// that on Windows, any crashes (e.g. null pointer dereferences) invoke
// the debugger immediately, rather than being translated into structured
// exceptions that can interfere with debugging.
#include "module_tail.cpp"

View File

@@ -0,0 +1,5 @@
# Copyright Stefan Seefeld 2007. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
value = 42

View File

@@ -0,0 +1,116 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//#include <stdio.h>
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/python/detail/indirect_traits.hpp>
#include <boost/mpl/assert.hpp>
//#define print(expr) printf("%s ==> %s\n", #expr, expr)
// not all the compilers can handle an incomplete class type here.
struct X {};
using namespace boost::python::indirect_traits;
typedef void (X::*pmf)();
BOOST_MPL_ASSERT((is_reference_to_function<int (&)()>));
BOOST_MPL_ASSERT_NOT((is_reference_to_function<int (*)()>));
BOOST_MPL_ASSERT_NOT((is_reference_to_function<int&>));
BOOST_MPL_ASSERT_NOT((is_reference_to_function<pmf>));
BOOST_MPL_ASSERT_NOT((is_pointer_to_function<int (&)()>));
BOOST_MPL_ASSERT((is_pointer_to_function<int (*)()>));
BOOST_MPL_ASSERT_NOT((is_pointer_to_function<int (*&)()>));
BOOST_MPL_ASSERT_NOT((is_pointer_to_function<int (*const&)()>));
BOOST_MPL_ASSERT_NOT((is_pointer_to_function<pmf>));
BOOST_MPL_ASSERT_NOT((is_reference_to_function_pointer<int (&)()>));
BOOST_MPL_ASSERT_NOT((is_reference_to_function_pointer<int (*)()>));
BOOST_MPL_ASSERT_NOT((is_reference_to_function_pointer<int&>));
BOOST_MPL_ASSERT((is_reference_to_function_pointer<int (*&)()>));
BOOST_MPL_ASSERT((is_reference_to_function_pointer<int (*const&)()>));
BOOST_MPL_ASSERT_NOT((is_reference_to_function_pointer<pmf>));
BOOST_MPL_ASSERT((is_reference_to_pointer<int*&>));
BOOST_MPL_ASSERT((is_reference_to_pointer<int* const&>));
BOOST_MPL_ASSERT((is_reference_to_pointer<int*volatile&>));
BOOST_MPL_ASSERT((is_reference_to_pointer<int*const volatile&>));
BOOST_MPL_ASSERT((is_reference_to_pointer<int const*&>));
BOOST_MPL_ASSERT((is_reference_to_pointer<int const* const&>));
BOOST_MPL_ASSERT((is_reference_to_pointer<int const*volatile&>));
BOOST_MPL_ASSERT((is_reference_to_pointer<int const*const volatile&>));
BOOST_MPL_ASSERT_NOT((is_reference_to_pointer<pmf>));
BOOST_MPL_ASSERT_NOT((is_reference_to_pointer<int const volatile>));
BOOST_MPL_ASSERT_NOT((is_reference_to_pointer<int>));
BOOST_MPL_ASSERT_NOT((is_reference_to_pointer<int*>));
BOOST_MPL_ASSERT_NOT((is_reference_to_const<int*&>));
BOOST_MPL_ASSERT((is_reference_to_const<int* const&>));
BOOST_MPL_ASSERT_NOT((is_reference_to_const<int*volatile&>));
BOOST_MPL_ASSERT((is_reference_to_const<int*const volatile&>));
BOOST_MPL_ASSERT_NOT((is_reference_to_const<int const volatile>));
BOOST_MPL_ASSERT_NOT((is_reference_to_const<int>));
BOOST_MPL_ASSERT_NOT((is_reference_to_const<int*>));
BOOST_MPL_ASSERT((is_reference_to_non_const<int*&>));
BOOST_MPL_ASSERT_NOT((is_reference_to_non_const<int* const&>));
BOOST_MPL_ASSERT((is_reference_to_non_const<int*volatile&>));
BOOST_MPL_ASSERT_NOT((is_reference_to_non_const<int*const volatile&>));
BOOST_MPL_ASSERT_NOT((is_reference_to_non_const<int const volatile>));
BOOST_MPL_ASSERT_NOT((is_reference_to_non_const<int>));
BOOST_MPL_ASSERT_NOT((is_reference_to_non_const<int*>));
BOOST_MPL_ASSERT_NOT((is_reference_to_volatile<int*&>));
BOOST_MPL_ASSERT_NOT((is_reference_to_volatile<int* const&>));
BOOST_MPL_ASSERT((is_reference_to_volatile<int*volatile&>));
BOOST_MPL_ASSERT((is_reference_to_volatile<int*const volatile&>));
BOOST_MPL_ASSERT_NOT((is_reference_to_volatile<int const volatile>));
BOOST_MPL_ASSERT_NOT((is_reference_to_volatile<int>));
BOOST_MPL_ASSERT_NOT((is_reference_to_volatile<int*>));
namespace tt = boost::python::indirect_traits;
BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<int>));
BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<int&>));
BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<int*>));
BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<pmf>));
BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<pmf const&>));
BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<X>));
BOOST_MPL_ASSERT((tt::is_reference_to_class<X&>));
BOOST_MPL_ASSERT((tt::is_reference_to_class<X const&>));
BOOST_MPL_ASSERT((tt::is_reference_to_class<X volatile&>));
BOOST_MPL_ASSERT((tt::is_reference_to_class<X const volatile&>));
BOOST_MPL_ASSERT_NOT((is_pointer_to_class<int>));
BOOST_MPL_ASSERT_NOT((is_pointer_to_class<int*>));
BOOST_MPL_ASSERT_NOT((is_pointer_to_class<int&>));
BOOST_MPL_ASSERT_NOT((is_pointer_to_class<X>));
BOOST_MPL_ASSERT_NOT((is_pointer_to_class<X&>));
BOOST_MPL_ASSERT_NOT((is_pointer_to_class<pmf>));
BOOST_MPL_ASSERT_NOT((is_pointer_to_class<pmf const>));
BOOST_MPL_ASSERT((is_pointer_to_class<X*>));
BOOST_MPL_ASSERT((is_pointer_to_class<X const*>));
BOOST_MPL_ASSERT((is_pointer_to_class<X volatile*>));
BOOST_MPL_ASSERT((is_pointer_to_class<X const volatile*>));
BOOST_MPL_ASSERT((tt::is_reference_to_member_function_pointer<pmf&>));
BOOST_MPL_ASSERT((tt::is_reference_to_member_function_pointer<pmf const&>));
BOOST_MPL_ASSERT((tt::is_reference_to_member_function_pointer<pmf volatile&>));
BOOST_MPL_ASSERT((tt::is_reference_to_member_function_pointer<pmf const volatile&>));
BOOST_MPL_ASSERT_NOT((tt::is_reference_to_member_function_pointer<pmf[2]>));
BOOST_MPL_ASSERT_NOT((tt::is_reference_to_member_function_pointer<pmf(&)[2]>));
BOOST_MPL_ASSERT_NOT((tt::is_reference_to_member_function_pointer<pmf>));

View File

@@ -0,0 +1,39 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include "test_class.hpp"
#include <memory>
#include <boost/shared_ptr.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/python/args.hpp>
using namespace boost::python;
typedef test_class<> X;
X* empty() { return new X(1000); }
std::auto_ptr<X> sum(int a, int b) { return std::auto_ptr<X>(new X(a+b)); }
boost::shared_ptr<X> product(int a, int b, int c)
{
return boost::shared_ptr<X>(new X(a*b*c));
}
BOOST_PYTHON_MODULE(injected_ext)
{
class_<X>("X", init<int>())
.def("__init__", make_constructor(empty))
.def("__init__", make_constructor(sum))
.def("__init__", make_constructor(product
, default_call_policies()
, ( arg_("a"), arg_("b"), arg_("c"))
),
"this is product's docstring")
.def("value", &X::value)
;
}

View File

@@ -0,0 +1,28 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from injected_ext import *
>>> X(3,5).value() - (3+5)
0
>>> X(a=3,b=5,c=7).value() - (3*5*7)
0
>>> X().value()
1000
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,48 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/iterator.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <list>
using namespace boost::python;
typedef std::list<int> list_int;
// Prove that we can handle InputIterators which return rvalues.
struct doubler
{
typedef int result_type;
int operator()(int x) const { return x * 2; }
};
typedef boost::transform_iterator<doubler, list_int::iterator> doubling_iterator;
typedef std::pair<doubling_iterator,doubling_iterator> list_range2;
list_range2 range2(list_int& x)
{
return list_range2(
boost::make_transform_iterator<doubler>(x.begin(), doubler())
, boost::make_transform_iterator<doubler>(x.end(), doubler()));
}
// We do this in a separate module from iterators_ext (iterators.cpp)
// to work around an MSVC6 linker bug, which causes it to complain
// about a "duplicate comdat" if the input iterator is instantiated in
// the same module with the others.
BOOST_PYTHON_MODULE(input_iterator)
{
def("range2", &::range2);
class_<list_range2>("list_range2")
// We can wrap InputIterators which return by-value
.def("__iter__"
, range(&list_range2::first, &list_range2::second))
;
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,16 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/class.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
void int_map_indexing_suite()
{
using namespace boost::python;
// Compile check only...
class_<std::map<int, int> >("IntMap")
.def(map_indexing_suite<std::map<int, int> >())
;
}

View File

@@ -0,0 +1,137 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/return_internal_reference.hpp>
#include <boost/python/copy_non_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/iterator.hpp>
#include <list>
#include <utility>
#include <iterator>
#include <algorithm>
using namespace boost::python;
typedef std::list<int> list_int;
typedef std::list<list_int> list_list;
void push_back(list_int& x, int y)
{
x.push_back(y);
}
void push_list_back(list_list& x, list_int const& y)
{
x.push_back(y);
}
int back(list_int& x)
{
return x.back();
}
typedef std::pair<list_int::iterator,list_int::iterator> list_range;
struct list_range2 : list_range
{
list_int::iterator& begin() { return this->first; }
list_int::iterator& end() { return this->second; }
};
list_range range(list_int& x)
{
return list_range(x.begin(), x.end());
}
struct two_lists
{
two_lists()
{
int primes[] = { 2, 3, 5, 7, 11, 13 };
std::copy(primes, primes + sizeof(primes)/sizeof(*primes), std::back_inserter(one));
int evens[] = { 2, 4, 6, 8, 10, 12 };
std::copy(evens, evens + sizeof(evens)/sizeof(*evens), std::back_inserter(two));
}
struct two_start
{
typedef list_int::iterator result_type;
result_type operator()(two_lists& ll) const { return ll.two.begin(); }
};
friend struct two_start;
list_int::iterator one_begin() { return one.begin(); }
list_int::iterator two_begin() { return two.begin(); }
list_int::iterator one_end() { return one.end(); }
list_int::iterator two_end() { return two.end(); }
private:
list_int one;
list_int two;
};
BOOST_PYTHON_MODULE(iterator_ext)
{
using boost::python::iterator; // gcc 2.96 bug workaround
def("range", &::range);
class_<list_int>("list_int")
.def("push_back", push_back)
.def("back", back)
.def("__iter__", iterator<list_int>())
;
class_<list_range>("list_range")
// We can specify data members
.def("__iter__"
, range(&list_range::first, &list_range::second))
;
// No runtime tests for this one yet
class_<list_range2>("list_range2")
// We can specify member functions returning a non-const reference
.def("__iter__", range(&list_range2::begin, &list_range2::end))
;
class_<two_lists>("two_lists")
// We can spcify member functions
.add_property(
"primes"
, range(&two_lists::one_begin, &two_lists::one_end))
// Prove that we can explicitly specify call policies
.add_property(
"evens"
, range<return_value_policy<copy_non_const_reference> >(
&two_lists::two_begin, &two_lists::two_end))
// Prove that we can specify call policies and target
.add_property(
"twosies"
, range<return_value_policy<copy_non_const_reference>, two_lists>(
// And we can use adaptable function objects when
// partial specialization is available.
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
two_lists::two_start()
# else
&two_lists::two_begin
# endif
, &two_lists::two_end))
;
class_<list_list>("list_list")
.def("push_back", push_list_back)
.def("__iter__", iterator<list_list,return_internal_reference<> >())
;
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,78 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
'''
>>> from iterator_ext import *
>>> from input_iterator import *
>>> x = list_int()
>>> x.push_back(1)
>>> x.back()
1
>>> x.push_back(3)
>>> x.push_back(5)
>>> for y in x:
... print(y)
1
3
5
>>> z = range(x)
>>> for y in z:
... print(y)
1
3
5
Range2 wraps a transform_iterator which doubles the elements it
traverses. This proves we can wrap input iterators
>>> z2 = range2(x)
>>> for y in z2:
... print(y)
2
6
10
>>> l2 = two_lists()
>>> for y in l2.primes:
... print(y)
2
3
5
7
11
13
>>> for y in l2.evens:
... print(y)
2
4
6
8
10
12
>>> ll = list_list()
>>> ll.push_back(x)
>>> x.push_back(7)
>>> ll.push_back(x)
>>> for a in ll: #doctest: +NORMALIZE_WHITESPACE
... for b in a:
... print(b, end='')
... print('')
...
1 3 5
1 3 5 7
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,118 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python.hpp>
#include <string>
struct Foo
{
Foo(
int a = 0
, double b = 0
, const std::string &n = std::string()
) :
a_(a)
, b_(b)
, n_(n)
{}
void set(int a=0, double b=0, const std::string &n=std::string())
{
a_ = a;
b_ = b;
n_ = n;
}
int geta() const { return a_; }
double getb() const { return b_; }
std::string getn() const { return n_; }
private:
int a_;
double b_;
std::string n_;
};
struct Bar
{
Bar(
int a = 0
, double b = 0
, const std::string &n = std::string()
) :
a_(a)
, b_(b)
, n_(n)
{}
void set(int a=0, double b=0, const std::string &n=std::string())
{
a_ = a;
b_ = b;
n_ = n;
}
void seta(int a)
{
a_ = a;
}
int geta() const { return a_; }
double getb() const { return b_; }
std::string getn() const { return n_; }
private:
int a_;
double b_;
std::string n_;
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(bar_set, Bar::set, 0,3)
using namespace boost::python;
BOOST_PYTHON_MODULE(keywords)
{
#if BOOST_WORKAROUND(__GNUC__, == 2)
using boost::python::arg;
#endif
class_<Foo>(
"Foo"
, init<int, double, const std::string&>(
( arg("a") = 0
, arg("b") = 0.0
, arg("n") = std::string()
)
))
.def("set", &Foo::set, (arg("a") = 0, arg("b") = 0.0, arg("n") = std::string()) )
.def("set2", &Foo::set, (arg("a"), "b", "n") )
.def("a", &Foo::geta)
.def("b", &Foo::getb)
.def("n", &Foo::getn)
;
class_<Bar>("Bar"
, init<optional<int, double, const std::string &> >()
)
.def("set", &Bar::set, bar_set())
.def("set2", &Bar::set, bar_set("set2's docstring"))
.def("seta", &Bar::seta, arg("a"))
.def("a", &Bar::geta)
.def("b", &Bar::getb)
.def("n", &Bar::getn)
;
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,106 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from keywords import *
>>> f = Foo()
>>> f.a(), f.b(), f.n()
(0, 0.0, '')
>>> f = Foo(1)
>>> f.a(), f.b(), f.n()
(1, 0.0, '')
>>> f = Foo(1,1.0)
>>> f.a(), f.b(), f.n()
(1, 1.0, '')
>>> f = Foo(1,1.0,"1")
>>> f.a(), f.b(), f.n()
(1, 1.0, '1')
>>> f = Foo(a=1)
>>> f.a(), f.b(), f.n()
(1, 0.0, '')
>>> f = Foo(b=1)
>>> f.a(), f.b(), f.n()
(0, 1.0, '')
>>> f = Foo(n="1")
>>> f.a(), f.b(), f.n()
(0, 0.0, '1')
>>> f = Foo(1,n="1")
>>> f.a(), f.b(), f.n()
(1, 0.0, '1')
>>> f.set()
>>> f.a(), f.b(), f.n()
(0, 0.0, '')
>>> f.set(1)
>>> f.a(), f.b(), f.n()
(1, 0.0, '')
>>> f.set(1,1.0)
>>> f.a(), f.b(), f.n()
(1, 1.0, '')
>>> f.set(1,1.0,"1")
>>> f.a(), f.b(), f.n()
(1, 1.0, '1')
>>> f.set(a=1)
>>> f.a(), f.b(), f.n()
(1, 0.0, '')
>>> f.set(b=1)
>>> f.a(), f.b(), f.n()
(0, 1.0, '')
>>> f.set(n="1")
>>> f.a(), f.b(), f.n()
(0, 0.0, '1')
>>> f.set(1,n="1")
>>> f.a(), f.b(), f.n()
(1, 0.0, '1')
>>> f.set2(b=2.0,n="2",a=2)
>>> f.a(), f.b(), f.n()
(2, 2.0, '2')
# lets see how badly we've broken the 'regular' functions
>>> f = Bar()
>>> f.a(), f.b(), f.n()
(0, 0.0, '')
>>> f = Bar(1)
>>> f.a(), f.b(), f.n()
(1, 0.0, '')
>>> f = Bar(1,1.0)
>>> f.a(), f.b(), f.n()
(1, 1.0, '')
>>> f = Bar(1,1.0,"1")
>>> f.a(), f.b(), f.n()
(1, 1.0, '1')
>>> f.set()
>>> f.a(), f.b(), f.n()
(0, 0.0, '')
>>> f.set(1)
>>> f.a(), f.b(), f.n()
(1, 0.0, '')
>>> f.set(1,1.0)
>>> f.a(), f.b(), f.n()
(1, 1.0, '')
>>> f.set(1,1.0,"1")
>>> f.a(), f.b(), f.n()
(1, 1.0, '1')
>>> f.set2.__doc__.splitlines()[1]
'set2( (Bar)arg1 [, (int)arg2 [, (float)arg3 [, (str)arg4]]]) -> None :'
>>> f.set2.__doc__.splitlines()[2]
" set2's docstring"
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

154
libs/python/test/list.cpp Normal file
View File

@@ -0,0 +1,154 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/list.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/dict.hpp>
#include <boost/python/make_function.hpp>
#include <boost/lexical_cast.hpp>
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>
#include "test_class.hpp"
using namespace boost::python;
object new_list()
{
return list();
}
list listify(object x)
{
return list(x);
}
object listify_string(char const* s)
{
return list(s);
}
std::string x_rep(test_class<> const& x)
{
return "X(" + boost::lexical_cast<std::string>(x.value()) + ")";
}
object apply_object_list(object f, list x)
{
return f(x);
}
list apply_list_list(object f, list x)
{
return call<list>(f.ptr(), x);
}
void append_object(list& x, object y)
{
x.append(y);
}
void append_list(list& x, list const& y)
{
x.append(y);
}
typedef test_class<> X;
int notcmp(object const& x, object const& y)
{
return y < x ? -1 : y > x ? 1 : 0;
}
void exercise(list x, object y, object print)
{
x.append(y);
x.append(5);
x.append(X(3));
print("after append:");
print(x);
print("number of", y, "instances:", x.count(y));
print("number of 5s:", x.count(5));
x.extend("xyz");
print("after extend:");
print(x);
print("index of", y, "is:", x.index(y));
print("index of 'l' is:", x.index("l"));
x.insert(4, 666);
print("after inserting 666:");
print(x);
print("inserting with object as index:");
x.insert(x[x.index(5)], "---");
print(x);
print("popping...");
x.pop();
print(x);
x.pop(x[x.index(5)]);
print(x);
x.pop(x.index(5));
print(x);
print("removing", y);
x.remove(y);
print(x);
print("removing", 666);
x.remove(666);
print(x);
print("reversing...");
x.reverse();
print(x);
print("sorted:");
x.pop(2); // make sorting predictable
x.pop(2); // remove [1,2] so the list is sortable in py3k
x.sort();
print(x);
print("reverse sorted:");
#if PY_VERSION_HEX >= 0x03000000
x.sort(*tuple(), **dict(make_tuple(make_tuple("reverse", true))));
#else
x.sort(&notcmp);
#endif
print(x);
list w;
w.append(5);
w.append(6);
w += "hi";
BOOST_ASSERT(w[0] == 5);
BOOST_ASSERT(w[1] == 6);
BOOST_ASSERT(w[2] == 'h');
BOOST_ASSERT(w[3] == 'i');
}
BOOST_PYTHON_MODULE(list_ext)
{
def("new_list", new_list);
def("listify", listify);
def("listify_string", listify_string);
def("apply_object_list", apply_object_list);
def("apply_list_list", apply_list_list);
def("append_object", append_object);
def("append_list", append_list);
def("exercise", exercise);
class_<X>("X", init<int>())
.def( "__repr__", x_rep)
;
}
#include "module_tail.cpp"

119
libs/python/test/list.py Normal file
View File

@@ -0,0 +1,119 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
'''
>>> from list_ext import *
>>> new_list()
[]
>>> listify((1,2,3))
[1, 2, 3]
>>> letters = listify_string('hello')
>>> letters
['h', 'e', 'l', 'l', 'o']
>>> X(22)
X(22)
>>> def identity(x):
... return x
>>> assert apply_object_list(identity, letters) is letters
5 is not convertible to a list
>>> try: result = apply_object_list(identity, 5)
... except TypeError: pass
... else: print('expected an exception, got', result, 'instead')
>>> assert apply_list_list(identity, letters) is letters
5 is not convertible to a list as a return value
>>> try: result = apply_list_list(len, letters)
... except TypeError: pass
... else: print('expected an exception, got', result, 'instead')
>>> append_object(letters, '.')
>>> letters
['h', 'e', 'l', 'l', 'o', '.']
tuples do not automatically convert to lists when passed as arguments
>>> try: append_list(letters, (1,2))
... except TypeError: pass
... else: print('expected an exception')
>>> append_list(letters, [1,2])
>>> letters
['h', 'e', 'l', 'l', 'o', '.', [1, 2]]
Check that subclass functions are properly called
>>> class mylist(list):
... def append(self, o):
... list.append(self, o)
... if not hasattr(self, 'nappends'):
... self.nappends = 1
... else:
... self.nappends += 1
...
>>> l2 = mylist()
>>> append_object(l2, 'hello')
>>> append_object(l2, 'world')
>>> l2
['hello', 'world']
>>> l2.nappends
2
>>> def printer(*args):
... for x in args: print( x,)
... print('')
...
>>> y = X(42)
>>> exercise(letters, y, printer) #doctest: +NORMALIZE_WHITESPACE
after append:
['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3)]
number of X(42) instances: 1
number of 5s: 1
after extend:
['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z']
index of X(42) is: 7
index of 'l' is: 2
after inserting 666:
['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z']
inserting with object as index:
['h', 'e', 'l', 'l', 666, '---', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z']
popping...
['h', 'e', 'l', 'l', 666, '---', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y']
['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y']
['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), X(3), 'x', 'y']
removing X(42)
['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(3), 'x', 'y']
removing 666
['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(3), 'x', 'y']
reversing...
['y', 'x', X(3), [1, 2], '.', 'o', 'l', 'l', 'e', 'h']
sorted:
['.', 'e', 'h', 'l', 'l', 'o', 'x', 'y']
reverse sorted:
['y', 'x', 'o', 'l', 'l', 'h', 'e', '.']
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

63
libs/python/test/long.cpp Normal file
View File

@@ -0,0 +1,63 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/long.hpp>
#include <boost/python/class.hpp>
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>
using namespace boost::python;
object new_long()
{
return long_();
}
long_ longify(object x)
{
return long_(x);
}
object longify_string(char const* s)
{
return long_(s);
}
char const* is_long1(long_& x)
{
long_ y = x;
x += 50;
BOOST_ASSERT(x == y + 50);
return "yes";
}
int is_long2(char const*)
{
return 0;
}
// tests for accepting objects (and derived classes) in constructors
// from "Milind Patil" <milind_patil-at-hotmail.com>
struct Y
{
Y(boost::python::long_) {}
};
BOOST_PYTHON_MODULE(long_ext)
{
def("new_long", new_long);
def("longify", longify);
def("longify_string", longify_string);
def("is_long", is_long1);
def("is_long", is_long2);
class_< Y >("Y", init< boost::python::long_ >())
;
}
#include "module_tail.cpp"

36
libs/python/test/long.py Normal file
View File

@@ -0,0 +1,36 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import sys
if (sys.version_info.major >= 3):
long = int
'''
>>> from long_ext import *
>>> print(new_long())
0
>>> print(longify(42))
42
>>> print(longify_string('300'))
300
>>> is_long(long(20))
'yes'
>>> is_long('20')
0
>>> x = Y(long(4294967295))
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

344
libs/python/test/m1.cpp Normal file
View File

@@ -0,0 +1,344 @@
// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/def.hpp>
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/lvalue_from_pytype.hpp>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/to_python_converter.hpp>
#include <boost/python/errors.hpp>
#include <boost/python/manage_new_object.hpp>
#include <boost/python/converter/pytype_function.hpp>
#include <string.h>
#include "simple_type.hpp"
#include "complicated.hpp"
// Declare some straightforward extension types
extern "C" void
dealloc(PyObject* self)
{
PyObject_Del(self);
}
// Noddy is a type we got from one of the Python sample files
struct NoddyObject : PyObject
{
int x;
};
PyTypeObject NoddyType = {
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Noddy"),
sizeof(NoddyObject),
0,
dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
0, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
#if PYTHON_API_VERSION >= 1012
0 /* tp_del */
#endif
};
// Create a Noddy containing 42
PyObject* new_noddy()
{
NoddyObject* noddy = PyObject_New(NoddyObject, &NoddyType);
noddy->x = 42;
return (PyObject*)noddy;
}
// Simple is a wrapper around a struct simple, which just contains a char*
struct SimpleObject
{
PyObject_HEAD
simple x;
};
struct extract_simple_object
{
static simple& execute(SimpleObject& o) { return o.x; }
};
PyTypeObject SimpleType = {
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Simple"),
sizeof(SimpleObject),
0,
dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
0, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
#if PYTHON_API_VERSION >= 1012
0 /* tp_del */
#endif
};
// Create a Simple containing "hello, world"
PyObject* new_simple()
{
SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType);
simple->x.s = const_cast<char*>("hello, world");
return (PyObject*)simple;
}
//
// Declare some wrappers/unwrappers to test the low-level conversion
// mechanism.
//
using boost::python::to_python_converter;
// Wrap a simple by copying it into a Simple
struct simple_to_python
: to_python_converter<simple, simple_to_python, true>
//, boost::python::converter::wrap_pytype<&SimpleType>
{
static PyObject* convert(simple const& x)
{
SimpleObject* p = PyObject_New(SimpleObject, &SimpleType);
p->x = x;
return (PyObject*)p;
}
static PyTypeObject const *get_pytype(){return &SimpleType; }
};
struct int_from_noddy
{
static int& execute(NoddyObject& p)
{
return p.x;
}
};
//
// Some C++ functions to expose to Python
//
// Returns the length of s's held string
int f(simple const& s)
{
return strlen(s.s);
}
int f_mutable_ref(simple& s)
{
return strlen(s.s);
}
int f_mutable_ptr(simple* s)
{
return strlen(s->s);
}
int f_const_ptr(simple const* s)
{
return strlen(s->s);
}
int f2(SimpleObject const& s)
{
return strlen(s.x.s);
}
// A trivial passthru function for simple objects
simple const& g(simple const& x)
{
return x;
}
struct A
{
A() : x(0) {}
virtual ~A() {}
char const* name() { return "A"; }
int x;
};
struct B : A
{
B() : x(1) {}
static char const* name(B*) { return "B"; }
int x;
};
struct C : A
{
C() : x(2) {}
char const* name() { return "C"; }
virtual ~C() {}
int x;
};
struct D : B, C
{
D() : x(3) {}
char const* name() { return "D"; }
int x;
};
A take_a(A const& a) { return a; }
B take_b(B& b) { return b; }
C take_c(C* c) { return *c; }
D take_d(D* const& d) { return *d; }
D take_d_shared_ptr(boost::shared_ptr<D> d) { return *d; }
boost::shared_ptr<A> d_factory() { return boost::shared_ptr<B>(new D); }
struct Unregistered {};
Unregistered make_unregistered(int) { return Unregistered(); }
Unregistered* make_unregistered2(int) { return new Unregistered; }
BOOST_PYTHON_MODULE(m1)
{
using namespace boost::python;
using boost::shared_ptr;
simple_to_python();
lvalue_from_pytype<int_from_noddy,&NoddyType>();
lvalue_from_pytype<
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // doesn't support non-type member pointer parameters
extract_member<SimpleObject, simple, &SimpleObject::x>
#else
extract_simple_object
#endif
, &SimpleType
>();
lvalue_from_pytype<extract_identity<SimpleObject>,&SimpleType>();
def("new_noddy", new_noddy);
def("new_simple", new_simple);
def("make_unregistered", make_unregistered);
def("make_unregistered2", make_unregistered2, return_value_policy<manage_new_object>());
// Expose f() in all its variations
def("f", f);
def("f_mutable_ref", f_mutable_ref);
def("f_mutable_ptr", f_mutable_ptr);
def("f_const_ptr", f_const_ptr);
def("f2", f2);
// Expose g()
def("g", g , return_value_policy<copy_const_reference>()
);
def("take_a", take_a);
def("take_b", take_b);
def("take_c", take_c);
def("take_d", take_d);
def("take_d_shared_ptr", take_d_shared_ptr);
def("d_factory", d_factory);
class_<A, shared_ptr<A> >("A")
.def("name", &A::name)
;
// sequence points don't ensure that "A" is constructed before "B"
// or "C" below if we make them part of the same chain
class_<B,bases<A> >("B")
.def("name", &B::name)
;
class_<C,bases<A> >("C")
.def("name", &C::name)
;
class_<D, bases<B,C> >("D")
.def("name", &D::name)
;
class_<complicated>("complicated",
init<simple const&,int>())
.def(init<simple const&>())
.def("get_n", &complicated::get_n)
;
}
#include "module_tail.cpp"

108
libs/python/test/m2.cpp Normal file
View File

@@ -0,0 +1,108 @@
// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This module exercises the converters exposed in m1 at a low level
// by exposing raw Python extension functions that use wrap<> and
// unwrap<> objects.
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/copy_non_const_reference.hpp>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include "simple_type.hpp"
#if PY_VERSION_HEX >= 0x03000000
# define PyString_FromString PyUnicode_FromString
# define PyInt_FromLong PyLong_FromLong
#endif
// Get a simple (by value) from the argument, and return the
// string it holds.
PyObject* unwrap_simple(simple x)
{
return PyString_FromString(x.s);
}
// Likewise, but demands that its possible to get a non-const
// reference to the simple.
PyObject* unwrap_simple_ref(simple& x)
{
return PyString_FromString(x.s);
}
// Likewise, with a const reference to the simple object.
PyObject* unwrap_simple_const_ref(simple const& x)
{
return PyString_FromString(x.s);
}
// Get an int (by value) from the argument, and convert it to a
// Python Int.
PyObject* unwrap_int(int x)
{
return PyInt_FromLong(x);
}
// Get a non-const reference to an int from the argument
PyObject* unwrap_int_ref(int& x)
{
return PyInt_FromLong(x);
}
// Get a const reference to an int from the argument.
PyObject* unwrap_int_const_ref(int const& x)
{
return PyInt_FromLong(x);
}
#if PY_VERSION_HEX >= 0x03000000
# undef PyString_FromString
# undef PyInt_FromLong
#endif
// rewrap<T> extracts a T from the argument, then converts the T back
// to a PyObject* and returns it.
template <class T>
struct rewrap
{
static T f(T x) { return x; }
};
BOOST_PYTHON_MODULE(m2)
{
using boost::python::return_value_policy;
using boost::python::copy_const_reference;
using boost::python::copy_non_const_reference;
using boost::python::def;
def("unwrap_int", unwrap_int);
def("unwrap_int_ref", unwrap_int_ref);
def("unwrap_int_const_ref", unwrap_int_const_ref);
def("unwrap_simple", unwrap_simple);
def("unwrap_simple_ref", unwrap_simple_ref);
def("unwrap_simple_const_ref", unwrap_simple_const_ref);
def("wrap_int", &rewrap<int>::f);
def("wrap_int_ref", &rewrap<int&>::f
, return_value_policy<copy_non_const_reference>()
);
def("wrap_int_const_ref", &rewrap<int const&>::f
, return_value_policy<copy_const_reference>()
);
def("wrap_simple", &rewrap<simple>::f);
def("wrap_simple_ref", &rewrap<simple&>::f
, return_value_policy<copy_non_const_reference>()
);
def("wrap_simple_const_ref", &rewrap<simple const&>::f
, return_value_policy<copy_const_reference>()
);
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,68 @@
// Copyright Joel de Guzman 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/implicit.hpp>
using namespace boost::python;
struct X // a container element
{
std::string s;
X():s("default") {}
X(std::string s):s(s) {}
std::string repr() const { return s; }
void reset() { s = "reset"; }
void foo() { s = "foo"; }
bool operator==(X const& x) const { return s == x.s; }
bool operator!=(X const& x) const { return s != x.s; }
};
std::string x_value(X const& x)
{
return "gotya " + x.s;
}
BOOST_PYTHON_MODULE(map_indexing_suite_ext)
{
class_<X>("X")
.def(init<>())
.def(init<X>())
.def(init<std::string>())
.def("__repr__", &X::repr)
.def("reset", &X::reset)
.def("foo", &X::foo)
;
def("x_value", x_value);
implicitly_convertible<std::string, X>();
class_<std::map<std::string, X> >("XMap")
.def(map_indexing_suite<std::map<std::string, X> >())
;
void int_map_indexing_suite(); // moved to int_map_indexing_suite.cpp to
int_map_indexing_suite(); // avoid MSVC 6/7 internal structure overflow
#if 0
// Compile check only...
class_<std::map<int, int> >("IntMap")
.def(map_indexing_suite<std::map<int, int> >())
;
#endif
// Some more..
class_<std::map<std::string, boost::shared_ptr<X> > >("TestMap")
.def(map_indexing_suite<std::map<std::string, boost::shared_ptr<X> >, true>())
;
void a_map_indexing_suite(); // moved to a_map_indexing_suite.cpp to
a_map_indexing_suite(); // avoid MSVC 6/7 internal structure overflow
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,243 @@
# Copyright Joel de Guzman 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
'''
#####################################################################
# Check an object that we will use as container element
#####################################################################
>>> from map_indexing_suite_ext import *
>>> assert "map_indexing_suite_IntMap_entry" in dir()
>>> assert "map_indexing_suite_TestMap_entry" in dir()
>>> assert "map_indexing_suite_XMap_entry" in dir()
>>> assert "map_indexing_suite_AMap_entry" in dir()
>>> x = X('hi')
>>> x
hi
>>> x.reset() # a member function that modifies X
>>> x
reset
>>> x.foo() # another member function that modifies X
>>> x
foo
# test that a string is implicitly convertible
# to an X
>>> x_value('bochi bochi')
'gotya bochi bochi'
#####################################################################
# Iteration
#####################################################################
>>> def print_xmap(xmap):
... s = '[ '
... for x in xmap:
... s += repr(x)
... s += ' '
... s += ']'
... print(s)
#####################################################################
# Setting (adding entries)
#####################################################################
>>> xm = XMap()
>>> xm['joel'] = 'apple'
>>> xm['tenji'] = 'orange'
>>> xm['mariel'] = 'grape'
>>> xm['tutit'] = 'banana'
>>> xm['kim'] = 'kiwi'
>>> print_xmap(xm)
[ (joel, apple) (kim, kiwi) (mariel, grape) (tenji, orange) (tutit, banana) ]
#####################################################################
# Changing an entry
#####################################################################
>>> xm['joel'] = 'pineapple'
>>> print_xmap(xm)
[ (joel, pineapple) (kim, kiwi) (mariel, grape) (tenji, orange) (tutit, banana) ]
#####################################################################
# Deleting an entry
#####################################################################
>>> del xm['joel']
>>> print_xmap(xm)
[ (kim, kiwi) (mariel, grape) (tenji, orange) (tutit, banana) ]
#####################################################################
# adding an entry
#####################################################################
>>> xm['joel'] = 'apple'
>>> print_xmap(xm)
[ (joel, apple) (kim, kiwi) (mariel, grape) (tenji, orange) (tutit, banana) ]
#####################################################################
# Indexing
#####################################################################
>>> len(xm)
5
>>> xm['joel']
apple
>>> xm['tenji']
orange
>>> xm['mariel']
grape
>>> xm['tutit']
banana
>>> xm['kim']
kiwi
#####################################################################
# Calling a mutating function of a container element
#####################################################################
>>> xm['joel'].reset()
>>> xm['joel']
reset
#####################################################################
# Copying a container element
#####################################################################
>>> x = X(xm['mariel'])
>>> x
grape
>>> x.foo()
>>> x
foo
>>> xm['mariel'] # should not be changed to 'foo'
grape
#####################################################################
# Referencing a container element
#####################################################################
>>> x = xm['mariel']
>>> x
grape
>>> x.foo()
>>> x
foo
>>> xm['mariel'] # should be changed to 'foo'
foo
>>> xm['mariel'] = 'grape' # take it back
>>> xm['joel'] = 'apple' # take it back
#####################################################################
# Contains
#####################################################################
>>> assert 'joel' in xm
>>> assert 'mariel' in xm
>>> assert 'tenji' in xm
>>> assert 'tutit' in xm
>>> assert 'kim' in xm
>>> assert not 'X' in xm
>>> assert not 12345 in xm
#####################################################################
# Some references to the container elements
#####################################################################
>>> z0 = xm['joel']
>>> z1 = xm['mariel']
>>> z2 = xm['tenji']
>>> z3 = xm['tutit']
>>> z4 = xm['kim']
>>> z0 # proxy
apple
>>> z1 # proxy
grape
>>> z2 # proxy
orange
>>> z3 # proxy
banana
>>> z4 # proxy
kiwi
#####################################################################
# Delete some container element
#####################################################################
>>> del xm['tenji']
>>> print_xmap(xm)
[ (joel, apple) (kim, kiwi) (mariel, grape) (tutit, banana) ]
>>> del xm['tutit']
>>> print_xmap(xm)
[ (joel, apple) (kim, kiwi) (mariel, grape) ]
#####################################################################
# Show that the references are still valid
#####################################################################
>>> z0 # proxy
apple
>>> z1 # proxy
grape
>>> z2 # proxy detached
orange
>>> z3 # proxy detached
banana
>>> z4 # proxy
kiwi
#####################################################################
# Show that iteration allows mutable access to the elements
#####################################################################
>>> for x in xm:
... x.data().reset()
>>> print_xmap(xm)
[ (joel, reset) (kim, reset) (mariel, reset) ]
#####################################################################
# Some more...
#####################################################################
>>> tm = TestMap()
>>> tm["joel"] = X("aaa")
>>> tm["kimpo"] = X("bbb")
>>> print_xmap(tm)
[ (joel, aaa) (kimpo, bbb) ]
>>> for el in tm: #doctest: +NORMALIZE_WHITESPACE
... print(el.key(), end='')
... dom = el.data()
joel kimpo
#####################################################################
# Test custom converter...
#####################################################################
>>> am = AMap()
>>> am[3] = 4
>>> am[3]
4
>>> for i in am:
... i.data()
4
#####################################################################
# END....
#####################################################################
'''
def run(args = None):
import sys
import doctest
if args is not None:
sys.argxm = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print('running...')
import sys
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,16 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
# include <iostream> // works around a KCC intermediate code generation bug
#endif
BOOST_PYTHON_MODULE(minimal_ext)
{
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,7 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
print("IMPORTING minimal_ext")
import minimal_ext
print("DONE IMPORTING minimal_ext")

View File

@@ -0,0 +1,58 @@
// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#if defined(_WIN32)
# ifdef __MWERKS__
# pragma ANSI_strict off
# endif
# include <windows.h>
# ifdef __MWERKS__
# pragma ANSI_strict reset
# endif
# ifdef _MSC_VER
# include <eh.h> // for _set_se_translator()
# pragma warning(push)
# pragma warning(disable:4297)
# pragma warning(disable:4535)
extern "C" void straight_to_debugger(unsigned int, EXCEPTION_POINTERS*)
{
throw;
}
extern "C" void (*old_translator)(unsigned, EXCEPTION_POINTERS*)
= _set_se_translator(straight_to_debugger);
# pragma warning(pop)
# endif
#endif // _WIN32
#include <exception>
#include <boost/python/extract.hpp>
#include <boost/python/str.hpp>
struct test_failure : std::exception
{
test_failure(char const* expr, char const* /*function*/, char const* file, unsigned line)
: msg(file + boost::python::str(":%s:") % line + ": Boost.Python assertion failure: " + expr)
{}
~test_failure() throw() {}
char const* what() const throw()
{
return boost::python::extract<char const*>(msg)();
}
boost::python::str msg;
};
namespace boost
{
void assertion_failed(char const * expr, char const * function, char const * file, long line)
{
throw ::test_failure(expr,function, file, line);
}
} // namespace boost

View File

@@ -0,0 +1,27 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
struct A
{
A(const double, const double, const double, const double, const double
, const double, const double
, const double, const double
) {}
};
BOOST_PYTHON_MODULE(multi_arg_constructor_ext)
{
using namespace boost::python;
class_<A>(
"A"
, init<double, double, double, double, double, double, double, double, double>()
)
;
}

View File

@@ -0,0 +1,21 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from multi_arg_constructor_ext import *
>>> a = A(1.0, 2, 3, 4, 5, 6, 7.0, 8.1, 9.3)
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,51 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/operators.hpp>
#include <boost/python/scope.hpp>
#include "test_class.hpp"
#if __GNUC__ != 2
# include <ostream>
#else
# include <ostream.h>
#endif
typedef test_class<> X;
typedef test_class<1> Y;
std::ostream& operator<<(std::ostream& s, X const& x)
{
return s << x.value();
}
std::ostream& operator<<(std::ostream& s, Y const& x)
{
return s << x.value();
}
BOOST_PYTHON_MODULE(nested_ext)
{
using namespace boost::python;
// Establish X as the current scope.
scope x_class
= class_<X>("X", init<int>())
.def(str(self))
;
// Y will now be defined in the current scope
class_<Y>("Y", init<int>())
.def(str(self))
;
}
#include "module_tail.cpp"

View File

@@ -0,0 +1,40 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from nested_ext import *
>>> X
<class 'nested_ext.X'>
>>> X.__module__
'nested_ext'
>>> X.__name__
'X'
>>> X.Y
<class 'nested_ext.Y'>
>>> X.Y.__module__
'nested_ext'
>>> X.Y.__name__
'Y'
'''
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

206
libs/python/test/newtest.py Normal file
View File

@@ -0,0 +1,206 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
"""
>>> from m1 import *
>>> from m2 import *
Prove that we get an appropriate error from trying to return a type
for which we have no registered to_python converter
>>> def check_unregistered(f, msgprefix):
... try:
... f(1)
... except TypeError as x:
... if not str(x).startswith(msgprefix):
... print(str(x))
... else:
... print('expected a TypeError')
...
>>> check_unregistered(make_unregistered, 'No to_python (by-value) converter found for C++ type')
>>> check_unregistered(make_unregistered2, 'No Python class registered for C++ class')
>>> n = new_noddy()
>>> s = new_simple()
>>> unwrap_int(n)
42
>>> unwrap_int_ref(n)
42
>>> unwrap_int_const_ref(n)
42
>>> unwrap_simple(s)
'hello, world'
>>> unwrap_simple_ref(s)
'hello, world'
>>> unwrap_simple_const_ref(s)
'hello, world'
>>> unwrap_int(5)
5
Can't get a non-const reference to a built-in integer object
>>> try:
... unwrap_int_ref(7)
... except: pass
... else: print('no exception')
>>> unwrap_int_const_ref(9)
9
>>> wrap_int(n)
42
try: wrap_int_ref(n)
... except: pass
... else: print('no exception')
>>> wrap_int_const_ref(n)
42
>>> unwrap_simple_ref(wrap_simple(s))
'hello, world'
>>> unwrap_simple_ref(wrap_simple_ref(s))
'hello, world'
>>> unwrap_simple_ref(wrap_simple_const_ref(s))
'hello, world'
>>> f(s)
12
>>> unwrap_simple(g(s))
'hello, world'
>>> f(g(s))
12
>>> f_mutable_ref(g(s))
12
>>> f_const_ptr(g(s))
12
>>> f_mutable_ptr(g(s))
12
>>> f2(g(s))
12
Create an extension class which wraps "complicated" (init1 and get_n)
are a complicated constructor and member function, respectively.
>>> c1 = complicated(s, 99)
>>> c1.get_n()
99
>>> c2 = complicated(s)
>>> c2.get_n()
0
a quick regression test for a bug where None could be converted
to the target of any member function. To see it, we need to
access the __dict__ directly, to bypass the type check supplied
by the Method property which wraps the method when accessed as an
attribute.
>>> try: A.__dict__['name'](None)
... except TypeError: pass
... else: print('expected an exception!')
>>> a = A()
>>> b = B()
>>> c = C()
>>> d = D()
>>> take_a(a).name()
'A'
>>> try:
... take_b(a)
... except: pass
... else: print('no exception')
>>> try:
... take_c(a)
... except: pass
... else: print('no exception')
>>> try:
... take_d(a)
... except: pass
... else: print('no exception')
------
>>> take_a(b).name()
'A'
>>> take_b(b).name()
'B'
>>> try:
... take_c(b)
... except: pass
... else: print('no exception')
>>> try:
... take_d(b)
... except: pass
... else: print('no exception')
-------
>>> take_a(c).name()
'A'
>>> try:
... take_b(c)
... except: pass
... else: print('no exception')
>>> take_c(c).name()
'C'
>>> try:
... take_d(c)
... except: pass
... else: print('no exception')
-------
>>> take_a(d).name()
'A'
>>> take_b(d).name()
'B'
>>> take_c(d).name()
'C'
>>> take_d(d).name()
'D'
>>> take_d_shared_ptr(d).name()
'D'
>>> d_as_a = d_factory()
>>> dd = take_d(d_as_a)
>>> dd.name()
'D'
>>> print(g.__doc__.splitlines()[1])
g( (Simple)arg1) -> Simple :
"""
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
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,49 @@
// Copyright Jim Bosch & Ankit Daftery 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/numpy.hpp>
#include <boost/cstdint.hpp>
namespace p = boost::python;
namespace np = boost::python::numpy;
template <typename T>
np::dtype accept(T) {
return np::dtype::get_builtin<T>();
}
BOOST_PYTHON_MODULE(dtype_ext)
{
np::initialize();
// wrap dtype equivalence test, since it isn't available in Python API.
p::def("equivalent", np::equivalent);
// integers, by number of bits
p::def("accept_int8", accept<boost::int8_t>);
p::def("accept_uint8", accept<boost::uint8_t>);
p::def("accept_int16", accept<boost::int16_t>);
p::def("accept_uint16", accept<boost::uint16_t>);
p::def("accept_int32", accept<boost::int32_t>);
p::def("accept_uint32", accept<boost::uint32_t>);
p::def("accept_int64", accept<boost::int64_t>);
p::def("accept_uint64", accept<boost::uint64_t>);
// integers, by C name according to NumPy
p::def("accept_bool_", accept<bool>);
p::def("accept_byte", accept<signed char>);
p::def("accept_ubyte", accept<unsigned char>);
p::def("accept_short", accept<short>);
p::def("accept_ushort", accept<unsigned short>);
p::def("accept_intc", accept<int>);
p::def("accept_uintc", accept<unsigned int>);
// floats and complex
p::def("accept_float32", accept<float>);
p::def("accept_complex64", accept< std::complex<float> >);
p::def("accept_float64", accept<double>);
p::def("accept_complex128", accept< std::complex<double> >);
if (sizeof(long double) > sizeof(double)) {
p::def("accept_longdouble", accept<long double>);
p::def("accept_clongdouble", accept< std::complex<long double> >);
}
}

View File

@@ -0,0 +1,63 @@
#!/usr/bin/env python
# Copyright Jim Bosch & Ankit Daftery 2010-2012.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
import dtype_ext
import unittest
import numpy
import sys
if (sys.version_info.major >= 3):
long = int
class DtypeTestCase(unittest.TestCase):
def assertEquivalent(self, a, b):
return self.assert_(dtype_ext.equivalent(a, b), "%r is not equivalent to %r")
def testIntegers(self):
for bits in (8, 16, 32, 64):
s = getattr(numpy, "int%d" % bits)
u = getattr(numpy, "uint%d" % bits)
fs = getattr(dtype_ext, "accept_int%d" % bits)
fu = getattr(dtype_ext, "accept_uint%d" % bits)
self.assertEquivalent(fs(s(1)), numpy.dtype(s))
self.assertEquivalent(fu(u(1)), numpy.dtype(u))
# these should just use the regular Boost.Python converters
self.assertEquivalent(fs(True), numpy.dtype(s))
self.assertEquivalent(fu(True), numpy.dtype(u))
self.assertEquivalent(fs(int(1)), numpy.dtype(s))
self.assertEquivalent(fu(int(1)), numpy.dtype(u))
self.assertEquivalent(fs(long(1)), numpy.dtype(s))
self.assertEquivalent(fu(long(1)), numpy.dtype(u))
for name in ("bool_", "byte", "ubyte", "short", "ushort", "intc", "uintc"):
t = getattr(numpy, name)
ft = getattr(dtype_ext, "accept_%s" % name)
self.assertEquivalent(ft(t(1)), numpy.dtype(t))
# these should just use the regular Boost.Python converters
self.assertEquivalent(ft(True), numpy.dtype(t))
if name != "bool_":
self.assertEquivalent(ft(int(1)), numpy.dtype(t))
self.assertEquivalent(ft(long(1)), numpy.dtype(t))
def testFloats(self):
f = numpy.float32
c = numpy.complex64
self.assertEquivalent(dtype_ext.accept_float32(f(numpy.pi)), numpy.dtype(f))
self.assertEquivalent(dtype_ext.accept_complex64(c(1+2j)), numpy.dtype(c))
f = numpy.float64
c = numpy.complex128
self.assertEquivalent(dtype_ext.accept_float64(f(numpy.pi)), numpy.dtype(f))
self.assertEquivalent(dtype_ext.accept_complex128(c(1+2j)), numpy.dtype(c))
if hasattr(numpy, "longdouble") and hasattr(dtype_ext, "accept_longdouble"):
f = numpy.longdouble
c = numpy.clongdouble
self.assertEquivalent(dtype_ext.accept_longdouble(f(numpy.pi)), numpy.dtype(f))
self.assertEquivalent(dtype_ext.accept_clongdouble(c(1+2j)), numpy.dtype(c))
if __name__=="__main__":
unittest.main()

View File

@@ -0,0 +1,28 @@
// Copyright Jim Bosch & Ankit Daftery 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/numpy.hpp>
#include <boost/python/slice.hpp>
namespace p = boost::python;
namespace np = boost::python::numpy;
p::object single(np::ndarray ndarr, int i) { return ndarr[i];}
p::object slice(np::ndarray ndarr, p::slice sl) { return ndarr[sl];}
p::object indexarray(np::ndarray ndarr, np::ndarray d1) { return ndarr[d1];}
p::object indexarray_2d(np::ndarray ndarr, np::ndarray d1,np::ndarray d2) { return ndarr[p::make_tuple(d1,d2)];}
p::object indexslice(np::ndarray ndarr, np::ndarray d1, p::slice sl) { return ndarr[p::make_tuple(d1, sl)];}
BOOST_PYTHON_MODULE(indexing_ext)
{
np::initialize();
p::def("single", single);
p::def("slice", slice);
p::def("indexarray", indexarray);
p::def("indexarray", indexarray_2d);
p::def("indexslice", indexslice);
}

Some files were not shown because too many files have changed in this diff Show More