2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-20 04:42:28 +00:00

Compare commits

..

8 Commits

Author SHA1 Message Date
Beman Dawes
37731fce5b Release 1.43.0 beta 1
[SVN r61461]
2010-04-21 14:13:35 +00:00
Ralf W. Grosse-Kunstleve
86db60255a libs/python/test/Jamfile.v2: disabling calling_conventions tests
[SVN r61034]
2010-04-04 05:23:15 +00:00
Ralf W. Grosse-Kunstleve
37b45d2baf merging current boost/python and libs/python from trunk into release branch
[SVN r61033]
2010-04-04 05:19:57 +00:00
Ralf W. Grosse-Kunstleve
471be524f4 boost.python: merging from trunk to release (gcc 4.4 -std=c++0x compatibility)
[SVN r57837]
2009-11-21 14:41:51 +00:00
Ralf W. Grosse-Kunstleve
e485244886 boost.python: merging from trunk to release (Troy Straszheim's fix for a long-standing bug)
[SVN r57621]
2009-11-13 00:40:01 +00:00
Troy D. Straszheim
b9cd3ff109 merge from trunk very minor fixes for ticket #2582
[SVN r57017]
2009-10-20 15:18:26 +00:00
Troy D. Straszheim
d804f1250e rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Ralf W. Grosse-Kunstleve
89100353db boost/python, libs/python: all changes from trunk merged into branches/release
[SVN r56806]
2009-10-13 22:37:59 +00:00
72 changed files with 1404 additions and 680 deletions

View File

@@ -1,72 +0,0 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
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})
boost_add_single_library(
${MODULE_NAME}
${BPL_EXT_DEFAULT_ARGS}
MODULE
LINK_LIBS ${PYTHON_LIBRARIES}
DEPENDS boost_python
SHARED
)
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,7 +3,9 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import os ;
import indirect ;
import modules ;
import feature ;
import python ;
@@ -22,73 +24,121 @@ if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
}
}
rule find-py3-version
{
local versions = [ feature.values python ] ;
local py3ver ;
for local v in $(versions)
{
if $(v) >= 3.0
{
py3ver = $(v) ;
}
}
return $(py3ver) ;
}
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) ; } }
lib boost_python
: # sources
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
rule lib_boost_python ( is-py3 ? )
{
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
: # requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<define>BOOST_PYTHON_SOURCE
# On Windows, all code using Python has to link to the Python
# import library.
#
# On *nix we never link libboost_python to libpython. When
# extending Python, all Python symbols are provided by the
# Python interpreter executable. When embedding Python, the
# client executable is expected to explicitly link to
# /python//python (the target representing libpython) itself.
#
# python_for_extensions is a target defined by Boost.Build to
# provide the Python include paths, and on Windows, the Python
# import library, as usage requirements.
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
# we prevent building when there is no python available
# as it's not possible anyway, and to cause dependents to
# fail to build
[ unless [ python.configured ] : <build>no ]
lib [ cond $(is-py3) : boost_python3 : boost_python ]
: # sources
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
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
: # requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<define>BOOST_PYTHON_SOURCE
# On Windows, all code using Python has to link to the Python
# import library.
#
# On *nix we never link libboost_python to libpython. When
# extending Python, all Python symbols are provided by the
# Python interpreter executable. When embedding Python, the
# client executable is expected to explicitly link to
# /python//python (the target representing libpython) itself.
#
# python_for_extensions is a target defined by Boost.Build to
# provide the Python include paths, and on Windows, the Python
# import library, as usage requirements.
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
# we prevent building when there is no python available
# as it's not possible anyway, and to cause dependents to
# fail to build
[ unless [ python.configured ] : <build>no ]
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
[ cond $(is-py3) : <python>$(py3-version) ]
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
}
lib_boost_python ;
boost-install boost_python ;
if $(py3-version)
{
lib_boost_python yes ;
boost-install boost_python3 ;
}

View File

@@ -32,7 +32,43 @@
<hr>
<dl class="page-index">
<dt>Current SVN</dt>
<dd>
<ul>
<li>Python 3 support:</li>
<ul>
<li>All the current Boost.Python test cases passed. Extension modules using
Boost.Python expected to support Python 3 smoothly.</li>
<li>Introduced <code>object.contains</code> where <code>x.contains(y)</code>
is equivalent to Python code <code>y in x</code>.
Now <code>dict.has_key</code> is just a wrapper of <code>object.contains</code>.
</li>
<li>When building against Python 3, <code>str.decode</code> will be removed.</li>
<li>When building against Python 3, the original signature of <code>list.sort</code>, which is:
<pre>void sort(object_cref cmpfunc);</pre>
will change to:
<pre>void sort(args_proxy const &args, kwds_proxy const &kwds);</pre>
This is because in Python 3 <code>list.sort</code> requires all its arguments be keyword arguments.
So you should call it like this:
<pre>x.sort(*tuple(), **dict(make_tuple(make_tuple("reverse", true))));</pre>
</li>
<li>According to <a href="http://www.python.org/dev/peps/pep-3123/">PEP 3123</a>,
when building Boost.Python against Python older than 2.6, the following macros will
be defined in Boost.Python header:
<pre>
# define Py_TYPE(o) (((PyObject*)(o))->ob_type)
# define Py_REFCNT(o) (((PyObject*)(o))->ob_refcnt)
# define Py_SIZE(o) (((PyVarObject*)(o))->ob_size)</pre>
So extension writers can use these macro directly, to make code clean and compatible with Python 3.
</li>
</ul>
</ul>
</dd>
<dt>1.39.0 Release</dt>
<dd>
<ul>

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

@@ -90,6 +90,14 @@ namespace detail
BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
// Specialize converters for signed and unsigned T to Python Int
#if PY_VERSION_HEX >= 0x03000000
# define BOOST_PYTHON_TO_INT(T) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyLong_FromLong(x), &PyLong_Type) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, ::PyLong_FromUnsignedLong(x), &PyLong_Type)
#else
# define BOOST_PYTHON_TO_INT(T) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x), &PyInt_Type) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
@@ -98,6 +106,7 @@ namespace detail
(std::numeric_limits<long>::max)()) \
? ::PyLong_FromUnsignedLong(x) \
: ::PyInt_FromLong(x), &PyInt_Type)
#endif
// Bool is not signed.
#if PY_VERSION_HEX >= 0x02030000
@@ -116,17 +125,24 @@ BOOST_PYTHON_TO_INT(long)
// using Python's macro instead of Boost's - we don't seem to get the
// config right all the time.
# ifdef HAVE_LONG_LONG
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyInt_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyInt_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyLong_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyLong_Type)
# endif
# undef BOOST_TO_PYTHON_INT
#if PY_VERSION_HEX >= 0x03000000
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyUnicode_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyUnicode_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyUnicode_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyUnicode_Type)
#else
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyString_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyString_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
#endif
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyUnicode_Type)
# endif
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x), &PyFloat_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x), &PyFloat_Type)

View File

@@ -34,7 +34,9 @@ struct pyobject_traits<PyObject>
// This is not an exhaustive list; should be expanded.
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Type);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(List);
#if PY_VERSION_HEX < 0x03000000
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Int);
#endif
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Long);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Dict);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Tuple);

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

@@ -47,7 +47,11 @@ enum operator_id
op_ixor,
op_ior,
op_complex,
#if PY_VERSION_HEX >= 0x03000000
op_bool,
#else
op_nonzero,
#endif
op_repr
};

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

