mirror of
https://github.com/boostorg/python.git
synced 2026-01-22 17:32:55 +00:00
Compare commits
37 Commits
sandbox-br
...
boost-1.43
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e376cbbd95 | ||
|
|
86db60255a | ||
|
|
37b45d2baf | ||
|
|
471be524f4 | ||
|
|
e485244886 | ||
|
|
b9cd3ff109 | ||
|
|
d804f1250e | ||
|
|
89100353db | ||
|
|
46be73387c | ||
|
|
d685a5e8c5 | ||
|
|
e80224b1ad | ||
|
|
03fdf5b992 | ||
|
|
73b4cd3325 | ||
|
|
f7d31f6ead | ||
|
|
47bb3f55a7 | ||
|
|
6296bd5bc4 | ||
|
|
217250f078 | ||
|
|
29152af56c | ||
|
|
19846f5d79 | ||
|
|
a1924a2a72 | ||
|
|
c205cd86c6 | ||
|
|
8d86dc199c | ||
|
|
55e9ff14a1 | ||
|
|
4fea58f634 | ||
|
|
694ae13063 | ||
|
|
5168895803 | ||
|
|
c8bf94663c | ||
|
|
928a9389ce | ||
|
|
7d22435994 | ||
|
|
96dd880146 | ||
|
|
63f8e9f3d7 | ||
|
|
d9b4ada654 | ||
|
|
f5df393360 | ||
|
|
bf33b54638 | ||
|
|
87451007b9 | ||
|
|
2392a6a3e2 | ||
|
|
6c1e7decfa |
@@ -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)
|
||||
@@ -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) ; } }
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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 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 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 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
|
||||
|
||||
@@ -835,6 +835,8 @@ namespace boost { namespace python { namespace api
|
||||
object& operator=(object const&);
|
||||
|
||||
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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,7 +30,7 @@ struct value_destroyer<
|
||||
template <class T>
|
||||
static void execute(T const volatile* p)
|
||||
{
|
||||
p->T::~T();
|
||||
p->~T();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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<
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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*
|
||||
)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -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}"
|
||||
)
|
||||
@@ -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
|
||||
|
||||
46
src/exec.cpp
46
src/exec.cpp
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)");
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -184,6 +184,11 @@ bpl-test crossmod_opaque
|
||||
# bpl-test bienstman5 ;
|
||||
# }
|
||||
|
||||
# XXX disabled on release branch only,
|
||||
# XXX to avoid failures on platforms other than Windows
|
||||
# [ bpl-test calling_conventions ]
|
||||
# [ bpl-test calling_conventions_mf ]
|
||||
|
||||
# --- unit tests of library components ---
|
||||
|
||||
[ compile indirect_traits_test.cpp ]
|
||||
|
||||
158
test/calling_conventions.cpp
Normal file
158
test/calling_conventions.cpp
Normal 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)
|
||||
81
test/calling_conventions.py
Normal file
81
test/calling_conventions.py
Normal 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)
|
||||
159
test/calling_conventions_mf.cpp
Normal file
159
test/calling_conventions_mf.cpp
Normal 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)
|
||||
84
test/calling_conventions_mf.py
Normal file
84
test/calling_conventions_mf.py
Normal 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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
;
|
||||
|
||||
|
||||
20
test/enum.py
20
test/enum.py
@@ -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
|
||||
|
||||
100
test/exec.cpp
100
test/exec.cpp
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
7
test/pyrun.py
Normal 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)
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
53
test/test_overload_resolution.cpp
Normal file
53
test/test_overload_resolution.cpp
Normal 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user