2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-22 17:32:55 +00:00

Compare commits

..

39 Commits

Author SHA1 Message Date
Daniel James
8bf5a125cf Create a branch for inspect fixes.
[SVN r61439]
2010-04-20 21:11:27 +00:00
Jeremiah Willcock
5b36b84444 Fixed tab and no-newline-at-end-of-file issues from inspection report
[SVN r61435]
2010-04-20 17:54:16 +00:00
Ralf W. Grosse-Kunstleve
78ec0d12db libs/python/test/Jamfile.v2: moving "rule require-windows" block up to avoid bjam syntax error
[SVN r61086]
2010-04-05 21:28:30 +00:00
Ralf W. Grosse-Kunstleve
a7c16bf695 libs/python/test/Jamfile.v2: compile calling_conventions tests only under Windows, following Valdimir Prus' instructions (boost mailing list)
[SVN r61053]
2010-04-04 21:03:33 +00:00
Steven Watanabe
6d4be7ab3a Handle the destructor call in a way that keeps msvc happy. Fixes #4003
[SVN r60868]
2010-03-26 19:04:40 +00:00
Ralf W. Grosse-Kunstleve
65e74ccf1e boost/python/object_core.hpp: new .is_none() member function
[SVN r60625]
2010-03-15 22:00:30 +00:00
Vladimir Prus
9398a63250 Implement --python-buildid.
Fixes #3544.
Patch from Gaudenz Steinlin.


[SVN r59987]
2010-02-28 08:22:46 +00:00
Dave Abrahams
1660730320 Remove unintentional reference to "union" test that's not checked in.
[SVN r59331]
2010-01-28 14:39:30 +00:00
Dave Abrahams
5418a663cb Support different MS calling conventions, thanks to Nicolas Lelong.
Closes #3833.


[SVN r59265]
2010-01-25 14:48:49 +00:00
Ralf W. Grosse-Kunstleve
33408d2dcc boost/python/object/make_instance.hpp: missing include added to resolve g++ 4.4 compilation errors
[SVN r59256]
2010-01-24 19:04:59 +00:00
Dave Abrahams
3ad52bce72 Support different MS calling conventions, thanks to Nicolas Lelong.
Closes #3833.


[SVN r59247]
2010-01-24 02:08:46 +00:00
Ralf W. Grosse-Kunstleve
4f6a37f80d boost.python: some make_tuple changed to boost::python::make_tuple for gcc 4.4 -std=c++0x compatibility; https://svn.boost.org/trac/boost/ticket/3584
[SVN r57641]
2009-11-13 20:48:25 +00:00
Troy D. Straszheim
338732793a Don't use type_is_gc... type_is_gc expects a PyTypeObject, which is not what will get passed to it if we pass it to the tp_is_gc fields of static_data_object
[SVN r57590]
2009-11-12 00:46:46 +00:00
Troy D. Straszheim
8b0655ce94 Fix for #2582, thanks for the patch.
[SVN r57016]
2009-10-20 15:06:21 +00:00
Troy D. Straszheim
36d24b9f8b rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
Ralf W. Grosse-Kunstleve
35ff0adf2b boost/python: some Py_ssize_t replaced with boost::python::ssize_t to restore compatibility with Python 2.3 and 2.4
[SVN r56491]
2009-09-30 12:35:54 +00:00
Stefan Seefeld
115cde9c7f Revert accidental change.
[SVN r56310]
2009-09-19 16:59:05 +00:00
Stefan Seefeld
ef2a02c396 Merged 2009 GSoC work from sandbox-branches/bhy/py3k branch back into trunk.
[SVN r56305]
2009-09-19 02:32:41 +00:00
Ralf W. Grosse-Kunstleve
e3f6f01588 boost/python/object_operators.hpp: added missing error checks in operator bool_type(), operator!(); this resolves https://svn.boost.org/trac/boost/ticket/3356 posted by Stefan Seefeld
[SVN r55708]
2009-08-22 00:18:28 +00:00
Ralf W. Grosse-Kunstleve
d7389277d3 libs/python/test/exec.cpp: new exercise_embedding_html(), in reaction to https://svn.boost.org/trac/boost/ticket/1890
[SVN r55640]
2009-08-18 00:49:05 +00:00
Ralf W. Grosse-Kunstleve
8d2ca93e98 libs/python/src/exec.cpp: bug fixes
Remark:
  operator!() for boost::python::object invokes PyObject_IsTrue()
  and is therefore not equivalent to "is None".
  In this particular case !global or !local returns true for an
  empty dict.
(Changes to libs/python/test/exec.cpp just helped in debugging.)