@@ -175,6 +175,19 @@ typedef int pid_t;
( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
#endif
// Define Python 3 macros for Python 2.x
#if PY_VERSION_HEX < 0x02060000
# define Py_TYPE(o) (((PyObject*)(o))->ob_type)
# 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,
#endif
#ifdef __MWERKS__
# pragma warn_possunwant off
#elif _MSC_VER

View File

@@ -79,7 +79,11 @@ void* enum_<T>::convertible_from_python(PyObject* obj)
template <class T>
void enum_<T>::construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data)
{
#if PY_VERSION_HEX >= 0x03000000
T x = static_cast<T>(PyLong_AS_LONG(obj));
#else
T x = static_cast<T>(PyInt_AS_LONG(obj));
#endif
void* const storage = ((converter::rvalue_from_python_storage<T>*)data)->storage.bytes;
new (storage) T(x);
data->convertible = storage;

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
long 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
@@ -37,8 +37,12 @@ namespace detail
void reverse(); // reverse *IN PLACE*
void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1
#if PY_VERSION_HEX >= 0x03000000
void sort(args_proxy const &args,
kwds_proxy const &kwds);
#else
void sort(object_cref cmpfunc);
#endif
protected:
list_base(); // new list
@@ -113,13 +117,15 @@ class list : public detail::list_base
base::remove(object(value));
}
#if PY_VERSION_HEX <= 0x03000000
void sort() { base::sort(); }
template <class T>
void sort(T const& value)
{
base::sort(object(value));
}
#endif
public: // implementation detail -- for internal use only
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list, base)

View File

@@ -63,7 +63,7 @@ struct extract_member
{
static MemberType& execute(InstanceType& c)
{
(void)c.ob_type; // static assertion
(void)Py_TYPE(&c); // static assertion
return c.*member;
}
};
@@ -75,7 +75,7 @@ struct extract_identity
{
static InstanceType& execute(InstanceType& c)
{
(void)c.ob_type; // static assertion
(void)Py_TYPE(&c); // static assertion
return c;
}
};

View File

@@ -11,40 +11,49 @@
namespace boost { namespace python { namespace detail {
BOOST_PYTHON_DECL void init_module(char const* name, void(*)());
BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
}}}
# if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(BOOST_PYTHON_STATIC_MODULE)
# if PY_VERSION_HEX >= 0x03000000
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \
extern "C" __declspec(dllexport) void init##name() \
# define _BOOST_PYTHON_MODULE_INIT(name) \
PyObject* PyInit_##name() \
{ \
return boost::python::detail::init_module( \
#name,&init_module_##name); \
} \
void init_module_##name()
# else
# define _BOOST_PYTHON_MODULE_INIT(name) \
void init##name() \
{ \
boost::python::detail::init_module( \
#name,&init_module_##name); \
} \
void init_module_##name()
# endif
# if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(BOOST_PYTHON_STATIC_MODULE)
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \
extern "C" __declspec(dllexport) _BOOST_PYTHON_MODULE_INIT(name)
# elif BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \
extern "C" __attribute__ ((visibility("default"))) void init##name() \
{ \
boost::python::detail::init_module(#name, &init_module_##name); \
} \
void init_module_##name()
extern "C" __attribute__ ((visibility("default"))) _BOOST_PYTHON_MODULE_INIT(name)
# else
# define BOOST_PYTHON_MODULE_INIT(name) \
void init_module_##name(); \
extern "C" void init##name() \
{ \
boost::python::detail::init_module(#name, &init_module_##name); \
} \
void init_module_##name()
extern "C" _BOOST_PYTHON_MODULE_INIT(name)
# endif

View File

@@ -129,7 +129,11 @@ namespace detail
return class_<range_>(name, no_init)
.def("__iter__", identity_function())
.def(
#if PY_VERSION_HEX >= 0x03000000
"__next__"
#else
"next"
#endif
, make_function(
next_fn()
, policies

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);
@@ -43,7 +44,7 @@ struct make_instance_impl
// Note the position of the internally-stored Holder,
// for the sake of destruction
instance->ob_size = offsetof(instance_t, storage);
Py_SIZE(instance) = offsetof(instance_t, storage);
// Release ownership of the python object
protect.cancel();

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>
@@ -126,6 +128,10 @@ namespace api
const_object_objattribute attr(object const&) const;
object_objattribute attr(object const&);
// Wrap 'in' operator (aka. __contains__)
template <class T>
object contains(T const& key) const;
// item access
//
const_object_item operator[](object_cref) const;
@@ -235,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;
};
@@ -483,6 +491,15 @@ object api::object_operators<U>::operator()(detail::args_proxy const &args,
}
template <typename U>
template <class T>
object api::object_operators<U>::contains(T const& key) const
{
return this->attr("__contains__")(object(key));
}
inline object::object()
: object_base(python::incref(Py_None))
{}
@@ -526,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

@@ -121,8 +121,7 @@ opaque<Pointee> opaque<Pointee>::instance;
template <class Pointee>
PyTypeObject opaque<Pointee>::type_object =
{
PyObject_HEAD_INIT(0)
0,
PyVarObject_HEAD_INIT(NULL, 0)
0,
sizeof( BOOST_DEDUCED_TYPENAME opaque<Pointee>::python_instance ),
0,

View File

@@ -341,7 +341,11 @@ BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-)
BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+)
BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs)
BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~)
#if PY_VERSION_HEX >= 0x03000000
BOOST_PYTHON_UNARY_OPERATOR(bool, !!, operator!)
#else
BOOST_PYTHON_UNARY_OPERATOR(nonzero, !!, operator!)
#endif
BOOST_PYTHON_UNARY_OPERATOR(int, long, int_)
BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)

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

@@ -37,10 +37,12 @@ namespace detail
long count(object_cref sub, object_cref start, object_cref end) const;
#if PY_VERSION_HEX < 0x03000000
object decode() const;
object decode(object_cref encoding) const;
object decode(object_cref encoding, object_cref errors) const;
#endif
object encode() const;
object encode(object_cref encoding) const;
@@ -185,6 +187,7 @@ class str : public detail::str_base
return base::count(object(sub), object(start));
}
#if PY_VERSION_HEX < 0x03000000
object decode() const { return base::decode(); }
template<class T>
@@ -198,6 +201,7 @@ class str : public detail::str_base
{
return base::decode(object(encoding),object(errors));
}
#endif
object encode() const { return base::encode(); }
@@ -404,7 +408,11 @@ namespace converter
{
template <>
struct object_manager_traits<str>
#if PY_VERSION_HEX >= 0x03000000
: pytype_object_manager_traits<&PyUnicode_Type,str>
#else
: pytype_object_manager_traits<&PyString_Type,str>
#endif
{
};
}

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,70 +0,0 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
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