[SVN r55639]
2009-08-18 00:24:54 +00:00
Troy D. Straszheim
d47e3b2a15 Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
Ralf W. Grosse-Kunstleve
27aa9382fc boost_python_unsigned_converter_fix_no_ctypes.patch by Anderson Lizardo (https://svn.boost.org/trac/boost/ticket/3189)
[SVN r54923]
2009-07-13 15:00:07 +00:00
Ralf W. Grosse-Kunstleve
1a204046c7 boost::python: unsigned converter fix by Anderson Lizardo (https://svn.boost.org/trac/boost/ticket/3189)
[SVN r54919]
2009-07-13 05:16:34 +00:00
Stefan Seefeld
3c98a72153 Use appropriate default values for global and local dicts.
[SVN r53936]
2009-06-15 14:53:48 +00:00
Dave Abrahams
a4f028246a Allow duplicate enum values. Fixes #2744
Thanks to hugo.lima@openbossa.org


[SVN r53660]
2009-06-05 21:18:14 +00:00
Dave Abrahams
6ffeca641c GCC Warning Suppression
[SVN r53659]
2009-06-05 20:15:01 +00:00
Dave Abrahams
22b65a1485 Fix up a lot of missing dependency info. Closes #3136.
[SVN r53657]
2009-06-05 20:12:47 +00:00
Dave Abrahams
d45b9ea66b Add missing dependencies
[SVN r53645]
2009-06-04 23:27:40 +00:00
Vladimir Prus
0373302165 If no python is configured, default-configure it.
Fixes #2846.


[SVN r53380]
2009-05-29 08:18:09 +00:00
Vladimir Prus
ef53bedd0a Don't mention --preserve-test-targets.
Targets are no longer removed by default, so this reference
is unnecessary.

Addresses #2001.


[SVN r53379]
2009-05-29 08:05:49 +00:00
Jeremiah Willcock
3ecb3301a2 Fixed most tab and min/max issues from trunk inspection report
[SVN r53141]
2009-05-20 19:19:00 +00:00
Troy D. Straszheim
e16b3f8ab8 Merge cmake files release -> trunk.
[SVN r52866]
2009-05-09 22:57:30 +00:00
Joel de Guzman
7a7b32661e fixed wrong version
[SVN r52604]
2009-04-26 14:46:18 +00:00
Ralf W. Grosse-Kunstleve
e312047405 libs/python/src/converter/builtin_converters.cpp: Troy Straszheim's bool/int patch with additional BOOST_PYTHON_BOOL_INT_STRICT condition; see also: http://mail.python.org/pipermail/cplusplus-sig/2009-March/014354.html
[SVN r52299]
2009-04-09 17:30:13 +00:00
Troy D. Straszheim
50acffa593 Tune up python tests for removal of our ctest hacks
[SVN r52255]
2009-04-08 15:46:14 +00:00
Troy D. Straszheim
cf5fcc0a1e Test for overload resolution bug.
See this mail for details:

http://mail.python.org/pipermail/cplusplus-sig/2009-March/014362.html



[SVN r52250]
2009-04-08 12:08:35 +00:00
Troy D. Straszheim
c9e694bed8 Build python modules without leading 'lib' and not single threaded
[SVN r52249]
2009-04-08 11:54:20 +00:00
Jeremiah Willcock
0b7333f854 Moved property map library into property_map/ directory; made old files into stubs with #warnings; converted uses and docs of property map library to use new names
[SVN r52226]
2009-04-07 01:28:38 +00:00
50 changed files with 1027 additions and 492 deletions

View File

@@ -1,80 +0,0 @@
if (PYTHON_LIBRARIES)
include_directories(${PYTHON_INCLUDE_PATH})
# Determine extra libraries we need to link against to build Python
# extension modules.
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "dl")
if(CMAKE_COMPILER_IS_GNUCXX)
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt")
endif(CMAKE_COMPILER_IS_GNUCXX)
elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSD")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread")
elseif(CMAKE_SYSTEM_NAME STREQUAL "DragonFly")
# DragonFly is a variant of FreeBSD
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread")
elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread" "dl")
if(CMAKE_COMPILER_IS_GNUCXX)
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt")
endif(CMAKE_COMPILER_IS_GNUCXX)
elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX")
# No options necessary for QNX
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# No options necessary for Mac OS X
elseif(CMAKE_SYSTEM_NAME STREQUAL "HP-UX")
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt")
elseif(UNIX)
# Assume -pthread and -ldl on all other variants
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread" "dl")
if(CMAKE_COMPILER_IS_GNUCXX)
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "util")
endif(CMAKE_COMPILER_IS_GNUCXX)
endif(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
################################################################################
#-- Macro for building Boost.Python extension modules
macro(boost_python_extension MODULE_NAME)
parse_arguments(BPL_EXT
""
""
${ARGN})
#TODO: The target properties are NOT being set correctly for the test libraries
if (FALSE)
# Create the library target itself
add_library(${MODULE_NAME} MODULE ${BPL_EXT_DEFAULT_ARGS} )
# Miscellaneous target properties
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
# Link against Boost.Python library
target_link_libraries(${MODULE_NAME} boost_python-static)
# Link against Python libraries
target_link_libraries(${MODULE_NAME} ${PYTHON_LIBRARIES})
endif(FALSE)
boost_add_library(
${MODULE_NAME}
${BPL_EXT_DEFAULT_ARGS}
MODULE
LINK_LIBS ${PYTHON_LIBRARIES}
DEPENDS boost_python
)
endmacro(boost_python_extension)
#--
################################################################################
boost_library_project(
Python
SRCDIRS src
TESTDIRS test
HEADERS python.hpp python
MODULARIZED
DESCRIPTION "A framework for interfacing Python and C++. It allows you to quickly and seamlessly expose C++ classes functions and objects to Python, and vice-versa, using no special tools -- just your C++ compiler."
AUTHORS "David Abrahams <dave -at- boostpro.com>"
)
endif (PYTHON_LIBRARIES)

View File

@@ -3,6 +3,7 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import os ;
import indirect ;
import modules ;
import feature ;
@@ -41,8 +42,27 @@ py3-version = [ find-py3-version ] ;
project boost/python
: source-location ../src
: requirements
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(__name__).tag
;
rule tag ( name : type ? : property-set )
{
local result = $(name) ;
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
{
if $(name) = boost_python && $(PYTHON_ID)
{
result = $(result)-$(PYTHON_ID) ;
}
}
# forward to the boost tagging rule
return [ indirect.call $(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
$(result) : $(type) : $(property-set) ] ;
}
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }

View File

@@ -1,7 +1,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter 1. python 1.0</title>
<title>Chapter 1. python 2.0</title>
<link rel="stylesheet" href="../../../../../../doc/html/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="index.html" title="Chapter 1. python 1.0">

View File

@@ -1,5 +1,5 @@
[library python
[version 1.0]
[version 2.0]
[authors [de Guzman, Joel], [Abrahams, David]]
[copyright 2002 2003 2004 2005 Joel de Guzman, David Abrahams]
[category inter-language support]
@@ -186,10 +186,6 @@ And so on... Finally:
Or something similar. If all is well, you should now have built the DLLs and
run the Python program.
[note Starting from Boost 1.35, bjam erases the generated executables
(e.g. pyd file) after the test has concluded to conserve disk space.
To keep bjam from doing that, pass --preserve-test-targets to bjam.]
[:[*There you go... Have fun!]]
[endsect]

View File

@@ -106,6 +106,33 @@
function from being treated as an exported symbol on platforms which
support that distinction in-code</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_ENABLE_CDECL</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined, allows functions using the <code>__cdecl
</code> calling convention to be wrapped.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_ENABLE_STDCALL</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined, allows functions using the <code>__stdcall
</code> calling convention to be wrapped.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_ENABLE_FASTCALL</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined, allows functions using the <code>__fastcall
</code> calling convention to be wrapped.</td>
</tr>
</table>
<h2><a name="lib-defined-impl"></a>Library Defined Implementation

View File

@@ -835,6 +835,8 @@ namespace boost { namespace python { namespace api
object&amp; operator=(object const&amp;);
PyObject* ptr() const;
bool is_none() const;
};
}}}
</pre>
@@ -895,6 +897,14 @@ PyObject* ptr() const;
<dt><b>Returns:</b> a pointer to the internally-held Python
object.</dt>
</dl>
<pre>
bool is_none() const;
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> result of (ptr() == Py_None)</dt>
</dl>
<!-- -->
<h3><a name="proxy-spec"></a>Class template <code>proxy</code></h3>
@@ -1101,7 +1111,7 @@ object sum_items(object seq)
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
27 May, 2008
15 March, 2010
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>

View File

@@ -2,6 +2,15 @@
# 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 ;
if ! [ python.configured ]
{
ECHO "notice: no Python configured in user-config.jam" ;
ECHO "notice: will use default configuration" ;
using python ;
}
# Specify the path to the Boost project. If you move this project,
# adjust this path to refer to the Boost root directory.
use-project boost

View File

@@ -55,8 +55,8 @@ inline decorated_type_info::decorated_type_info(type_info base_t, decoration dec
inline bool decorated_type_info::operator<(decorated_type_info const& rhs) const
{
return m_decoration < rhs.m_decoration
|| m_decoration == rhs.m_decoration
&& m_base_type < rhs.m_base_type;
|| (m_decoration == rhs.m_decoration
&& m_base_type < rhs.m_base_type);
}
inline bool decorated_type_info::operator==(decorated_type_info const& rhs) const

View File

@@ -30,7 +30,7 @@ struct value_destroyer<
template <class T>
static void execute(T const volatile* p)
{
p->T::~T();
p->~T();
}
};

View File

@@ -2,13 +2,15 @@
// 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 TRANSLATE_EXCEPTION_DWA2002810_HPP
# define TRANSLATE_EXCEPTION_DWA2002810_HPP
#ifndef TRANSLATE_EXCEPTION_TDS20091020_HPP
# define TRANSLATE_EXCEPTION_TDS20091020_HPP
# include <boost/python/detail/exception_handler.hpp>
# include <boost/call_traits.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/remove_reference.hpp>
# include <boost/function/function0.hpp>

View File

@@ -182,8 +182,8 @@ typedef int pid_t;
# define Py_REFCNT(o) (((PyObject*)(o))->ob_refcnt)
# define Py_SIZE(o) (((PyVarObject*)(o))->ob_size)
# define PyVarObject_HEAD_INIT(type, size) \
PyObject_HEAD_INIT(type) size,
# define PyVarObject_HEAD_INIT(type, size) \
PyObject_HEAD_INIT(type) size,
#endif

View File

@@ -41,7 +41,7 @@ inline enum_<T>::enum_(char const* name, char const* doc )
, &enum_<T>::convertible_from_python
, &enum_<T>::construct
, type_id<T>()
, doc
, doc
)
{
}

View File

@@ -20,6 +20,13 @@ object
BOOST_PYTHON_DECL
eval(str string, object global = object(), object local = object());
// Execute an individual python statement from str.
// global and local are the global and local scopes respectively,
// used during execution.
object
BOOST_PYTHON_DECL
exec_statement(str string, object global = object(), object local = object());
// Execute python source code from str.
// global and local are the global and local scopes respectively,
// used during execution.

View File