@@ -37,12 +37,20 @@ void shared_ptr_deleter::operator()(void const*)
namespace
{
// An lvalue conversion function which extracts a char const* from a
// Python String.
#if PY_VERSION_HEX < 0x03000000
void* convert_to_cstring(PyObject* obj)
{
return PyString_Check(obj) ? PyString_AsString(obj) : 0;
}
#else
void* convert_to_cstring(PyObject* obj)
{
return PyUnicode_Check(obj) ? _PyUnicode_AsString(obj) : 0;
}
#endif
// Given a target type and a SlotPolicy describing how to perform a
// given conversion, registers from_python converters which use the
@@ -90,6 +98,52 @@ namespace
}
};
// identity_unaryfunc/py_object_identity -- manufacture a unaryfunc
// "slot" which just returns its argument.
extern "C" PyObject* identity_unaryfunc(PyObject* x)
{
Py_INCREF(x);
return x;
}
unaryfunc py_object_identity = identity_unaryfunc;
#if PY_VERSION_HEX >= 0x03000000
// As in Python 3 there is only one integer type, we can have much
// simplified logic.
// XXX(bhy) maybe the code will work with 2.6 or even 2.5?
struct int_rvalue_from_python_base
{
static unaryfunc* get_slot(PyObject* obj)
{
return PyLong_Check(obj) ? &py_object_identity : 0;
}
static PyTypeObject const* get_pytype() {return &PyLong_Type;}
};
template <class T>
struct signed_int_rvalue_from_python : int_rvalue_from_python_base
{
static T extract(PyObject* intermediate)
{
long x = PyLong_AsLong(intermediate);
if (PyErr_Occurred())
throw_error_already_set();
return numeric_cast<T>(x);
}
};
template <class T>
struct unsigned_int_rvalue_from_python : int_rvalue_from_python_base
{
static T extract(PyObject* intermediate)
{
unsigned long x = PyLong_AsUnsignedLong(intermediate);
if (PyErr_Occurred())
throw_error_already_set();
return numeric_cast<T>(x);
}
};
#else // PY_VERSION_HEX >= 0x03000000
// A SlotPolicy for extracting signed integer types from Python objects
struct signed_int_rvalue_from_python_base
{
@@ -121,16 +175,7 @@ namespace
return numeric_cast<T>(x);
}
};
// identity_unaryfunc/py_object_identity -- manufacture a unaryfunc
// "slot" which just returns its argument.
extern "C" PyObject* identity_unaryfunc(PyObject* x)
{
Py_INCREF(x);
return x;
}
unaryfunc py_object_identity = identity_unaryfunc;
// A SlotPolicy for extracting unsigned integer types from Python objects
struct unsigned_int_rvalue_from_python_base
{
@@ -178,6 +223,7 @@ namespace
}
}
};
#endif // PY_VERSION_HEX >= 0x03000000
// Checking Python's macro instead of Boost's - we don't seem to get
// the config right all the time. Furthermore, Python's is defined
@@ -190,6 +236,9 @@ namespace
{
static unaryfunc* get_slot(PyObject* obj)
{
#if PY_VERSION_HEX >= 0x03000000
return PyLong_Check(obj) ? &py_object_identity : 0;
#else
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
if (number_methods == 0)
return 0;
@@ -202,19 +251,22 @@ namespace
return &number_methods->nb_long;
else
return 0;
#endif
}
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
static PyTypeObject const* get_pytype() { return &PyLong_Type;}
};
struct long_long_rvalue_from_python : long_long_rvalue_from_python_base
{
static BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate)
{
#if PY_VERSION_HEX < 0x03000000
if (PyInt_Check(intermediate))
{
return PyInt_AS_LONG(intermediate);
}
else
#endif
{
BOOST_PYTHON_LONG_LONG result = PyLong_AsLongLong(intermediate);
@@ -230,11 +282,13 @@ namespace
{
static unsigned BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate)
{
#if PY_VERSION_HEX < 0x03000000
if (PyInt_Check(intermediate))
{
return numeric_cast<unsigned BOOST_PYTHON_LONG_LONG>(PyInt_AS_LONG(intermediate));
}
else
#endif
{
unsigned BOOST_PYTHON_LONG_LONG result = PyLong_AsUnsignedLongLong(intermediate);
@@ -252,7 +306,9 @@ namespace
{
static unaryfunc* get_slot(PyObject* obj)
{
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
#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;
@@ -285,8 +341,10 @@ namespace
// For integer types, return the tp_int conversion slot to avoid
// creating a new object. We'll handle that below
#if PY_VERSION_HEX < 0x03000000
if (PyInt_Check(obj))
return &number_methods->nb_int;
#endif
return (PyLong_Check(obj) || PyFloat_Check(obj))
? &number_methods->nb_float : 0;
@@ -294,11 +352,13 @@ namespace
static double extract(PyObject* intermediate)
{
#if PY_VERSION_HEX < 0x03000000
if (PyInt_Check(intermediate))
{
return PyInt_AS_LONG(intermediate);
}
else
#endif
{
return PyFloat_AS_DOUBLE(intermediate);
}
@@ -306,22 +366,36 @@ namespace
static PyTypeObject const* get_pytype() { return &PyFloat_Type;}
};
unaryfunc py_unicode_as_string_unaryfunc = PyUnicode_AsUTF8String;
// A SlotPolicy for extracting C++ strings from Python objects.
struct string_rvalue_from_python
{
// If the underlying object is "string-able" this will succeed
static unaryfunc* get_slot(PyObject* obj)
{
return (PyString_Check(obj))
? &obj->ob_type->tp_str : 0;
#if PY_VERSION_HEX >= 0x03000000
return (PyUnicode_Check(obj)) ? &py_unicode_as_string_unaryfunc : 0;
#else
return (PyString_Check(obj)) ? &obj->ob_type->tp_str : 0;
#endif
};
// Remember that this will be used to construct the result object
#if PY_VERSION_HEX >= 0x03000000
static std::string extract(PyObject* intermediate)
{
return std::string(PyBytes_AsString(intermediate),PyBytes_Size(intermediate));
}
static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
#else
static std::string extract(PyObject* intermediate)
{
return std::string(PyString_AsString(intermediate),PyString_Size(intermediate));
}
static PyTypeObject const* get_pytype() { return &PyString_Type;}
#endif
};
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
@@ -341,7 +415,11 @@ namespace
{
return PyUnicode_Check(obj)
? &py_object_identity
#if PY_VERSION_HEX >= 0x03000000
: PyBytes_Check(obj)
#else
: PyString_Check(obj)
#endif
? &py_encode_string
: 0;
};
@@ -384,10 +462,12 @@ namespace
PyComplex_RealAsDouble(intermediate)
, PyComplex_ImagAsDouble(intermediate));
}
#if PY_VERSION_HEX < 0x03000000
else if (PyInt_Check(intermediate))
{
return PyInt_AS_LONG(intermediate);
}
#endif
else
{
return PyFloat_AS_DOUBLE(intermediate);
@@ -399,12 +479,20 @@ namespace
BOOST_PYTHON_DECL PyObject* do_return_to_python(char x)
{
#if PY_VERSION_HEX >= 0x03000000
return PyUnicode_FromStringAndSize(&x, 1);
#else
return PyString_FromStringAndSize(&x, 1);
#endif
}
BOOST_PYTHON_DECL PyObject* do_return_to_python(char const* x)
{
#if PY_VERSION_HEX >= 0x03000000
return x ? PyUnicode_FromString(x) : boost::python::detail::none();
#else
return x ? PyString_FromString(x) : boost::python::detail::none();
#endif
}
BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject* x)
@@ -459,13 +547,18 @@ void initialize_builtin_converters()
slot_rvalue_from_python<std::complex<long double>,complex_rvalue_from_python>();
// Add an lvalue converter for char which gets us char const*
#if PY_VERSION_HEX < 0x03000000
registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyString_Type>::get_pytype);
#else
registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyUnicode_Type>::get_pytype);
#endif
// Register by-value converters to std::string, std::wstring
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
slot_rvalue_from_python<std::wstring, wstring_rvalue_from_python>();
# endif
slot_rvalue_from_python<std::string, string_rvalue_from_python>();
}
}}} // namespace boost::python::converter

View File

@@ -96,7 +96,12 @@ BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
if (!data.convertible)
{
handle<> msg(
::PyString_FromFormat(
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromFormat
#else
::PyString_FromFormat
#endif
(
"No registered converter was able to produce a C++ rvalue of type %s from this Python object of type %s"
, converters.target_type.name()
, source->ob_type->tp_name
@@ -196,7 +201,12 @@ namespace
void throw_no_lvalue_from_python(PyObject* source, registration const& converters, char const* ref_type)
{
handle<> msg(
::PyString_FromFormat(
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromFormat
#else
::PyString_FromFormat
#endif
(
"No registered converter was able to extract a C++ %s to type %s"
" from this Python object of type %s"
, ref_type
@@ -218,7 +228,12 @@ namespace
if (source->ob_refcnt <= 1)
{
handle<> msg(
::PyString_FromFormat(
#if PY_VERSION_HEX >= 0x3000000
::PyUnicode_FromFormat
#else
::PyString_FromFormat
#endif
(
"Attempt to return dangling %s to object of type: %s"
, ref_type
, converters.target_type.name()));

View File

@@ -70,7 +70,12 @@ BOOST_PYTHON_DECL PyObject* registration::to_python(void const volatile* source)
if (this->m_to_python == 0)
{
handle<> msg(
::PyString_FromFormat(
#if PY_VERSION_HEX >= 0x3000000
::PyUnicode_FromFormat
#else
::PyString_FromFormat
#endif
(
"No to_python (by-value) converter found for C++ type: %s"
, this->target_type.name()
)

View File

@@ -84,7 +84,7 @@ object dict_base::get(object_cref k, object_cref d) const
bool dict_base::has_key(object_cref k) const
{
return extract<bool>(this->attr("has_key")(k));
return extract<bool>(this->contains(k));
}
list dict_base::items() const

View File

@@ -17,15 +17,14 @@ namespace python
object BOOST_PYTHON_DECL eval(str string, object global, object local)
{
// Set suitable default values for global and local dicts.
object none;
if (global.ptr() == none.ptr())
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.ptr() == none.ptr()) local = global;
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());
@@ -36,15 +35,14 @@ 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.
object none;
if (global.ptr() == none.ptr())
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.ptr() == none.ptr()) local = global;
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());
@@ -55,15 +53,14 @@ object BOOST_PYTHON_DECL exec(str string, object global, object local)
object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
{
// Set suitable default values for global and local dicts.
object none;
if (global.ptr() == none.ptr())
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.ptr() == none.ptr()) local = global;
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());
@@ -77,22 +74,29 @@ object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
{
// Set suitable default values for global and local dicts.
object none;
if (global.ptr() == none.ptr())
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.ptr() == none.ptr()) local = global;
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
// TODO(bhy) temporary workaround for Python 3.
// should figure out a way to avoid binary incompatibilities as the Python 2
// version did.
FILE *fs = fopen(f, "r");
#else
// Let python open the file to avoid potential binary incompatibilities.
PyObject *pyfile = PyFile_FromString(f, const_cast<char*>("r"));
if (!pyfile) throw std::invalid_argument(std::string(f) + " : no such file");
python::handle<> file(pyfile);
PyObject* result = PyRun_File(PyFile_AsFile(file.get()),
FILE *fs = PyFile_AsFile(file.get());
#endif
PyObject* result = PyRun_File(fs,
f,
Py_file_input,
global.ptr(), local.ptr());

View File

@@ -48,7 +48,11 @@ void list_base::extend(object_cref sequence)
long list_base::index(object_cref value) const
{
object result_obj(this->attr("index")(value));
#if PY_VERSION_HEX >= 0x03000000
ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
#else
long result = PyInt_AsLong(result_obj.ptr());
#endif
if (result == -1)
throw_error_already_set();
return result;
@@ -69,7 +73,11 @@ void list_base::insert(ssize_t index, object_cref item)
void list_base::insert(object const& index, object_cref x)
{
#if PY_VERSION_HEX >= 0x03000000
ssize_t index_ = PyLong_AsSsize_t(index.ptr());
#else
long index_ = PyInt_AsLong(index.ptr());
#endif
if (index_ == -1 && PyErr_Occurred())
throw_error_already_set();
this->insert(index_, x);
@@ -121,17 +129,29 @@ void list_base::sort()
}
}
#if PY_VERSION_HEX >= 0x03000000
void list_base::sort(args_proxy const &args,
kwds_proxy const &kwds)
{
this->attr("sort")(args, kwds);
}
#else
void list_base::sort(object_cref cmpfunc)
{
this->attr("sort")(cmpfunc);
}
#endif
// For some reason, moving this to the end of the TU suppresses an ICE
// with vc6.
long 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
ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
#else
long result = PyInt_AsLong(result_obj.ptr());
#endif
if (result == -1)
throw_error_already_set();
return result;

View File

@@ -24,11 +24,25 @@ namespace
PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } };
}
BOOST_PYTHON_DECL void init_module(char const* name, void(*init_function)())
BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*init_function)())
{
#if PY_VERSION_HEX >= 0x03000000
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
name,
0, /* m_doc */
-1, /* m_size */
initial_methods,
0, /* m_reload */
0, /* m_traverse */
0, /* m_clear */
0, /* m_free */
};
PyObject* m = PyModule_Create(&moduledef);
#else
PyObject* m
= Py_InitModule(const_cast<char*>(name), initial_methods);
#endif
if (m != 0)
{
@@ -38,6 +52,7 @@ BOOST_PYTHON_DECL void init_module(char const* name, void(*init_function)())
handle_exception(init_function);
}
return m;
}
}}} // namespace boost::python::detail

View File

@@ -67,8 +67,44 @@ extern "C"
PyObject *prop_set;
PyObject *prop_del;
PyObject *prop_doc;
int getter_doc;
} propertyobject;
// Copied from Python source and removed the part for setting docstring,
// since we don't have a setter for __doc__ and trying to set it will
// cause the init fail.
static int property_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
propertyobject *prop = (propertyobject *)self;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
kwlist, &get, &set, &del, &doc))
return -1;
if (get == Py_None)
get = NULL;
if (set == Py_None)
set = NULL;
if (del == Py_None)
del = NULL;
Py_XINCREF(get);
Py_XINCREF(set);
Py_XINCREF(del);
Py_XINCREF(doc);
prop->prop_get = get;
prop->prop_set = set;
prop->prop_del = del;
prop->prop_doc = doc;
prop->getter_doc = 0;
return 0;
}
static PyObject *
static_data_descr_get(PyObject *self, PyObject * /*obj*/, PyObject * /*type*/)
{
@@ -106,10 +142,9 @@ extern "C"
}
static PyTypeObject static_data_object = {
PyObject_HEAD_INIT(0)//&PyType_Type)
0,
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Boost.Python.StaticProperty"),
PyType_Type.tp_basicsize,
sizeof(propertyobject),
0,
0, /* tp_dealloc */
0, /* tp_print */
@@ -143,11 +178,11 @@ static PyTypeObject static_data_object = {
static_data_descr_get, /* tp_descr_get */
static_data_descr_set, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
property_init, /* tp_init */
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 */
@@ -160,17 +195,20 @@ static PyTypeObject static_data_object = {
namespace objects
{
#if PY_VERSION_HEX < 0x03000000
// XXX Not sure why this run into compiling error in Python 3
extern "C"
{
// This declaration needed due to broken Python 2.2 headers
extern DL_IMPORT(PyTypeObject) PyProperty_Type;
}
#endif
BOOST_PYTHON_DECL PyObject* static_data()
{
if (static_data_object.tp_dict == 0)
{
static_data_object.ob_type = &PyType_Type;
Py_TYPE(&static_data_object) = &PyType_Type;
static_data_object.tp_base = &PyProperty_Type;
if (PyType_Ready(&static_data_object))
return 0;
@@ -203,15 +241,14 @@ extern "C"
// If we found a static data descriptor, call it directly to
// force it to set the static data member
if (a != 0 && PyObject_IsInstance(a, objects::static_data()))
return a->ob_type->tp_descr_set(a, obj, value);
return Py_TYPE(a)->tp_descr_set(a, obj, value);
else
return PyType_Type.tp_setattro(obj, name, value);
}
}
static PyTypeObject class_metatype_object = {
PyObject_HEAD_INIT(0)//&PyType_Type)
0,
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Boost.Python.class"),
PyType_Type.tp_basicsize,
0,
@@ -266,7 +303,7 @@ static PyTypeObject class_metatype_object = {
// object.
void instance_holder::install(PyObject* self) throw()
{
assert(self->ob_type->ob_type == &class_metatype_object);
assert(Py_TYPE(Py_TYPE(self)) == &class_metatype_object);
m_next = ((objects::instance<>*)self)->objects;
((objects::instance<>*)self)->objects = this;
}
@@ -279,7 +316,7 @@ namespace objects
{
if (class_metatype_object.tp_dict == 0)
{
class_metatype_object.ob_type = &PyType_Type;
Py_TYPE(&class_metatype_object) = &PyType_Type;
class_metatype_object.tp_base = &PyType_Type;
if (PyType_Ready(&class_metatype_object))
return type_handle();
@@ -308,7 +345,7 @@ namespace objects
Py_XDECREF(kill_me->dict);
inst->ob_type->tp_free(inst);
Py_TYPE(inst)->tp_free(inst);
}
static PyObject *
@@ -318,7 +355,12 @@ namespace objects
PyObject* d = type_->tp_dict;
PyObject* instance_size_obj = PyObject_GetAttrString(d, const_cast<char*>("__instance_size__"));
long instance_size = instance_size_obj ? PyInt_AsLong(instance_size_obj) : 0;
ssize_t instance_size = instance_size_obj ?
#if PY_VERSION_HEX >= 0x03000000
PyLong_AsSsize_t(instance_size_obj) : 0;
#else
PyInt_AsLong(instance_size_obj) : 0;
#endif
if (instance_size < 0)
instance_size = 0;
@@ -332,7 +374,12 @@ namespace objects
// like, so we'll store the total size of the object
// there. A negative number indicates that the extra
// instance memory is not yet allocated to any holders.
result->ob_size = -(static_cast<int>(offsetof(instance<>,storage) + instance_size));
#if PY_VERSION_HEX >= 0x02060000
Py_SIZE(result) =
#else
result->ob_size =
#endif
-(static_cast<int>(offsetof(instance<>,storage) + instance_size));
}
return (PyObject*)result;
}
@@ -368,8 +415,7 @@ namespace objects
};
static PyTypeObject class_type_object = {
PyObject_HEAD_INIT(0) //&class_metatype_object)
0,
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Boost.Python.instance"),
offsetof(instance<>,storage), /* tp_basicsize */
1, /* tp_itemsize */
@@ -424,7 +470,7 @@ namespace objects
{
if (class_type_object.tp_dict == 0)
{
class_type_object.ob_type = incref(class_metatype().get());
Py_TYPE(&class_type_object) = incref(class_metatype().get());
class_type_object.tp_base = &PyBaseObject_Type;
if (PyType_Ready(&class_type_object))
return type_handle();
@@ -436,7 +482,7 @@ namespace objects
BOOST_PYTHON_DECL void*
find_instance_impl(PyObject* inst, type_info type, bool null_shared_ptr_only)
{
if (inst->ob_type->ob_type != &class_metatype_object)
if (Py_TYPE(Py_TYPE(inst)) != &class_metatype_object)
return 0;
instance<>* self = reinterpret_cast<instance<>*>(inst);
@@ -526,7 +572,7 @@ namespace objects
d["__doc__"] = doc;
object result = object(class_metatype())(name, bases, d);
assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type));
assert(PyType_IsSubtype(Py_TYPE(result.ptr()), &PyType_Type));
if (scope().ptr() != Py_None)
scope().attr(name) = result;
@@ -589,8 +635,9 @@ namespace objects
void class_base::add_static_property(char const* name, object const& fget)
{
object property(
(python::detail::new_reference)
PyObject_CallFunction(static_data(), const_cast<char*>("O"), fget.ptr()));
(python::detail::new_reference)
PyObject_CallFunction(static_data(), const_cast<char*>("O"), fget.ptr())
);
this->setattr(name, property);
}
@@ -650,7 +697,7 @@ namespace objects
::PyErr_Format(
PyExc_TypeError
, const_cast<char*>("staticmethod expects callable object; got an object of type %s, which is not callable")
, callable->ob_type->tp_name
, Py_TYPE(callable)->tp_name
);
throw_error_already_set();
@@ -680,18 +727,18 @@ namespace objects
void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size)
{
assert(self_->ob_type->ob_type == &class_metatype_object);
assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
objects::instance<>* self = (objects::instance<>*)self_;
int total_size_needed = holder_offset + holder_size;
if (-self->ob_size >= total_size_needed)
if (-Py_SIZE(self) >= total_size_needed)
{
// holder_offset should at least point into the variable-sized part
assert(holder_offset >= offsetof(objects::instance<>,storage));
// Record the fact that the storage is occupied, noting where it starts
self->ob_size = holder_offset;
Py_SIZE(self) = holder_offset;
return (char*)self + holder_offset;
}
else
@@ -705,9 +752,9 @@ void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std:
void instance_holder::deallocate(PyObject* self_, void* storage) throw()
{
assert(self_->ob_type->ob_type == &class_metatype_object);
assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
objects::instance<>* self = (objects::instance<>*)self_;
if (storage != (char*)self + self->ob_size)
if (storage != (char*)self + Py_SIZE(self))
{
PyMem_Free(storage);
}

View File

@@ -18,7 +18,11 @@ namespace boost { namespace python { namespace objects {
struct enum_object
{
#if PY_VERSION_HEX >= 0x03000000
PyLongObject base_object;
#else
PyIntObject base_object;
#endif
PyObject* name;
};
@@ -32,19 +36,32 @@ extern "C"
{
static PyObject* enum_repr(PyObject* self_)
{
const char *mod = PyString_AsString(PyObject_GetAttrString( self_, const_cast<char*>("__module__")));
// XXX(bhy) Potentional memory leak here since PyObject_GetAttrString returns a new reference
// const char *mod = PyString_AsString(PyObject_GetAttrString( self_, const_cast<char*>("__module__")));
PyObject *mod = PyObject_GetAttrString( self_, "__module__");
enum_object* self = downcast<enum_object>(self_);
if (!self->name)
{
return PyString_FromFormat("%s.%s(%ld)", mod, self_->ob_type->tp_name, PyInt_AS_LONG(self_));
return
#if PY_VERSION_HEX >= 0x03000000
PyUnicode_FromFormat("%S.%s(%ld)", mod, self_->ob_type->tp_name, PyLong_AsLong(self_));
#else
PyString_FromFormat("%s.%s(%ld)", PyString_AsString(mod), self_->ob_type->tp_name, PyInt_AS_LONG(self_));
#endif
}
else
{
char* name = PyString_AsString(self->name);
PyObject* name = self->name;
if (name == 0)
return 0;
return PyString_FromFormat("%s.%s.%s", mod, self_->ob_type->tp_name, name);
return
#if PY_VERSION_HEX >= 0x03000000
PyUnicode_FromFormat("%S.%s.%S", mod, self_->ob_type->tp_name, name);
#else
PyString_FromFormat("%s.%s.%s",
PyString_AsString(mod), self_->ob_type->tp_name, PyString_AsString(name));
#endif
}
}
@@ -53,7 +70,11 @@ extern "C"
enum_object* self = downcast<enum_object>(self_);
if (!self->name)
{
#if PY_VERSION_HEX >= 0x03000000
return PyLong_Type.tp_str(self_);
#else
return PyInt_Type.tp_str(self_);
#endif
}
else
{
@@ -63,8 +84,7 @@ extern "C"
}
static PyTypeObject enum_type_object = {
PyObject_HEAD_INIT(0) // &PyType_Type
0,
PyVarObject_HEAD_INIT(NULL, 0) // &PyType_Type
const_cast<char*>("Boost.Python.enum"),
sizeof(enum_object), /* tp_basicsize */
0, /* tp_itemsize */
@@ -84,7 +104,9 @@ static PyTypeObject enum_type_object = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT
#if PY_VERSION_HEX < 0x03000000
| Py_TPFLAGS_CHECKTYPES
#endif
| Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
@@ -125,8 +147,12 @@ namespace
{
if (enum_type_object.tp_dict == 0)
{
enum_type_object.ob_type = incref(&PyType_Type);
Py_TYPE(&enum_type_object) = incref(&PyType_Type);
#if PY_VERSION_HEX >= 0x03000000
enum_type_object.tp_base = &PyLong_Type;
#else
enum_type_object.tp_base = &PyInt_Type;
#endif
if (PyType_Ready(&enum_type_object))
throw_error_already_set();
}

View File

@@ -105,9 +105,9 @@ function::function(
}
PyObject* p = this;
if (function_type.ob_type == 0)
if (Py_TYPE(&function_type) == 0)
{
function_type.ob_type = &PyType_Type;
Py_TYPE(&function_type) = &PyType_Type;
::PyType_Ready(&function_type);
}
@@ -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<>();
@@ -435,9 +435,13 @@ void function::add_to_namespace(
function* new_func = downcast<function>(attribute.ptr());
PyObject* dict = 0;
#if PY_VERSION_HEX < 0x03000000
// Old-style class gone in Python 3
if (PyClass_Check(ns))
dict = ((PyClassObject*)ns)->cl_dict;
else if (PyType_Check(ns))
else
#endif
if (PyType_Check(ns))
dict = ((PyTypeObject*)ns)->tp_dict;
else
dict = PyObject_GetAttrString(ns, const_cast<char*>("__dict__"));
@@ -483,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(
@@ -595,9 +599,18 @@ extern "C"
static PyObject *
function_descr_get(PyObject *func, PyObject *obj, PyObject *type_)
{
#if PY_VERSION_HEX >= 0x03000000
// The implement is different in Python 3 because of the removal of unbound method
if (obj == Py_None || obj == NULL) {
Py_INCREF(func);
return func;
}
return PyMethod_New(func, obj);
#else
if (obj == Py_None)
obj = NULL;
return PyMethod_New(func, obj, type_);
#endif
}
static void
@@ -640,8 +653,12 @@ 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
return PyString_InternFromString("<unnamed Boost.Python function>");
#endif
else
return python::incref(f->name().ptr());
}
@@ -665,8 +682,7 @@ static PyGetSetDef function_getsetlist[] = {
};
PyTypeObject function_type = {
PyObject_HEAD_INIT(0)
0,
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Boost.Python.function"),
sizeof(function),
0,

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 {
@@ -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

@@ -36,8 +36,7 @@ extern "C"
}
PyTypeObject life_support_type = {
PyObject_HEAD_INIT(0)//(&PyType_Type)
0,
PyVarObject_HEAD_INIT(NULL, 0)//(&PyType_Type)
const_cast<char*>("Boost.Python.life_support"),
sizeof(life_support),
0,
@@ -92,9 +91,9 @@ PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient)
if (nurse == Py_None || nurse == patient)
return nurse;
if (life_support_type.ob_type == 0)
if (Py_TYPE(&life_support_type) == 0)
{
life_support_type.ob_type = &PyType_Type;
Py_TYPE(&life_support_type) = &PyType_Type;
PyType_Ready(&life_support_type);
}

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

@@ -38,7 +38,13 @@ BOOST_PYTHON_DECL object operator op(object const& l, object const& r) \
BOOST_PYTHON_BINARY_OPERATOR(+, Add)
BOOST_PYTHON_BINARY_OPERATOR(-, Subtract)
BOOST_PYTHON_BINARY_OPERATOR(*, Multiply)
#if PY_VERSION_HEX >= 0x03000000
// We choose FloorDivide instead of TrueDivide to keep the semantic
// conform with C/C++'s '/' operator
BOOST_PYTHON_BINARY_OPERATOR(/, FloorDivide)
#else
BOOST_PYTHON_BINARY_OPERATOR(/, Divide)
#endif
BOOST_PYTHON_BINARY_OPERATOR(%, Remainder)
BOOST_PYTHON_BINARY_OPERATOR(<<, Lshift)
BOOST_PYTHON_BINARY_OPERATOR(>>, Rshift)
@@ -58,7 +64,12 @@ BOOST_PYTHON_DECL object& operator op##=(object& l, object const& r) \
BOOST_PYTHON_INPLACE_OPERATOR(+, Add)
BOOST_PYTHON_INPLACE_OPERATOR(-, Subtract)
BOOST_PYTHON_INPLACE_OPERATOR(*, Multiply)
#if PY_VERSION_HEX >= 0x03000000
// Same reason as above for choosing FloorDivide instead of TrueDivide
BOOST_PYTHON_INPLACE_OPERATOR(/, FloorDivide)
#else
BOOST_PYTHON_INPLACE_OPERATOR(/, Divide)
#endif
BOOST_PYTHON_INPLACE_OPERATOR(%, Remainder)
BOOST_PYTHON_INPLACE_OPERATOR(<<, Lshift)
BOOST_PYTHON_INPLACE_OPERATOR(>>, Rshift)

View File

@@ -103,6 +103,7 @@ namespace // slicing code copied directly out of the Python implementation
static PyObject *
apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
{
#if PY_VERSION_HEX < 0x03000000
PyTypeObject *tp = u->ob_type;
PySequenceMethods *sq = tp->tp_as_sequence;
@@ -114,7 +115,9 @@ namespace // slicing code copied directly out of the Python implementation
return NULL;
return PySequence_GetSlice(u, ilow, ihigh);
}
else {
else
#endif
{
PyObject *slice = PySlice_New(v, w, NULL);
if (slice != NULL) {
PyObject *res = PyObject_GetItem(u, slice);
@@ -130,6 +133,7 @@ namespace // slicing code copied directly out of the Python implementation
assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
/* u[v:w] = x */
{
#if PY_VERSION_HEX < 0x03000000
PyTypeObject *tp = u->ob_type;
PySequenceMethods *sq = tp->tp_as_sequence;
@@ -144,7 +148,9 @@ namespace // slicing code copied directly out of the Python implementation
else
return PySequence_SetSlice(u, ilow, ihigh, x);
}
else {
else
#endif
{
PyObject *slice = PySlice_New(v, w, NULL);
if (slice != NULL) {
int res;

View File

@@ -10,16 +10,33 @@ namespace boost { namespace python { namespace detail {
detail::new_reference str_base::call(object const& arg_)
{
return (detail::new_reference)PyObject_CallFunction(
(PyObject*)&PyString_Type, const_cast<char*>("(O)"),
#if PY_VERSION_HEX >= 0x03000000
(PyObject*)&PyUnicode_Type,
#else
(PyObject*)&PyString_Type,
#endif
const_cast<char*>("(O)"),
arg_.ptr());
}
str_base::str_base()
: object(detail::new_reference(::PyString_FromString("")))
: object(detail::new_reference(
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromString("")
#else
::PyString_FromString("")
#endif
))
{}
str_base::str_base(const char* s)
: object(detail::new_reference(::PyString_FromString(s)))
: object(detail::new_reference(
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromString(s)
#else
::PyString_FromString(s)
#endif
))
{}
namespace {
@@ -38,9 +55,12 @@ namespace {
str_base::str_base(char const* start, char const* finish)
: object(
detail::new_reference(
::PyString_FromStringAndSize(
start, str_size_as_py_ssize_t(finish - start)
)
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromStringAndSize
#else
::PyString_FromStringAndSize
#endif
(start, str_size_as_py_ssize_t(finish - start))
)
)
{}
@@ -48,9 +68,12 @@ str_base::str_base(char const* start, char const* finish)
str_base::str_base(char const* start, std::size_t length) // new str
: object(
detail::new_reference(
::PyString_FromStringAndSize(
start, str_size_as_py_ssize_t(length)
)
#if PY_VERSION_HEX >= 0x03000000
::PyUnicode_FromStringAndSize
#else
::PyString_FromStringAndSize
#endif
( start, str_size_as_py_ssize_t(length) )
)
)
{}
@@ -92,6 +115,7 @@ long str_base::count(object_cref sub, object_cref start, object_cref end) const
return extract<long>(this->attr("count")(sub,start,end));
}
#if PY_VERSION_HEX < 0x03000000
object str_base::decode() const
{
return this->attr("decode")();
@@ -106,6 +130,7 @@ object str_base::decode(object_cref encoding, object_cref errors) const
{
return this->attr("decode")(encoding,errors);
}
#endif
object str_base::encode() const
{
@@ -122,9 +147,16 @@ object str_base::encode(object_cref encoding, object_cref errors) const
return this->attr("encode")(encoding,errors);
}
#if PY_VERSION_HEX >= 0x03000000
#define _BOOST_PYTHON_ASLONG PyLong_AsLong
#else
#define _BOOST_PYTHON_ASLONG PyInt_AsLong
#endif
bool str_base::endswith(object_cref suffix) const
{
bool result = PyInt_AsLong(this->attr("endswith")(suffix).ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("endswith")(suffix).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -135,7 +167,7 @@ BOOST_PYTHON_DEFINE_STR_METHOD(expandtabs, 1)
long str_base::find(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("find")(sub).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -143,7 +175,7 @@ long str_base::find(object_cref sub) const
long str_base::find(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("find")(sub,start).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -151,7 +183,7 @@ long str_base::find(object_cref sub, object_cref start) const
long str_base::find(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("find")(sub,start,end).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -159,7 +191,7 @@ long str_base::find(object_cref sub, object_cref start, object_cref end) const
long str_base::index(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("index")(sub).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -167,7 +199,7 @@ long str_base::index(object_cref sub) const
long str_base::index(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("index")(sub,start).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -175,7 +207,7 @@ long str_base::index(object_cref sub, object_cref start) const
long str_base::index(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("index")(sub,start,end).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -183,7 +215,7 @@ long str_base::index(object_cref sub, object_cref start, object_cref end) const
bool str_base::isalnum() const
{
bool result = PyInt_AsLong(this->attr("isalnum")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("isalnum")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -191,7 +223,7 @@ bool str_base::isalnum() const
bool str_base::isalpha() const
{
bool result = PyInt_AsLong(this->attr("isalpha")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("isalpha")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -199,7 +231,7 @@ bool str_base::isalpha() const
bool str_base::isdigit() const
{
bool result = PyInt_AsLong(this->attr("isdigit")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("isdigit")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -207,7 +239,7 @@ bool str_base::isdigit() const
bool str_base::islower() const
{
bool result = PyInt_AsLong(this->attr("islower")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("islower")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -215,7 +247,7 @@ bool str_base::islower() const
bool str_base::isspace() const
{
bool result = PyInt_AsLong(this->attr("isspace")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("isspace")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -223,7 +255,7 @@ bool str_base::isspace() const
bool str_base::istitle() const
{
bool result = PyInt_AsLong(this->attr("istitle")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("istitle")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -231,7 +263,7 @@ bool str_base::istitle() const
bool str_base::isupper() const
{
bool result = PyInt_AsLong(this->attr("isupper")().ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("isupper")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -246,7 +278,7 @@ BOOST_PYTHON_DEFINE_STR_METHOD(replace, 3)
long str_base::rfind(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("rfind")(sub).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -254,7 +286,7 @@ long str_base::rfind(object_cref sub) const
long str_base::rfind(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("rfind")(sub,start).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -262,7 +294,7 @@ long str_base::rfind(object_cref sub, object_cref start) const
long str_base::rfind(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("rfind")(sub,start,end).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -270,7 +302,7 @@ long str_base::rfind(object_cref sub, object_cref start, object_cref end) const
long str_base::rindex(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("rindex")(sub).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -278,7 +310,7 @@ long str_base::rindex(object_cref sub) const
long str_base::rindex(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("rindex")(sub,start).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -286,7 +318,7 @@ long str_base::rindex(object_cref sub, object_cref start) const
long str_base::rindex(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("rindex")(sub,start,end).ptr());
long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -322,7 +354,7 @@ list str_base::splitlines(object_cref keepends) const
bool str_base::startswith(object_cref prefix) const
{
bool result = PyInt_AsLong(this->attr("startswith")(prefix).ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -330,7 +362,7 @@ bool str_base::startswith(object_cref prefix) const
bool str_base::startswith(object_cref prefix, object_cref start) const
{
bool result = PyInt_AsLong(this->attr("startswith")(prefix,start).ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
@@ -338,12 +370,14 @@ bool str_base::startswith(object_cref prefix, object_cref start) const
bool str_base::startswith(object_cref prefix, object_cref start, object_cref end) const
{
bool result = PyInt_AsLong(this->attr("startswith")(prefix,start,end).ptr());
bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
#undef _BOOST_PYTHON_ASLONG
BOOST_PYTHON_DEFINE_STR_METHOD(strip, 0)
BOOST_PYTHON_DEFINE_STR_METHOD(swapcase, 0)
BOOST_PYTHON_DEFINE_STR_METHOD(title, 0)
@@ -357,7 +391,12 @@ static struct register_str_pytype_ptr
{
const_cast<converter::registration &>(
converter::registry::lookup(boost::python::type_id<boost::python::str>())
).m_class_object = &PyString_Type;
)
#if PY_VERSION_HEX >= 0x03000000
.m_class_object = &PyUnicode_Type;
#else
.m_class_object = &PyString_Type;
#endif
}
}register_str_pytype_ptr_;

View File

@@ -1,231 +0,0 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
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)
# Process all the .cpp file and extension module names
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}")
set(BPL_EXTENSION_MODULE ${BPL_SRC_NAME}_ext)
else(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}")
set(BPL_EXTENSION_MODULE ${BPL_SRC_NAME})
endif(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}")
boost_python_extension(${BPL_EXTENSION_MODULE} ${SRC})
else (BPL_SRC_EXT STREQUAL ".cpp")
set(BPL_EXTENSION_MODULE ${SRC})
endif (BPL_SRC_EXT STREQUAL ".cpp")
add_dependencies(${PROJECT_NAME}-test ${BPL_EXTENSION_MODULE})
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")
add_dependencies(${PROJECT_NAME}-test ${TESTNAME}_ext)
endif(BPL_TEST_DEFAULT_ARGS)
add_dependencies(${PROJECT_NAME}-test ${BPL_TEST_PYSOURCE})
# 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 "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" PYTHONPATH)
if(WIN32 AND NOT UNIX)
string(REPLACE "\\" "\\\\" PYTHONPATH "${PYTHONPATH}")
endif(WIN32 AND NOT UNIX)
set(FULL_TESTNAME ${PROJECT_NAME}-${TESTNAME})
add_test(${FULL_TESTNAME}
${PYTHON_EXECUTABLE}
"${CMAKE_CURRENT_SOURCE_DIR}/pyrun.py"
"${PYTHONPATH}"
${BPL_TEST_PYSOURCE} ${BPL_TEST_ARGS})
set_tests_properties(${FULL_TESTNAME}
PROPERTIES
LABELS "${PROJECT_NAME}"
)
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)
#
# See the contents of this file for more details on an existing
# overload resoluton bug.
#
# boost_python_extension(overload_resolution test_overload_resolution.cpp)
#
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

@@ -77,12 +77,15 @@ bpl-test crossmod_exception
[ bpl-test shared_ptr ]
[ bpl-test enable_shared_from_this ]
[ bpl-test andreas_beyer ]
[ bpl-test wrapper_held_type ]
[ bpl-test polymorphism2_auto_ptr
: polymorphism2_auto_ptr.py polymorphism2.py polymorphism2_auto_ptr.cpp
]
[ bpl-test polymorphism ]
[ bpl-test polymorphism2 ]
[ bpl-test wrapper_held_type ]
[ bpl-test polymorphism2_auto_ptr ]
[ bpl-test auto_ptr ]
[ bpl-test minimal ]
@@ -181,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 ]

View File

@@ -48,7 +48,11 @@ struct AFromPython
static void* convertible(PyObject* obj_ptr)
{
#if PY_VERSION_HEX >= 0x03000000
if (!PyLong_Check(obj_ptr)) return 0;
#else
if (!PyInt_Check(obj_ptr)) return 0;
#endif
return obj_ptr;
}
@@ -60,7 +64,11 @@ struct AFromPython
(boost::python::converter::rvalue_from_python_storage< A >*)
data)-> storage.bytes;
#if PY_VERSION_HEX >= 0x03000000
new (storage) A((int)PyLong_AsLong(obj_ptr));
#else
new (storage) A((int)PyInt_AsLong(obj_ptr));
#endif
data->convertible = storage;
}
};

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

@@ -1,4 +1,4 @@
# -*- coding: iso-latin-1 -*-
# -*- coding: latin-1 -*-
# Copyright Gottfried Ganßauge 2006.
# Distributed under the Boost Software License, Version 1.0. (See
# accompanying file LICENSE_1_0.txt or copy at

View File

@@ -2,13 +2,6 @@
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
"""
# Use builtin True/False when available:
>>> try:
... assert(True == 1)
... except:
... True = 1
... False = 0
>>> from defaults_ext import *
>>> bar(1)
'int(1); char(D); string(default); double(0.0); '

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

@@ -20,7 +20,7 @@
[(1, {'key2': 'value2'}), ('key1', 'value1')]
>>> print dict_from_sequence([(1,1),(2,2),(3,3)])
{1: 1, 2: 2, 3: 3}
>>> test_templates(printer)
>>> test_templates(printer) #doctest: +NORMALIZE_WHITESPACE
a test string
13
None

View File

@@ -59,7 +59,13 @@ void eval_test()
void exec_test()
{
// Register the module with the interpreter
if (PyImport_AppendInittab(const_cast<char*>("embedded_hello"), initembedded_hello) == -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
@@ -105,7 +111,7 @@ void exec_test_error()
{
// Execute a statement that raises a python exception.
python::dict global;
python::object result = python::exec("print unknown \n", global, global);
python::object result = python::exec("print(unknown) \n", global, global);
}
void exercise_embedding_html()

View File

@@ -2,5 +2,5 @@
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
print 'Hello World !'
number = 42
if 1:
number = 42

View File

@@ -53,7 +53,7 @@
>>> ll.push_back(x)
>>> x.push_back(7)
>>> ll.push_back(x)
>>> for a in ll:
>>> for a in ll: #doctest: +NORMALIZE_WHITESPACE
... for b in a:
... print b,
... print

View File

@@ -7,6 +7,8 @@
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/list.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/dict.hpp>
#include <boost/python/make_function.hpp>
#include <boost/lexical_cast.hpp>
#define BOOST_ENABLE_ASSERT_HANDLER
@@ -109,11 +111,16 @@ void exercise(list x, object y, object print)
print("sorted:");
x.pop(2); // make sorting predictable
x.pop(2); // remove [1,2] so the list is sortable in py3k
x.sort();
print(x);
print("reverse sorted:");
#if PY_VERSION_HEX >= 0x03000000
x.sort(*tuple(), **dict(make_tuple(make_tuple("reverse", true))));
#else
x.sort(&notcmp);
#endif
print(x);
list w;

View File

@@ -73,7 +73,7 @@ X(22)
...
>>> y = X(42)
>>> exercise(letters, y, printer)
>>> exercise(letters, y, printer) #doctest: +NORMALIZE_WHITESPACE
after append:
['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3)]
number of X(42) instances: 1
@@ -97,9 +97,9 @@ removing 666
reversing...
['y', 'x', X(3), [1, 2], '.', 'o', 'l', 'l', 'e', 'h']
sorted:
[[1, 2], '.', 'e', 'h', 'l', 'l', 'o', 'x', 'y']
['.', 'e', 'h', 'l', 'l', 'o', 'x', 'y']
reverse sorted:
['y', 'x', 'o', 'l', 'l', 'h', 'e', '.', [1, 2]]
['y', 'x', 'o', 'l', 'l', 'h', 'e', '.']
'''
def run(args = None):

View File

@@ -3,12 +3,12 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from long_ext import *
>>> new_long()
0L
>>> longify(42)
42L
>>> longify_string('300')
300L
>>> print new_long()
0
>>> print longify(42)
42
>>> print longify_string('300')
300
>>> is_long(20L)
'yes'
>>> is_long('20')

View File

@@ -32,8 +32,7 @@ struct NoddyObject : PyObject
};
PyTypeObject NoddyType = {
PyObject_HEAD_INIT(NULL)
0,
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Noddy"),
sizeof(NoddyObject),
0,
@@ -104,8 +103,7 @@ struct extract_simple_object
};
PyTypeObject SimpleType = {
PyObject_HEAD_INIT(NULL)
0,
PyVarObject_HEAD_INIT(NULL, 0)
const_cast<char*>("Simple"),
sizeof(SimpleObject),
0,

View File

@@ -13,6 +13,11 @@
#include <boost/python/return_value_policy.hpp>
#include "simple_type.hpp"
#if PY_VERSION_HEX >= 0x03000000
# define PyString_FromString PyUnicode_FromString
# define PyInt_FromLong PyLong_FromLong
#endif
// Get a simple (by value) from the argument, and return the
// string it holds.
PyObject* unwrap_simple(simple x)
@@ -52,6 +57,11 @@ PyObject* unwrap_int_const_ref(int const& x)
return PyInt_FromLong(x);
}
#if PY_VERSION_HEX >= 0x03000000
# undef PyString_FromString
# undef PyInt_FromLong
#endif
// rewrap<T> extracts a T from the argument, then converts the T back
// to a PyObject* and returns it.
template <class T>

View File

@@ -197,7 +197,7 @@ kiwi
>>> tm["kimpo"] = X("bbb")
>>> print_xmap(tm)
[ (joel, aaa) (kimpo, bbb) ]
>>> for el in tm:
>>> for el in tm: #doctest: +NORMALIZE_WHITESPACE
... print el.key(),
... dom = el.data()
joel kimpo

View File

@@ -1,4 +1,4 @@
# -*- coding: iso-latin-1 -*-
# -*- coding: latin-1 -*-
# Copyright Gottfried Ganßauge 2003..2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

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

@@ -29,7 +29,7 @@ r'''>>> import pickle2_ext
>>> wd.__dict__
{'x': 1}
>>> try: pstr = pickle.dumps(wd)
... except RuntimeError, err: print err[0]
... except RuntimeError, err: print err
...
Incomplete pickle support (__getstate_manages_dict__ not set)
'''

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)

View File

@@ -26,8 +26,13 @@ void work_with_string(object print)
print(data.capitalize());
print('[' + data.center(30) + ']');
print(data.count("t"));
#if PY_VERSION_HEX < 0x03000000
print(data.encode("utf-8"));
print(data.decode("utf-8"));
#else
print(data.encode("utf-8").attr("decode")("utf-8"));
print(data.encode("utf-8").attr("decode")("utf-8"));
#endif
BOOST_ASSERT(!data.endswith("xx"));
BOOST_ASSERT(!data.startswith("test"));

View File

@@ -7,7 +7,7 @@
... for x in args: print x,
... print
...
>>> work_with_string(printer)
>>> work_with_string(printer) #doctest: +NORMALIZE_WHITESPACE
['this', 'is', 'a', 'demo', 'string']
['this', 'is', 'a', 'demo string']
this<->is<->a<->demo<->string

View File

@@ -77,10 +77,10 @@ False
>>> hex(rewrap_value_unsigned_long(0x80000001L)).replace('L','')
'0x80000001'
>>> rewrap_value_long_long(42)
42L
>>> rewrap_value_unsigned_long_long(42)
42L
>>> rewrap_value_long_long(42) == 42
True
>>> rewrap_value_unsigned_long_long(42) == 42
True
show that we have range checking.
@@ -130,23 +130,13 @@ False
>>> rewrap_value_string('yo, wassup?')
'yo, wassup?'
>>> try:
... if unicode: pass
... except:
... print "u'yo, wassup?'"
... else:
... eval("rewrap_value_wstring(u'yo, wassup?')")
u'yo, wassup?'
>>> print rewrap_value_wstring(u'yo, wassup?')
yo, wassup?
test that overloading on unicode works:
>>> try:
... if unicode: pass
... except:
... print "u'yo, wassup?'"
... else:
... eval("rewrap_value_string(u'yo, wassup?')")
u'yo, wassup?'
>>> print rewrap_value_string(u'yo, wassup?')
yo, wassup?
wrap strings with embedded nulls:
@@ -198,10 +188,10 @@ u'yo, wassup?'
42
>>> rewrap_const_reference_unsigned_long(42)
42
>>> rewrap_const_reference_long_long(42)
42L
>>> rewrap_const_reference_unsigned_long_long(42)
42L
>>> rewrap_const_reference_long_long(42) == 42
True
>>> rewrap_const_reference_unsigned_long_long(42) == 42
True
>>> assert abs(rewrap_const_reference_float(4.2) - 4.2) < .000001

View File

@@ -11,7 +11,7 @@
('t', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g')
>>> t1 = convert_to_tuple("this is")
>>> t2 = (1,2,3,4)
>>> test_operators(t1,t2,printer)
>>> test_operators(t1,t2,printer) #doctest: +NORMALIZE_WHITESPACE
('t', 'h', 'i', 's', ' ', 'i', 's', 1, 2, 3, 4)
>>> make_tuple()
()

View File

@@ -13,7 +13,7 @@ int main()
{
PyTypeObject o;
Y y;
BOOST_TEST(&boost::python::upcast<PyObject>(&o)->ob_refcnt == &o.ob_refcnt);
BOOST_TEST(&boost::python::upcast<PyObject>(&y)->ob_refcnt == &y.ob_refcnt);
BOOST_TEST(&Py_REFCNT(boost::python::upcast<PyObject>(&o)) == &Py_REFCNT(&o));
BOOST_TEST(&Py_REFCNT(boost::python::upcast<PyObject>(&y)) == &Py_REFCNT(&y));
return boost::report_errors();
}