@@ -19,7 +19,7 @@ namespace detail
{
void append(object_cref); // append object to end
Py_ssize_t count(object_cref value) const; // return number of occurrences of value
ssize_t count(object_cref value) const; // return number of occurrences of value
void extend(object_cref sequence); // extend list by appending sequence elements

View File

@@ -105,12 +105,12 @@ namespace detail
// If the BasePolicy_ supplied a result converter it would be
// ignored; issue an error if it's not the default.
#if defined _MSC_VER && _MSC_VER < 1300
typedef is_same<
typedef is_same<
typename BasePolicy_::result_converter
, default_result_converter
> same_result_converter;
//see above for explanation
BOOST_STATIC_ASSERT(same_result_converter::value) ;
//see above for explanation
BOOST_STATIC_ASSERT(same_result_converter::value) ;
#else
BOOST_MPL_ASSERT_MSG(
(is_same<

View File

@@ -10,6 +10,7 @@
# include <boost/python/converter/registered.hpp>
# include <boost/python/detail/decref_guard.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/type_traits/is_union.hpp>
namespace boost { namespace python { namespace objects {
@@ -21,7 +22,7 @@ struct make_instance_impl
template <class Arg>
static inline PyObject* execute(Arg& x)
{
BOOST_STATIC_ASSERT(is_class<T>::value);
BOOST_MPL_ASSERT((mpl::or_<is_class<T>, is_union<T> >));
PyTypeObject* type = Derived::get_class_object(x);

View File

@@ -35,6 +35,8 @@
# include <boost/detail/workaround.hpp>
# include <boost/type_traits/remove_const.hpp>
namespace boost { namespace python {
template <class T> class wrapper;
@@ -122,26 +124,29 @@ inline pointer_holder_back_reference<Pointer,Value>::pointer_holder_back_referen
template <class Pointer, class Value>
void* pointer_holder<Pointer, Value>::holds(type_info dst_t, bool null_ptr_only)
{
typedef typename boost::remove_const< Value >::type non_const_value;
if (dst_t == python::type_id<Pointer>()
&& !(null_ptr_only && get_pointer(this->m_p))
)
return &this->m_p;
Value* p
Value* p0
# if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
= static_cast<Value*>( get_pointer(this->m_p) )
# else
= get_pointer(this->m_p)
# endif
;
non_const_value* p = const_cast<non_const_value*>( p0 );
if (p == 0)
return 0;
if (void* wrapped = holds_wrapped(dst_t, p, p))
return wrapped;
type_info src_t = python::type_id<Value>();
type_info src_t = python::type_id<non_const_value>();
return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t);
}

View File

@@ -5,6 +5,8 @@
#ifndef OBJECT_CORE_DWA2002615_HPP
# define OBJECT_CORE_DWA2002615_HPP
# define BOOST_PYTHON_OBJECT_HAS_IS_NONE // added 2010-03-15 by rwgk
# include <boost/python/detail/prefix.hpp>
# include <boost/type.hpp>
@@ -239,7 +241,9 @@ namespace api
// Underlying object access -- returns a borrowed reference
inline PyObject* ptr() const;
inline bool is_none() const;
private:
PyObject* m_ptr;
};
@@ -539,6 +543,11 @@ inline PyObject* api::object_base::ptr() const
return m_ptr;
}
inline bool api::object_base::is_none() const
{
return (m_ptr == Py_None);
}
//
// Converter specialization implementations
//

View File

@@ -60,7 +60,9 @@ inline
object_operators<U>::operator bool_type() const
{
object_cref2 x = *static_cast<U const*>(this);
return PyObject_IsTrue(x.ptr()) ? &object::ptr : 0;
int is_true = PyObject_IsTrue(x.ptr());
if (is_true < 0) throw_error_already_set();
return is_true ? &object::ptr : 0;
}
template <class U>
@@ -68,7 +70,9 @@ inline bool
object_operators<U>::operator!() const
{
object_cref2 x = *static_cast<U const*>(this);
return !PyObject_IsTrue(x.ptr());
int is_true = PyObject_IsTrue(x.ptr());
if (is_true < 0) throw_error_already_set();
return !is_true;
}
# define BOOST_PYTHON_COMPARE_OP(op, opid) \

View File

@@ -52,16 +52,23 @@ struct most_derived
//
// template <class RT, class T0... class TN>
// inline mpl::vector<RT, T0...TN>
// get_signature(RT(*)(T0...TN), void* = 0)
// get_signature(RT(BOOST_PYTHON_FN_CC *)(T0...TN), void* = 0)
// {
// return mpl::list<RT, T0...TN>();
// }
//
// where BOOST_PYTHON_FN_CC is a calling convention keyword, can be
//
// empty, for default calling convention
// __cdecl (if BOOST_PYTHON_ENABLE_CDECL is defined)
// __stdcall (if BOOST_PYTHON_ENABLE_STDCALL is defined)
// __fastcall (if BOOST_PYTHON_ENABLE_FASTCALL is defined)
//
// And, for an appropriate assortment of cv-qualifications::
//
// template <class RT, class ClassT, class T0... class TN>
// inline mpl::vector<RT, ClassT&, T0...TN>
// get_signature(RT(ClassT::*)(T0...TN) cv))
// get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv))
// {
// return mpl::list<RT, ClassT&, T0...TN>();
// }
@@ -72,7 +79,7 @@ struct most_derived
// , typename most_derived<Target, ClassT>::type&
// , T0...TN
// >
// get_signature(RT(ClassT::*)(T0...TN) cv), Target*)
// get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv), Target*)
// {
// return mpl::list<RT, ClassT&, T0...TN>();
// }
@@ -87,7 +94,8 @@ struct most_derived
//
// These functions extract the return type, class (for member
// functions) and arguments of the input signature and stuff them in
// an mpl type sequence. Note that cv-qualification is dropped from
// an mpl type sequence (the calling convention is dropped).
// Note that cv-qualification is dropped from
// the "hidden this" argument of member functions; that is a
// necessary sacrifice to ensure that an lvalue from_python converter
// is used. A pointer is not used so that None will be rejected for
@@ -100,10 +108,64 @@ struct most_derived
//
// @group {
// 'default' calling convention
# define BOOST_PYTHON_FN_CC
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_PYTHON_FN_CC
// __cdecl calling convention
# if defined(BOOST_PYTHON_ENABLE_CDECL)
# define BOOST_PYTHON_FN_CC __cdecl
# define BOOST_PYTHON_FN_CC_IS_CDECL
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_PYTHON_FN_CC
# undef BOOST_PYTHON_FN_CC_IS_CDECL
# endif // defined(BOOST_PYTHON_ENABLE_CDECL)
// __stdcall calling convention
# if defined(BOOST_PYTHON_ENABLE_STDCALL)
# define BOOST_PYTHON_FN_CC __stdcall
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_PYTHON_FN_CC
# endif // defined(BOOST_PYTHON_ENABLE_STDCALL)
// __fastcall calling convention
# if defined(BOOST_PYTHON_ENABLE_FASTCALL)
# define BOOST_PYTHON_FN_CC __fastcall
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_PYTHON_FN_CC
# endif // defined(BOOST_PYTHON_ENABLE_FASTCALL)
# undef BOOST_PYTHON_LIST_INC
// }
@@ -120,17 +182,24 @@ struct most_derived
# define N BOOST_PP_ITERATION()
// as 'get_signature(RT(*)(T0...TN), void* = 0)' is the same
// function as 'get_signature(RT(__cdecl *)(T0...TN), void* = 0)',
// we don't define it twice
# if !defined(BOOST_PYTHON_FN_CC_IS_CDECL)
template <
class RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)>
inline BOOST_PYTHON_LIST_INC(N)<
RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)>
get_signature(RT(*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0)
get_signature(RT(BOOST_PYTHON_FN_CC *)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0)
{
return BOOST_PYTHON_LIST_INC(N)<
RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
>();
}
# endif // !defined(BOOST_PYTHON_FN_CC_IS_CDECL)
# undef N
# define BOOST_PP_ITERATION_PARAMS_2 \
@@ -146,7 +215,7 @@ template <
class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)>
inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)>
get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q)
get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q)
{
return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
@@ -165,7 +234,7 @@ inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
>
get_signature(
RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q
RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q
, Target*
)
{

View File

@@ -1,3 +0,0 @@
boost_module(python DEPENDS graph numeric)
# numeric is there because of boost/cast.hpp from libs/python/src/errors.cpp:11

View File

@@ -1,64 +0,0 @@
if (PYTHON_DEBUG_LIBRARIES AND BUILD_BOOST_PYTHON)
# We have detected that there might be Python debug libraries
# available, but check for ourselves whether this is true by trying
# to compile/link a program against them.
set(CMAKE_REQUIRED_DEFINITIONS "-DBOOST_DEBUG_PYTHON -DPy_DEBUG")
get_directory_property(CMAKE_REQUIRED_INCLUDES INCLUDE_DIRECTORIES)
set(CMAKE_REQUIRED_LIBRARIES ${PYTHON_DEBUG_LIBRARIES})
set(CHECK_PYDEBUG_SOURCE
"#include <boost/python/object.hpp>")
check_cxx_source_compiles(
"#include <boost/python/object.hpp>
void check(PyObject *obj) { Py_INCREF(obj); } int main() { }"
PYDEBUG_CAN_BUILD)
# Setup an option to enable/disable building variants with Python
# debugging. If we were able to link against the debug libraries,
# default to ON; otherwise, default to OFF.
option(BUILD_PYTHON_DEBUG
"Build an additional Boost.Python library with Python debugging enabled"
${PYDEBUG_CAN_BUILD})
endif (PYTHON_DEBUG_LIBRARIES AND BUILD_BOOST_PYTHON)
# Always build the non-debug variants of the boost_python library
set(BUILD_PYTHON_NODEBUG ON)
boost_add_library(boost_python
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
object/enum.cpp
object/class.cpp
object/function.cpp
object/inheritance.cpp
object/life_support.cpp
object/pickle_support.cpp
errors.cpp
module.cpp
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object/stl_iterator.cpp
object_protocol.cpp
object_operators.cpp
wrapper.cpp
import.cpp
exec.cpp
object/function_doc_signature.cpp
STATIC_COMPILE_FLAGS "-DBOOST_PYTHON_SOURCE -DBOOST_PYTHON_STATIC_LIB"
SHARED_COMPILE_FLAGS "-DBOOST_PYTHON_SOURCE"
PYTHON_NODEBUG_LINK_LIBS "${PYTHON_LIBRARIES}"
# Support for Python debugging
EXTRA_VARIANTS PYTHON_NODEBUG:PYTHON_DEBUG
PYTHON_DEBUG_COMPILE_FLAGS "-DBOOST_DEBUG_PYTHON -DPy_DEBUG"
PYTHON_DEBUG_LINK_LIBS "${PYTHON_DEBUG_LIBRARIES}"
)

View File

@@ -153,8 +153,13 @@ namespace
if (number_methods == 0)
return 0;
return (PyInt_Check(obj) || PyLong_Check(obj))
? &number_methods->nb_int : 0;
return (
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
!PyBool_Check(obj) &&
#endif
(PyInt_Check(obj) || PyLong_Check(obj)))
? &number_methods->nb_int : 0;
}
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
};
@@ -180,7 +185,11 @@ namespace
if (number_methods == 0)
return 0;
return (PyInt_Check(obj) || PyLong_Check(obj))
return (
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
!PyBool_Check(obj) &&
#endif
(PyInt_Check(obj) || PyLong_Check(obj)))
? &py_object_identity : 0;
}
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
@@ -191,10 +200,27 @@ namespace
{
static T extract(PyObject* intermediate)
{
return numeric_cast<T>(
PyLong_Check(intermediate)
? PyLong_AsUnsignedLong(intermediate)
: PyInt_AS_LONG(intermediate));
if (PyLong_Check(intermediate)) {
// PyLong_AsUnsignedLong() checks for negative overflow, so no
// need to check it here.
unsigned long result = PyLong_AsUnsignedLong(intermediate);
if (PyErr_Occurred())
throw_error_already_set();
return numeric_cast<T>(result);
} else {
// None of PyInt_AsUnsigned*() functions check for negative
// overflow, so use PyInt_AS_LONG instead and check if number is
// negative, issuing the exception appropriately.
long result = PyInt_AS_LONG(intermediate);
if (PyErr_Occurred())
throw_error_already_set();
if (result < 0) {
PyErr_SetString(PyExc_OverflowError, "can't convert negative"
" value to unsigned");
throw_error_already_set();
}
return numeric_cast<T>(result);
}
}
};
#endif // PY_VERSION_HEX >= 0x03000000
@@ -282,6 +308,8 @@ namespace
{
#if PY_VERSION_HEX >= 0x03000000
return obj == Py_None || PyLong_Check(obj) ? &py_object_identity : 0;
#elif PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
return obj == Py_None || PyBool_Check(obj) ? &py_object_identity : 0;
#else
return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0;
#endif

View File

@@ -5,6 +5,7 @@
#include <boost/python/exec.hpp>
#include <boost/python/borrowed.hpp>
#include <boost/python/dict.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/handle.hpp>
@@ -15,6 +16,15 @@ namespace python
object BOOST_PYTHON_DECL eval(str string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = python::extract<char *>(string);
PyObject* result = PyRun_String(s, Py_eval_input, global.ptr(), local.ptr());
@@ -24,6 +34,15 @@ object BOOST_PYTHON_DECL eval(str string, object global, object local)
object BOOST_PYTHON_DECL exec(str string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = python::extract<char *>(string);
PyObject* result = PyRun_String(s, Py_file_input, global.ptr(), local.ptr());
@@ -31,11 +50,38 @@ object BOOST_PYTHON_DECL exec(str string, object global, object local)
return object(detail::new_reference(result));
}
object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = python::extract<char *>(string);
PyObject* result = PyRun_String(s, Py_single_input, global.ptr(), local.ptr());
if (!result) throw_error_already_set();
return object(detail::new_reference(result));
}
// Execute python source code from file filename.
// global and local are the global and local scopes respectively,
// used during execution.
object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *f = python::extract<char *>(filename);
#if PY_VERSION_HEX >= 0x03000000

View File

@@ -144,11 +144,11 @@ void list_base::sort(object_cref cmpfunc)
// For some reason, moving this to the end of the TU suppresses an ICE
// with vc6.
Py_ssize_t list_base::count(object_cref value) const
ssize_t list_base::count(object_cref value) const
{
object result_obj(this->attr("count")(value));
#if PY_VERSION_HEX >= 0x03000000
Py_ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
#else
long result = PyInt_AsLong(result_obj.ptr());
#endif

View File

@@ -182,7 +182,7 @@ static PyTypeObject static_data_object = {
0, /* tp_alloc */
0, // filled in with type_new /* tp_new */
0, // filled in with __PyObject_GC_Del /* tp_free */
(inquiry)type_is_gc, /* tp_is_gc */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
@@ -355,7 +355,7 @@ namespace objects
PyObject* d = type_->tp_dict;
PyObject* instance_size_obj = PyObject_GetAttrString(d, const_cast<char*>("__instance_size__"));
Py_ssize_t instance_size = instance_size_obj ?
ssize_t instance_size = instance_size_obj ?
#if PY_VERSION_HEX >= 0x03000000
PyLong_AsSsize_t(instance_size_obj) : 0;
#else
@@ -552,13 +552,12 @@ namespace objects
// Build a tuple of the base Python type objects. If no bases
// were declared, we'll use our class_type() as the single base
// class.
std::size_t const num_bases = (std::max)(num_types - 1, static_cast<std::size_t>(1));
assert(num_bases <= ssize_t_max);
handle<> bases(PyTuple_New(static_cast<ssize_t>(num_bases)));
ssize_t const num_bases = (std::max)(num_types - 1, static_cast<std::size_t>(1));
handle<> bases(PyTuple_New(num_bases));
for (std::size_t i = 1; i <= num_bases; ++i)
for (ssize_t i = 1; i <= num_bases; ++i)
{
type_handle c = (i >= num_types) ? class_type() : get_class(types[i]);
type_handle c = (i >= static_cast<ssize_t>(num_types)) ? class_type() : get_class(types[i]);
// PyTuple_SET_ITEM steals this reference
PyTuple_SET_ITEM(bases.get(), static_cast<ssize_t>(i - 1), upcast<PyObject>(c.release()));
}

View File

@@ -14,7 +14,7 @@
#include <boost/python/object_protocol.hpp>
#include <structmember.h>
namespace boost { namespace python { namespace objects {
namespace boost { namespace python { namespace objects {
struct enum_object
{
@@ -51,7 +51,6 @@ extern "C"
}
else
{
//char* name = PyString_AsString(self->name);
PyObject* name = self->name;
if (name == 0)
return 0;
@@ -166,15 +165,16 @@ namespace
dict d;
d["__slots__"] = tuple();
d["values"] = dict();
d["names"] = dict();
object module_name = module_prefix();
if (module_name)
d["__module__"] = module_name;
if (doc)
d["__doc__"] = doc;
object result = (object(metatype))(name, make_tuple(base), d);
scope().attr(name) = result;
return result;
@@ -194,7 +194,7 @@ enum_base::enum_base(
converter::registration& converters
= const_cast<converter::registration&>(
converter::registry::lookup(id));
converters.m_class_object = downcast<PyTypeObject>(this->ptr());
converter::registry::insert(to_python, id);
converter::registry::insert(convertible, construct, id);
@@ -213,23 +213,24 @@ void enum_base::add_value(char const* name_, long value)
dict d = extract<dict>(this->attr("values"))();
d[value] = x;
// Set the name field in the new enum instanec
enum_object* p = downcast<enum_object>(x.ptr());
Py_XDECREF(p->name);
p->name = incref(name.ptr());
dict names_dict = extract<dict>(this->attr("names"))();
names_dict[x.attr("name")] = x;
}
void enum_base::export_values()
{
dict d = extract<dict>(this->attr("values"))();
list values = d.values();
dict d = extract<dict>(this->attr("names"))();
list items = d.items();
scope current;
for (unsigned i = 0, max = len(values); i < max; ++i)
{
api::setattr(current, object(values[i].attr("name")), values[i]);
}
for (unsigned i = 0, max = len(items); i < max; ++i)
api::setattr(current, items[i][0], items[i][1]);
}
PyObject* enum_base::to_python(PyTypeObject* type_, long x)

View File

@@ -144,7 +144,7 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
if (n_keyword_actual > 0 // Keyword arguments were supplied
|| n_actual < min_arity) // or default keyword values are needed
{
if (f->m_arg_names.ptr() == Py_None)
if (f->m_arg_names.is_none())
{
// this overload doesn't accept keywords
inner_args = handle<>();
@@ -166,7 +166,7 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
else
{
// build a new arg tuple, will adjust its size later
assert(max_arity <= ssize_t_max);
assert(max_arity <= static_cast<std::size_t>(ssize_t_max));
inner_args = handle<>(
PyTuple_New(static_cast<ssize_t>(max_arity)));
@@ -487,7 +487,7 @@ void function::add_to_namespace(
}
// A function is named the first time it is added to a namespace.
if (new_func->name().ptr() == Py_None)
if (new_func->name().is_none())
new_func->m_name = name;
handle<> name_space_name(
@@ -653,7 +653,7 @@ extern "C"
static PyObject* function_get_name(PyObject* op, void*)
{
function* f = downcast<function>(op);
if (f->name().ptr() == Py_None)
if (f->name().is_none())
#if PY_VERSION_HEX >= 0x03000000
return PyUnicode_InternFromString("<unnamed Boost.Python function>");
#else

View File

@@ -3,6 +3,9 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// boost::python::make_tuple below are for gcc 4.4 -std=c++0x compatibility
// (Intel C++ 10 and 11 with -std=c++0x don't need the full qualification).
#include <boost/python/converter/registrations.hpp>
#include <boost/python/object/function_doc_signature.hpp>
#include <boost/python/errors.hpp>
@@ -12,7 +15,6 @@
#include <boost/python/detail/signature.hpp>
#include <vector>
namespace boost { namespace python { namespace objects {
@@ -52,9 +54,9 @@ namespace boost { namespace python { namespace objects {
//check if the argument default values are the same
bool f1_has_names = bool(f1->m_arg_names);
bool f2_has_names = bool(f2->m_arg_names);
if ( f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=f1->m_arg_names[i-1]
|| f1_has_names && !f2_has_names
|| !f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=python::object()
if ( (f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=f1->m_arg_names[i-1])
|| (f1_has_names && !f2_has_names)
|| (!f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=python::object())
)
return false;
}
@@ -228,7 +230,7 @@ namespace boost { namespace python { namespace objects {
{
return str(
"%s %s(%s%s%s%s)"
% make_tuple
% boost::python::make_tuple // workaround, see top
( ret_type
, f->m_name
, str(",").join(formal_params.slice(0,arity-n_overloads))
@@ -239,7 +241,7 @@ namespace boost { namespace python { namespace objects {
}else{
return str(
"%s(%s%s%s%s) -> %s"
% make_tuple
% boost::python::make_tuple // workaround, see top
( f->m_name
, str(",").join(formal_params.slice(0,arity-n_overloads))
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
@@ -251,7 +253,7 @@ namespace boost { namespace python { namespace objects {
return str(
"%s %s(%s%s%s%s) %s"
% make_tuple
% boost::python::make_tuple // workaround, see top
( cpp_types?ret_type:str("")
, f->m_name
, str(",").join(formal_params.slice(0,arity-n_overloads))

View File

@@ -10,7 +10,7 @@
#endif
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/reverse_graph.hpp>
#include <boost/property_map.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/bind.hpp>
#include <boost/integer_traits.hpp>
#include <boost/tuple/tuple.hpp>

View File

@@ -38,21 +38,21 @@ namespace {
}
object getinitargs = getattr(instance_obj, "__getinitargs__", none);
tuple initargs;
if (getinitargs.ptr() != none.ptr()) {
if (!getinitargs.is_none()) {
initargs = tuple(getinitargs());
}
result.append(initargs);
object getstate = getattr(instance_obj, "__getstate__", none);
object instance_dict = getattr(instance_obj, "__dict__", none);
long len_instance_dict = 0;
if (instance_dict.ptr() != none.ptr()) {
if (!instance_dict.is_none()) {
len_instance_dict = len(instance_dict);
}
if (getstate.ptr() != none.ptr()) {
if (!getstate.is_none()) {
if (len_instance_dict > 0) {
object getstate_manages_dict = getattr(
instance_obj, "__getstate_manages_dict__", none);
if (getstate_manages_dict.ptr() == none.ptr()) {
if (getstate_manages_dict.is_none()) {
PyErr_SetString(PyExc_RuntimeError,
"Incomplete pickle support"
" (__getstate_manages_dict__ not set)");

View File

@@ -43,7 +43,7 @@ namespace {
ssize_t str_size_as_py_ssize_t(std::size_t n)
{
if (n > ssize_t_max)
if (n > static_cast<std::size_t>(ssize_t_max))
{
throw std::range_error("str size > ssize_t_max");
}

View File

@@ -1,194 +0,0 @@
macro(bpl_test TESTNAME)
parse_arguments(BPL_TEST
"ARGS"
""
${ARGN})
# Determine the Python and C++ source files for this test
if (BPL_TEST_DEFAULT_ARGS)
# First argument is the Python source we will run, the rest are
# either extra Python sources we're dependent on or C++ files from
# which we will build extension modules.
car(BPL_TEST_PYSOURCE ${BPL_TEST_DEFAULT_ARGS})
cdr(BPL_TEST_DEFAULT_ARGS ${BPL_TEST_DEFAULT_ARGS})
get_filename_component(BPL_TEST_PYBASE ${BPL_TEST_PYSOURCE} NAME_WE)
foreach(SRC ${BPL_TEST_DEFAULT_ARGS})
get_filename_component(BPL_SRC_EXT ${SRC} EXT)
if (BPL_SRC_EXT STREQUAL ".cpp")
# Build a Python extension module from this source file
get_filename_component(BPL_SRC_NAME ${SRC} NAME_WE)
if(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}")
boost_python_extension(${BPL_SRC_NAME}_ext ${SRC})
else(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}")
boost_python_extension(${BPL_SRC_NAME} ${SRC})
endif(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}")
endif (BPL_SRC_EXT STREQUAL ".cpp")
endforeach(SRC ${BPL_TEST_DEFAULT_ARGS})
else (BPL_TEST_DEFAULT_ARGS)
set(BPL_TEST_PYSOURCE "${TESTNAME}.py")
# Build a Python extension module from this source file
boost_python_extension(${TESTNAME}_ext "${TESTNAME}.cpp")
endif(BPL_TEST_DEFAULT_ARGS)
# We'll need the full patch to run the Python test
set(BPL_TEST_PYSOURCE ${CMAKE_CURRENT_SOURCE_DIR}/${BPL_TEST_PYSOURCE})
# Run the test itself
file(TO_NATIVE_PATH "${LIBRARY_OUTPUT_PATH}" PYTHONPATH)
if(WIN32 AND NOT UNIX)
string(REPLACE "\\" "\\\\" PYTHONPATH "${PYTHONPATH}")
endif(WIN32 AND NOT UNIX)
add_test("${PROJECT_NAME}::${TESTNAME}"
${PYTHON_EXECUTABLE}
"${CMAKE_CURRENT_SOURCE_DIR}/pyrun.py"
"${PYTHONPATH}"
${BPL_TEST_PYSOURCE} ${BPL_TEST_ARGS})
endmacro(bpl_test)
macro(py_run TESTNAME)
boost_test_run(${TESTNAME}
${TESTNAME}.cpp
DEPENDS boost_python STATIC
LINK_LIBS ${PYTHON_LIBRARIES})
endmacro(py_run)
boost_test_run(exec
DEPENDS boost_python STATIC
ARGS "${CMAKE_CURRENT_SOURCE_DIR}/exec.py"
LINK_LIBS ${PYTHON_LIBRARIES})
boost_test_run(exec-dynamic
exec.cpp
ARGS "${CMAKE_CURRENT_SOURCE_DIR}/exec.py"
DEPENDS boost_python SHARED
LINK_LIBS ${PYTHON_LIBRARIES})
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(shared_ptr)
bpl_test(andreas_beyer)
bpl_test(polymorphism)
bpl_test(polymorphism2)
bpl_test(wrapper_held_type)
bpl_test(polymorphism2_auto_ptr)
bpl_test(auto_ptr)
bpl_test(minimal)
bpl_test(args)
bpl_test(raw_ctor)
bpl_test(numpy numpy.py printer.py numeric_tests.py numarray_tests.py numpy.cpp)
bpl_test(enum)
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_test.py keywords.cpp)
boost_python_extension(builtin_converters_ext test_builtin_converters.cpp)
bpl_test(builtin_converters test_builtin_converters.py builtin_converters_ext)
bpl_test(test_pointer_adoption)
bpl_test(operators)
bpl_test(callbacks)
bpl_test(defaults)
bpl_test(object)
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)
# TODO: 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(vector_indexing_suite)
bpl_test(pointer_vector)
# TODO: 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
boost_python_extension(map_indexing_suite_ext
map_indexing_suite.cpp int_map_indexing_suite.cpp a_map_indexing_suite.cpp)
bpl_test(map_indexing_suite
map_indexing_suite.py map_indexing_suite_ext)
# --- unit tests of library components ---
boost_test_compile(indirect_traits_test)
boost_test_run(destroy_test)
py_run(pointer_type_id_test)
py_run(bases)
boost_test_run(if_else)
py_run(pointee)
boost_test_run(result)
boost_test_compile(string_literal)
boost_test_compile(borrowed)
boost_test_compile(object_manager)
boost_test_compile(copy_ctor_mutates_rhs)
py_run(upcast)
boost_test_compile(select_holder)
boost_test_run(select_from_python_test
select_from_python_test.cpp ../src/converter/type_id.cpp
COMPILE_FLAGS "-DBOOST_PYTHON_STATIC_LIB"
LINK_LIBS ${PYTHON_LIBRARIES})
boost_test_compile(select_arg_to_python_test)
boost_test_compile_fail(raw_pyobject_fail1)
boost_test_compile_fail(raw_pyobject_fail2)
boost_test_compile_fail(as_to_python_function)
boost_test_compile_fail(object_fail1)

View File

@@ -37,6 +37,13 @@ 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
:
@@ -184,6 +191,9 @@ bpl-test crossmod_opaque
# 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 ]

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

@@ -22,6 +22,10 @@ struct foo
*kills++ = n;
}
int n;
// This used to cause compiler errors with MSVC 9.0.
foo& operator~();
foo& T();
};
void assert_destructions(int n)

View File

@@ -12,7 +12,7 @@
#endif
using namespace boost::python;
enum color { red = 1, green = 2, blue = 4 };
enum color { red = 1, green = 2, blue = 4, blood = 1 };
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
namespace boost // Pro7 has a hard time detecting enums
@@ -34,6 +34,7 @@ BOOST_PYTHON_MODULE(enum_ext)
.value("red", red)
.value("green", green)
.value("blue", blue)
.value("blood", blood)
.export_values()
;

View File

@@ -4,8 +4,8 @@
'''
>>> from enum_ext import *
>>> identity(color.red)
enum_ext.color.red
>>> identity(color.red) # in case of duplicated enums it always take the last enum
enum_ext.color.blood
>>> identity(color.green)
enum_ext.color.green
@@ -13,8 +13,8 @@ enum_ext.color.green
>>> identity(color.blue)
enum_ext.color.blue
>>> identity(color(1))
enum_ext.color.red
>>> identity(color(1)) # in case of duplicated enums it always take the last enum
enum_ext.color.blood
>>> identity(color(2))
enum_ext.color.green
@@ -28,7 +28,7 @@ enum_ext.color.blue
--- check export to scope ---
>>> identity(red)
enum_ext.color.red
enum_ext.color.blood
>>> identity(green)
enum_ext.color.green
@@ -42,10 +42,18 @@ enum_ext.color.blue
>>> c = colorized()
>>> c.x
enum_ext.color.red
enum_ext.color.blood
>>> c.x = green
>>> c.x
enum_ext.color.green
>>> red == blood
True
>>> red == green
False
>>> hash(red) == hash(blood)
True
>>> hash(red) == hash(green)
False
'''
# pickling of enums only works with Python 2.3 or higher

View File

@@ -59,13 +59,13 @@ void eval_test()
void exec_test()
{
// 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)
if (PyImport_AppendInittab(const_cast<char*>("embedded_hello"),
#if PY_VERSION_HEX >= 0x03000000
PyInit_embedded_hello
#else
initembedded_hello
#endif
) == -1)
throw std::runtime_error("Failed to add embedded_hello to the interpreter's "
"builtin modules");
// Retrieve the main module
@@ -114,49 +114,75 @@ void exec_test_error()
python::object result = python::exec("print(unknown) \n", global, global);
}
int main(int argc, char **argv)
void exercise_embedding_html()
{
BOOST_TEST(argc == 2);
std::string script = argv[1];
// Initialize the interpreter
Py_Initialize();
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__");
if (python::handle_exception(eval_test)
|| python::handle_exception(exec_test)
|| python::handle_exception(boost::bind(exec_file_test, script))
)
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_Occurred())
{
if (!pyerr_expected) {
BOOST_ERROR("Python Error detected");
PyErr_Print();
}
else
{
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception handler registered.");
}
}
if (python::handle_exception(exec_test_error))
{
if (PyErr_Occurred())
{
PyErr_Print();
}
else
{
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception handler registered.");
else {
PyErr_Clear();
}
}
else
{
BOOST_ERROR("Python exception expected, but not seen.");
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];
// 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();
// Py_Finalize();
return boost::report_errors();
}

View File

@@ -62,7 +62,7 @@ BOOST_PYTHON_MODULE(map_indexing_suite_ext)
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

@@ -40,8 +40,7 @@ namespace boost_python_test {
boost::python::tuple
getinitargs(const world& w)
{
using namespace boost::python;
return make_tuple(w.get_country());
return boost::python::make_tuple(w.get_country());
}
};

View File

@@ -52,16 +52,14 @@ namespace boost_python_test {
boost::python::tuple
getinitargs(const world& w)
{
using namespace boost::python;
return make_tuple(w.get_country());
return boost::python::make_tuple(w.get_country());
}
static
boost::python::tuple
getstate(const world& w)
{
using namespace boost::python;
return make_tuple(w.get_secret_number());
return boost::python::make_tuple(w.get_secret_number());
}
static
@@ -77,7 +75,7 @@ namespace boost_python_test {
);
throw_error_already_set();
}
long number = extract<long>(state[0]);
if (number != 42)
w.set_secret_number(number);

View File

@@ -25,10 +25,6 @@
#include <boost/python/extract.hpp>
#include <boost/python/back_reference.hpp>
#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
namespace boost_python_test {
// A friendly class.
@@ -53,18 +49,18 @@ namespace boost_python_test {
boost::python::tuple
getinitargs(const world& w)
{
using namespace boost::python;
return make_tuple(w.get_country());
return boost::python::make_tuple(w.get_country());
}
static
boost::python::tuple
getstate(boost::python::object w_obj)
{
using namespace boost::python;
world const& w = extract<world const&>(w_obj)();
world const& w = boost::python::extract<world const&>(w_obj)();
return make_tuple(w_obj.attr("__dict__"), w.get_secret_number());
return boost::python::make_tuple(
w_obj.attr("__dict__"),
w.get_secret_number());
}
static
@@ -73,7 +69,7 @@ namespace boost_python_test {
{
using namespace boost::python;
world& w = extract<world&>(w_obj)();
if (len(state) != 2)
{
PyErr_SetObject(PyExc_ValueError,
@@ -82,11 +78,11 @@ namespace boost_python_test {
);
throw_error_already_set();
}
// restore the object's __dict__
dict d = extract<dict>(w_obj.attr("__dict__"))();
d.update(state[0]);
// restore the internal state of the C++ object
long number = extract<long>(state[1]);
if (number != 42)

7
test/pyrun.py Normal file
View File

@@ -0,0 +1,7 @@
import sys
pythonpath = sys.argv[1]
scriptfile = sys.argv[2]
sys.argv = sys.argv[2:]
sys.path.append(pythonpath)
execfile(scriptfile)

View File

@@ -17,6 +17,10 @@ struct by_value
{
return x;
}
static int size(void)
{
return sizeof(T);
}
};
template <class T>
@@ -61,7 +65,17 @@ 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);

View File

@@ -4,12 +4,33 @@
r"""
>>> from builtin_converters_ext import *
# Provide values for integer converter tests
>>> def _signed_values(s):
... base = 2 ** (8 * s - 1)
... return [[-base, -1, 1, base - 1], [-base - 1, base]]
>>> def _unsigned_values(s):
... base = 2 ** (8 * s)
... return [[1, base - 1], [-1L, -1, base]]
# Wrappers to simplify tests
>>> def should_pass(method, values):
... result = map(method, values[0])
... if result != values[0]:
... print "Got %s but expected %s" % (result, values[0])
>>> def test_overflow(method, values):
... for v in values[1]:
... try: method(v)
... except OverflowError: pass
... else: print "OverflowError expected"
# Synthesize idendity functions in case long long not supported
>>> if not 'rewrap_value_long_long' in dir():
... def rewrap_value_long_long(x): return long(x)
... def rewrap_value_unsigned_long_long(x): return long(x)
... def rewrap_const_reference_long_long(x): return long(x)
... def rewrap_const_reference_unsigned_long_long(x): return long(x)
>>> if not 'long_long_size' in dir():
... def long_long_size(): return long_size()
>>> try: bool_exists = bool
... except: pass
@@ -62,15 +83,37 @@ True
True
show that we have range checking.
>>> try: rewrap_value_unsigned_short(-42)
... except OverflowError: pass
... else: print 'expected an OverflowError!'
>>> try: rewrap_value_int(sys.maxint * 2)
... except OverflowError: pass
... else: print 'expected an OverflowError!'
>>> should_pass(rewrap_value_signed_char, _signed_values(char_size()))
>>> should_pass(rewrap_value_short, _signed_values(short_size()))
>>> should_pass(rewrap_value_int, _signed_values(int_size()))
>>> should_pass(rewrap_value_long, _signed_values(long_size()))
>>> should_pass(rewrap_value_long_long, _signed_values(long_long_size()))
>>> should_pass(rewrap_value_unsigned_char, _unsigned_values(char_size()))
>>> should_pass(rewrap_value_unsigned_short, _unsigned_values(short_size()))
>>> should_pass(rewrap_value_unsigned_int, _unsigned_values(int_size()))
>>> should_pass(rewrap_value_unsigned_long, _unsigned_values(long_size()))
>>> should_pass(rewrap_value_unsigned_long_long,
... _unsigned_values(long_long_size()))
>>> test_overflow(rewrap_value_signed_char, _signed_values(char_size()))
>>> test_overflow(rewrap_value_short, _signed_values(short_size()))
>>> test_overflow(rewrap_value_int, _signed_values(int_size()))
>>> test_overflow(rewrap_value_long, _signed_values(long_size()))
>>> test_overflow(rewrap_value_long_long, _signed_values(long_long_size()))
>>> test_overflow(rewrap_value_unsigned_char, _unsigned_values(char_size()))
>>> test_overflow(rewrap_value_unsigned_short, _unsigned_values(short_size()))
>>> test_overflow(rewrap_value_unsigned_int, _unsigned_values(int_size()))
>>> test_overflow(rewrap_value_unsigned_long, _unsigned_values(long_size()))
# Exceptionally for PyLong_AsUnsignedLongLong(), a negative value raises
# TypeError on Python versions prior to 2.7
>>> for v in _unsigned_values(long_long_size())[1]:
... try: rewrap_value_unsigned_long_long(v)
... except (OverflowError, TypeError): pass
... else: print "OverflowError or TypeError expected"
>>> assert abs(rewrap_value_float(4.2) - 4.2) < .000001
>>> rewrap_value_double(4.2) - 4.2

View File

@@ -0,0 +1,53 @@
// Copyright Troy D. Straszheim 2009
// 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)
//
//
// example that shows problems with overloading and automatic conversion.
// if you call one of the below functions from python with bool/int/double,
// you'll see that the overload called is first match, not best match.
// See overload matching in luabind for an example of how to do this better.
//
// see this mail:
// http://mail.python.org/pipermail/cplusplus-sig/2009-March/014362.html
//
// This test isn't called by the cmake/jamfiles. For future use.
//
#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>
using boost::python::def;
using boost::python::handle;
using boost::python::object;
using boost::python::borrowed;
std::string takes_bool(bool b) { return "bool"; }
std::string takes_int(int b) { return "int"; }
std::string takes_double(double b) { return "double"; }
BOOST_PYTHON_MODULE(overload_resolution)
{
def("bid", takes_bool);
def("bid", takes_int);
def("bid", takes_double);
def("dib", takes_double);
def("dib", takes_int);
def("dib", takes_bool);
def("idb", takes_int);
def("idb", takes_double);
def("idb", takes_bool);
def("bdi", takes_bool);
def("bdi", takes_double);
def("bdi", takes_int);
}