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

Compare commits

..

2 Commits

Author SHA1 Message Date
Peter Dimov
a858c2dc3c Add comments explaining the stage/install targets in build/Jamfile 2018-10-12 21:32:12 +03:00
Peter Dimov
11b9e3d4a7 Add empty stage/install targets when Python is not configured 2018-10-12 21:16:35 +03:00
35 changed files with 252 additions and 262 deletions

View File

@@ -4,6 +4,7 @@ environment:
# /E:ON and /V:ON options are not enabled in the batch script intepreter
# See: http://stackoverflow.com/a/13751649/163740
CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\ci\\run_with_env.cmd"
BOOST_PREFIX: C:\Libraries\boost_1_66_0
matrix:
@@ -11,28 +12,24 @@ environment:
# a later point release.
# See: http://www.appveyor.com/docs/installed-software#python
- PYTHON: C:\\Python36-x64
PYTHON_VERSION: 3.6.x
PYTHON_ARCH: 64
MSVC: 12.0
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x" # currently 2.7.9
PYTHON_ARCH: "32"
MSVC: "14.0"
ARCH: x86
- PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.x"
PYTHON_ARCH: "64"
MSVC: "12.0"
ARCH: x86_64
BOOST_PREFIX: C:\Libraries\boost_1_66_0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
PYTHON: C:\\Python36-x64
PYTHON_VERSION: 3.6.x
PYTHON_ARCH: 64
MSVC: 15.9.19
PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.x"
PYTHON_ARCH: "64"
MSVC: "14.13.26128"
ARCH: x86_64
BOOST_PREFIX: C:\Libraries\boost_1_69_0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
PYTHON: C:\\Python36-x64
PYTHON_VERSION: 3.6.x
PYTHON_ARCH: 64
MSVC: 16.7.4
ARCH: x86_64
BOOST_PREFIX: C:\Libraries\boost_1_73_0
install:
# If there is a newer build queued for the same PR, cancel this one.
@@ -67,33 +64,28 @@ install:
# Upgrade to the latest version of pip to avoid it displaying warnings
# about it being out of date.
- "python -m pip install --disable-pip-version-check --user --upgrade pip"
- "pip install --disable-pip-version-check --user --upgrade pip"
# Install the build dependencies of the project. If some dependencies contain
# compiled extensions and are not provided as pre-built wheel packages,
# pip will build them from source using the MSVC compiler matching the
# target Python version and architecture
- curl -LfsS -o vswhere.exe https://github.com/Microsoft/vswhere/releases/download/2.8.4/vswhere.exe
#- |
# curl -LfsS -o faber.tar.gz https://github.com/stefanseefeld/faber/archive/snapshot/2020-08-01.tar.gz
# tar xf faber.tar.gz
# CD faber-snapshot-2020-08-01
# python setup.py install
# CD ..
- python -m pip install faber
- |
curl -LfsS -o faber.tar.gz https://github.com/stefanseefeld/faber/archive/snapshot/2018-04-08.tar.gz
tar xf faber.tar.gz
CD faber-snapshot-2018-04-08
python setup.py install
CD ..
# report the available MSVC compilers
- faber --log=tools --info=tools cxx
- faber --info=tools cxx
- easy_install sphinx
- python -m pip install numpy
- set FARGS=--log=summary --log=output --log=actions --log=commands --with-boost-include=%BOOST_PREFIX% target.arch=%ARCH% cxx.name=msvc cxx.version=%MSVC%
- pip install numpy
build_script:
- faber %FARGS% config || type config.log
- faber %FARGS% -j8
- faber --with-boost-include=%BOOST_PREFIX% target.arch=%ARCH% msvc.version=%MSVC%
test_script:
- faber %FARGS% -j8 test.report
- faber --with-boost-include=%BOOST_PREFIX% test.report target.arch=%ARCH% msvc.version=%MSVC%
after_test:
# If tests are successful, create binary packages for the project.

View File

@@ -6,7 +6,8 @@
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
dist: bionic
sudo: required
dist: trusty
language: cpp
@@ -14,7 +15,7 @@ env:
global:
- secure: BRNUkxN3p8f+uYKWC3Hr0VPqZA0PxbWr1DJlcI4hbiZtzKhMCWjDmd9UW9CzzexqeOxpd+9s0G87qvOur+wMSVxugDxtTesZrh1czXHeSVxgQrYD783XJtQJ9aYypbChkiboRD6Xpmbq7itwMuHBJMFtCuDxMynpU1jWwkyTf2Y=
jobs:
matrix:
include:
- os: linux
env: CXX=g++ PYTHON=python CXXFLAGS=-std=c++98
@@ -28,27 +29,20 @@ jobs:
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++98
- os: linux
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++11
- os: linux
env: CXX=g++ PYTHON=pypy3 CXXFLAGS=-std=c++11
- os: osx
env: CXX=clang++ PYTHON=python CXXFLAGS=-std=c++11
- env: PYTHON=python DOC=1
allow_failures:
- os: linux
env: CXX=g++ PYTHON=pypy3 CXXFLAGS=-std=c++11
- os: osx
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- pypy
packages:
- gcc
- g++
- gcc-4.8
- g++-4.8
- clang
- pypy3-dev
- python3-pip
- python-numpy
- python-sphinx
- python3-dev
@@ -63,6 +57,12 @@ cache:
directories:
- $HOME/Boost
before_install:
# The Trusty image has several Python versions pre-installed compiled with
# conflicting UCS2 and UCS4 unicode. Modify the PATH to skip the TravisCI python.
# See https://github.com/travis-ci/travis-ci/issues/4948 for details.
- export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g")
install:
# Install our own version of Boost (the subset we need) as the system version is
# too old (for C++11 support).
@@ -83,14 +83,15 @@ install:
echo "using cached Boost prerequisites."
fi
# Install Faber, the build tool.
python3 -m pip install setuptools
python3 -m pip install faber
#date=2020-08-01
#wget https://github.com/stefanseefeld/faber/archive/snapshot/$date.tar.gz
#tar xf $date.tar.gz
#pushd faber-snapshot-$date
#sudo python3 setup.py install
#popd
date=2018-04-08
wget https://github.com/stefanseefeld/faber/archive/snapshot/$date.tar.gz
tar xf $date.tar.gz
pushd faber-snapshot-$date
#wget https://github.com/stefanseefeld/faber/archive/release/0.2.tar.gz
#tar xf 0.2.tar.gz
#pushd faber-release-0.2
sudo python setup.py install
popd
before_script:
- sed -e "s/\$PYTHON/$PYTHON/g" .ci/faber > ~/.faber
@@ -103,7 +104,7 @@ script:
if [ "$DOC" ]; then
BOOST_ROOT=$HOME/Boost faber --builddir=build doc.html
else
faber --with-boost-include=$HOME/Boost --builddir=build test.report cxx.name=$CXX cxxflags=$CXXFLAGS -j8
faber --with-boost-include=$HOME/Boost --builddir=build test.report cxx.name=$CXX cxxflags=$CXXFLAGS
fi
after_success:

68
Jamfile Normal file
View File

@@ -0,0 +1,68 @@
# Copyright (c) 2018 Stefan Seefeld
# All rights reserved.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
import option ;
import regex ;
import python ;
#
# The `version-suffix` rule really belongs into python.jam, and
# should be moved there. `split-version` is only duplicated here
# as a prerequisite. (See https://github.com/boostorg/build/pull/290)
#
# Validate the version string and extract the major/minor part we care about.
#
local rule split-version ( version )
{
local major-minor = [ MATCH "^([0-9]+)\.([0-9]+)(.*)$" : $(version) : 1 2 3 ] ;
if ! $(major-minor[2]) || $(major-minor[3])
{
ECHO "Warning: \"using python\" expects a two part (major, minor) version number; got" $(version) instead ;
# Add a zero to account for the missing digit if necessary.
major-minor += 0 ;
}
return $(major-minor[1]) $(major-minor[2]) ;
}
# Define a version suffix for libraries depending on Python.
# For example, Boost.Python built for Python 2.7 uses the suffix "27"
rule version-suffix ( version )
{
local major-minor = [ split-version $(version) ] ;
local suffix = $(major-minor:J="") ;
return $(suffix) ;
}
# Python build id (for Python libraries only).
python-id = [ option.get "python-buildid" ] ;
if $(python-id)
{
PYTHON_ID = [ regex.replace $(python-id) "[*\\/:.\"\']" _ ] ;
}
rule python-tag ( name : type ? : property-set )
{
local result = $(name) ;
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
{
local version = [ $(property-set).get <python> ] ;
local lib-suffix = [ version-suffix $(version) ] ;
result = $(result)$(lib-suffix) ;
}
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB && $(PYTHON_ID)
{
result = $(result)-$(PYTHON_ID) ;
}
# forward to the boost tagging rule
return [ tag $(result) : $(type) : $(property-set) ] ;
}

View File

@@ -30,6 +30,8 @@ else
;
}
if [ python.configured ]
{
project boost/python
: source-location ../src
;
@@ -93,7 +95,7 @@ lib boost_python
<dependency>config-warning
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@python-tag
<tag>@$(__name__).python-tag
<conditional>@python.require-py
: # default build
@@ -121,7 +123,7 @@ lib boost_numpy
<library>boost_python
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@python-tag
<tag>@$(__name__).python-tag
<conditional>@python.require-py
: # default build
@@ -140,16 +142,8 @@ lib boost_numpy
# `install` installs the two libraries and their dependencies and is similar
# to issuing `b2 --with-python install` from top level
if [ python.configured ]
{
if [ python.numpy ]
{
boost-install boost_python boost_numpy ;
}
else
{
boost-install boost_python ;
}
boost-install boost_python boost_numpy ;
}
else
{

View File

@@ -121,7 +121,7 @@ __jam__
file. Simply copy the file and tweak [^use-project boost] to where your
boost root directory is and you're OK.
The comments contained in the Jamroot file above should be sufficient
The comments contained in the Jamrules file above should be sufficient
to get you going.
[h2 Running bjam]

View File

@@ -75,8 +75,8 @@ checks = [cxx_checks.has_cxx11(features, define('HAS_CXX11')),
has_numpy(features)]
config = report('config', checks)
src = module('src', features=features|config.use)
test = module('test', features=features|config.use)
doc = module('doc', features=features|config.use)
src = module('src', features=config.use)
test = module('test', features=config.use)
doc = module('doc', features=config.use)
default = src.default

View File

@@ -60,7 +60,7 @@ call(PyObject* callable
)
{
PyObject* const result =
PyObject_CallFunction(
PyEval_CallFunction(
callable
, const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")")
BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil)
@@ -69,7 +69,7 @@ call(PyObject* callable
// This conversion *must not* be done in the same expression as
// the call, because, in the special case where the result is a
// reference a Python object which was created by converting a C++
// argument for passing to PyObject_CallFunction, its reference
// argument for passing to PyEval_CallFunction, its reference
// count will be 2 until the end of the full expression containing
// the conversion, and that interferes with dangling
// pointer/reference detection.

View File

@@ -69,7 +69,7 @@ call_method(PyObject* self, char const* name
// This conversion *must not* be done in the same expression as
// the call, because, in the special case where the result is a
// reference a Python object which was created by converting a C++
// argument for passing to PyObject_CallFunction, its reference
// argument for passing to PyEval_CallFunction, its reference
// count will be 2 until the end of the full expression containing
// the conversion, and that interferes with dangling
// pointer/reference detection.

View File

@@ -16,7 +16,7 @@ template <class T, class X1, class X2, class X3> class class_;
class def_visitor_access
{
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
|| BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends.
public:
@@ -52,7 +52,7 @@ class def_visitor
friend class def_visitor_access;
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
|| BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends.
public:

View File

@@ -109,23 +109,6 @@ struct converter_target_type <void_result_to_python >
return 0;
}
};
// Generation of ret moved from caller_arity<N>::impl::signature to here due to "feature" in MSVC 15.7.2 with /O2
// which left the ret uninitialized and caused segfaults in Python interpreter.
template<class Policies, class Sig> const signature_element* get_ret()
{
typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype;
typedef typename select_result_converter<Policies, rtype>::type result_converter;
static const signature_element ret = {
(is_void<rtype>::value ? "void" : type_id<rtype>().name())
, &detail::converter_target_type<result_converter>::get_pytype
, boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value
};
return &ret;
}
#endif
@@ -246,12 +229,16 @@ struct caller_arity<N>
{
const signature_element * sig = detail::signature<Sig>::elements();
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
// MSVC 15.7.2, when compiling to /O2 left the static const signature_element ret,
// originally defined here, uninitialized. This in turn led to SegFault in Python interpreter.
// Issue is resolved by moving the generation of ret to separate function in detail namespace (see above).
const signature_element * ret = detail::get_ret<Policies, Sig>();
py_func_sig_info res = {sig, ret };
typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype;
typedef typename select_result_converter<Policies, rtype>::type result_converter;
static const signature_element ret = {
(is_void<rtype>::value ? "void" : type_id<rtype>().name())
, &detail::converter_target_type<result_converter>::get_pytype
, boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value
};
py_func_sig_info res = {sig, &ret };
#else
py_func_sig_info res = {sig, sig };
#endif

View File

@@ -11,15 +11,13 @@
namespace boost { namespace python { namespace detail {
#if (!defined(_MSC_VER) || _MSC_VER >= 1915)
// If forward declared, msvc6.5 does not recognize them as inline.
// However, as of msvc14.15 (_MSC_VER 1915/Visual Studio 15.8.0) name lookup is now consistent with other compilers.
// forward declaration, required (at least) by Tru64 cxx V6.5-042 and msvc14.15
#ifndef _MSC_VER //if forward declared, msvc6.5 does not recognize them as inline
// forward declaration, required (at least) by Tru64 cxx V6.5-042
template <class Generator, class U>
inline typename Generator::result_type
unwind_type(U const& p, Generator* = 0);
// forward declaration, required (at least) by Tru64 cxx V6.5-042 and msvc14.15
// forward declaration, required (at least) by Tru64 cxx V6.5-042
template <class Generator, class U>
inline typename Generator::result_type
unwind_type(boost::type<U>*p = 0, Generator* = 0);
@@ -85,7 +83,7 @@ struct unwind_helper<false>
template <class Generator, class U>
inline typename Generator::result_type
#if (!defined(_MSC_VER) || _MSC_VER >= 1915)
#ifndef _MSC_VER
unwind_type(U const& p, Generator*)
#else
unwind_type(U const& p, Generator* = 0)
@@ -150,7 +148,7 @@ struct unwind_helper2<reference_to_pointer_>
// why bother?
template <class Generator, class U>
inline typename Generator::result_type
#if (!defined(_MSC_VER) || _MSC_VER >= 1915)
#ifndef _MSC_VER
unwind_type(boost::type<U>*, Generator*)
#else
unwind_type(boost::type<U>*p =0, Generator* =0)

View File

@@ -47,13 +47,6 @@
# endif
#endif
// pyconfig.h defines a macro with hypot name, what breaks libstdc++ math headers
// that Python.h tries to include afterwards.
#if defined(__MINGW32__)
# include <cmath>
# include <math.h>
#endif
# include <pyconfig.h>
# if defined(_SGI_COMPILER_VERSION) && _SGI_COMPILER_VERSION >= 740
# undef _POSIX_C_SOURCE
@@ -90,7 +83,6 @@
// than MSVC on Win32
//
#if defined(_WIN32) || defined(__CYGWIN__)
# if defined(__GNUC__) && defined(__CYGWIN__)
# if defined(__LP64__)
@@ -146,45 +138,19 @@ typedef int pid_t;
# undef hypot // undo the evil #define left by Python.
# elif defined(__BORLANDC__) && !defined(__clang__)
# elif defined(__BORLANDC__)
# undef HAVE_HYPOT
# define HAVE_HYPOT 1
# endif
#endif // _WIN32
#if defined(__GNUC__)
# if defined(__has_warning)
# define BOOST_PYTHON_GCC_HAS_WREGISTER __has_warning("-Wregister")
# else
# define BOOST_PYTHON_GCC_HAS_WREGISTER __GNUC__ >= 7
# endif
#else
# define BOOST_PYTHON_GCC_HAS_WREGISTER 0
#endif
// Python.h header uses `register` keyword until Python 3.4
#if BOOST_PYTHON_GCC_HAS_WREGISTER
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wregister"
#elif defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable : 5033) // 'register' is no longer a supported storage class
#endif
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 2 && PY_MICRO_VERSION < 2
# include <boost/python/detail/python22_fixed.h>
#else
# include <Python.h>
#endif
#if BOOST_PYTHON_GCC_HAS_WREGISTER
# pragma GCC diagnostic pop
#elif defined(_MSC_VER)
# pragma warning(pop)
#endif
#undef BOOST_PYTHON_GCC_HAS_WREGISTER
#ifdef BOOST_PYTHON_ULONG_MAX_UNDEFINED
# undef ULONG_MAX
# undef BOOST_PYTHON_ULONG_MAX_UNDEFINED

View File

@@ -73,7 +73,7 @@ class list : public detail::list_base
}
template <class T>
ssize_t count(T const& value) const
long count(T const& value) const
{
return base::count(object(value));
}

View File

@@ -24,8 +24,8 @@ namespace detail
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_base, object)
private:
static detail::new_reference call(object const&);
static detail::new_reference call(object const&, object const&);
static detail::new_non_null_reference call(object const&);
static detail::new_non_null_reference call(object const&, object const&);
};
}

View File

@@ -25,7 +25,7 @@
# include <boost/type.hpp>
# include <iterator>
# include <boost/detail/iterator.hpp>
namespace boost { namespace python { namespace objects {
@@ -42,7 +42,7 @@ struct iterator_range
{
iterator_range(object sequence, Iterator start, Iterator finish);
typedef std::iterator_traits<Iterator> traits_t;
typedef boost::detail::iterator_traits<Iterator> traits_t;
struct next
{

View File

@@ -97,7 +97,7 @@ class override : public object
operator()() const
{
detail::method_result x(
PyObject_CallFunction(
PyEval_CallFunction(
this->ptr()
, const_cast<char*>("()")
));
@@ -132,7 +132,7 @@ detail::method_result
operator()( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a) ) const
{
detail::method_result x(
PyObject_CallFunction(
PyEval_CallFunction(
this->ptr()
, const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")")
BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_fast_arg_to_python_get, nil)

View File

@@ -104,22 +104,14 @@ object BOOST_PYTHON_DECL exec_file(char const *filename, object global, object l
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *f = const_cast<char *>(filename);
#if PY_VERSION_HEX >= 0x03010000
// Let python manage any UTF bits to avoid potential incompatibilities.
PyObject *fo = Py_BuildValue("s", f);
PyObject *fb = Py_None;
PyUnicode_FSConverter(fo, &fb);
f = PyBytes_AsString(fb);
FILE *fs = fopen(f, "r");
Py_DECREF(fo);
Py_DECREF(fb);
#elif PY_VERSION_HEX >= 0x03000000
// Let python open the file to avoid potential binary incompatibilities.
#if PY_VERSION_HEX >= 0x03040000
FILE *fs = _Py_fopen(f, "r");
#elif PY_VERSION_HEX >= 0x03000000
PyObject *fo = Py_BuildValue("s", f);
FILE *fs = _Py_fopen(fo, "r"); // Private CPython API
FILE *fs = _Py_fopen(fo, "r");
Py_DECREF(fo);
#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);

View File

@@ -6,16 +6,16 @@
namespace boost { namespace python { namespace detail {
new_reference long_base::call(object const& arg_)
new_non_null_reference long_base::call(object const& arg_)
{
return (detail::new_reference)PyObject_CallFunction(
return (detail::new_non_null_reference)PyObject_CallFunction(
(PyObject*)&PyLong_Type, const_cast<char*>("(O)"),
arg_.ptr());
}
new_reference long_base::call(object const& arg_, object const& base)
new_non_null_reference long_base::call(object const& arg_, object const& base)
{
return (detail::new_reference)PyObject_CallFunction(
return (detail::new_non_null_reference)PyObject_CallFunction(
(PyObject*)&PyLong_Type, const_cast<char*>("(OO)"),
arg_.ptr(), base.ptr());
}

View File

@@ -444,9 +444,7 @@ void function::add_to_namespace(
if (dict == 0)
throw_error_already_set();
assert(!PyErr_Occurred());
handle<> existing(allow_null(::PyObject_GetItem(dict.get(), name.ptr())));
PyErr_Clear();
if (existing)
{
@@ -487,15 +485,16 @@ void function::add_to_namespace(
if (new_func->name().is_none())
new_func->m_name = name;
assert(!PyErr_Occurred());
handle<> name_space_name(
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>("__name__"))));
PyErr_Clear();
if (name_space_name)
new_func->m_namespace = object(name_space_name);
}
// The PyObject_GetAttrString() or PyObject_GetItem calls above may
// have left an active error
PyErr_Clear();
if (PyObject_SetAttr(ns, name.ptr(), attribute.ptr()) < 0)
throw_error_already_set();

View File

@@ -25,7 +25,7 @@ namespace detail
if (
PyMethod_Check(m.get())
&& PyMethod_GET_SELF(m.get()) == this->m_self
&& ((PyMethodObject*)m.get())->im_self == this->m_self
&& class_object->tp_dict != 0
)
{
@@ -34,7 +34,7 @@ namespace detail
}
if (borrowed_f != PyMethod_GET_FUNCTION(m.get()))
if (borrowed_f != ((PyMethodObject*)m.get())->im_func)
return override(m);
}
}

View File

@@ -1,19 +1,15 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
"""
>>> from args_ext import *
>>> args, kwargs = raw(3, 4, foo = 'bar', baz = 42)
>>> args
(3, 4)
>>> kwargs['foo']
'bar'
>>> kwargs['baz']
42
>>> raw(3, 4, foo = 'bar', baz = 42)
((3, 4), {'foo': 'bar', 'baz': 42})
Prove that we can handle empty keywords and non-keywords
>>> raw(3, 4)
((3, 4), {})
@@ -80,7 +76,7 @@
... else: print('expected an exception: unknown keyword')
Exercise member functions using default stubs
>>> q.f1(z = 'nix', y = .125, x = 2)
(2, 0.125, 'nix')
>>> q.f1(y = .125, x = 2)
@@ -127,16 +123,10 @@
1
>>> y = Y(value = 33)
>>> _, kwargs = y.raw(this = 1, that = 'the other')
>>> kwargs['this']
1
>>> kwargs['that']
'the other'
>>> y.raw(this = 1, that = 'the other')[1]
{'this': 1, 'that': 'the other'}
"""
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -153,3 +143,6 @@ if __name__ == '__main__':
import args_ext
help(args_ext)
sys.exit(status)

View File

@@ -21,13 +21,11 @@ object new_dict()
object data_dict()
{
dict tmp1;
tmp1["key1"] = "value1";
dict tmp2;
tmp2["key2"] = "value2";
tmp1[1] = tmp2;
tmp1["key1"] = "value1";
return tmp1;
}
@@ -62,20 +60,22 @@ void work_with_dict(dict data1, dict data2)
void test_templates(object print)
{
std::string key = "key";
dict tmp;
tmp[1.5] = 13;
print(tmp.get(1.5));
tmp[1] = "a test string";
print(tmp.get(1));
//print(tmp[1]);
tmp[1.5] = 13;
print(tmp.get(1.5));
print(tmp.get(44));
print(tmp);
print(tmp.get(2,"default"));
print(tmp.setdefault(3,"default"));
BOOST_ASSERT(!tmp.has_key(key));
//print(tmp[3]);
}
BOOST_PYTHON_MODULE(dict_ext)
{
def("new_dict", new_dict);

View File

@@ -1,6 +1,7 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
"""
>>> from dict_ext import *
>>> def printer(*args):
@@ -21,16 +22,14 @@
>>> print(dict_from_sequence([(1,1),(2,2),(3,3)]))
{1: 1, 2: 2, 3: 3}
>>> test_templates(printer) #doctest: +NORMALIZE_WHITESPACE
13
a test string
13
None
{1.5: 13, 1: 'a test string'}
default
default
"""
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -38,7 +37,7 @@ def run(args = None):
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print("running...")
import sys

View File

@@ -21,14 +21,14 @@ src = module('..src')
python_libs=python.instance().libs
features |= runpath(src.bpl.path, base='')
def extension_test(name, exts=[], script=None, numpy=False,
def extension_test(name, ext=[], script=None, np=False,
features=features, condition=None):
"""Create a Python extension test `name`.
Arguments:
* name: the name of the test.
* exts: extensions to be compiled, <name> if none are given.
* ext: extensions to be compiled, <name> if none are given.
* script: the test script to execute, <name>.py if none is given.
* numpy: if true, add boost_numpy to sources
* np: if true, add boost_numpy to sources
* features: pre-defined features
* condition: any condition under which to run the test
Return:
@@ -36,17 +36,17 @@ def extension_test(name, exts=[], script=None, numpy=False,
features=features.copy()
extensions = []
libs = [src.bnl, src.bpl] if numpy else [src.bpl]
for ext in exts or [name]:
if type(ext) is str: # build from a single source file
ext_name = ext if ext != name else ext + '_ext'
sources = [ext + '.cpp']
libs = [src.bnl, src.bpl] if np else [src.bpl]
for e in ext or [name]:
if type(e) is str: # build from a single source file
n = e if e != name else e + '_ext'
s = [e + '.cpp']
else: # build from a list of source files
ext_name = ext[0] if ext[0] != name else ext[0] + '_ext'
sources = [source + '.cpp' for source in ext]
ext = extension(ext_name, sources + libs, features=features)
features |= pythonpath(ext.path, base='')
extensions.append(ext)
n = e[0] if e[0] != name else e[0] + '_ext'
s = [n + '.cpp' for n in e]
e = extension(n, s + libs, features=features)
features |= pythonpath(e.path, base='')
extensions.append(e)
if not script:
script = name+'.py'
return test(name, script, run=python.run, dependencies=extensions,
@@ -123,9 +123,9 @@ tests.append(extension_test('auto_ptr',
import_ = binary('import_', ['import_.cpp', src.bpl], features=features|python_libs)
if platform.os == 'Windows':
command = """set PATH=$(runpath);%PATH%
$(>[0]) $(>[1])"""
$(>[1]) $(>[2])"""
else:
command = 'LD_LIBRARY_PATH=$(runpath) $(>[0]) $(>[1])'
command = 'LD_LIBRARY_PATH=$(runpath) $(>[1]) $(>[2])'
tests.append(test('import', [import_, 'import_.py'],
run=action('run', command),
@@ -167,7 +167,7 @@ for t in ['numpy/dtype',
'numpy/ndarray',
'numpy/indexing',
'numpy/shapes']:
tests.append(extension_test(t, numpy=True,
tests.append(extension_test(t, np=True,
condition=set.define.contains('HAS_NUMPY')))
default = report('report', tests, fail_on_failures=True)

View File

@@ -1,6 +1,7 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
'''
>>> from iterator_ext import *
>>> from input_iterator import *
@@ -24,7 +25,7 @@
Range2 wraps a transform_iterator which doubles the elements it
traverses. This proves we can wrap input iterators
>>> z2 = range2(x)
>>> for y in z2:
... print(y)
@@ -55,15 +56,12 @@
>>> ll.push_back(x)
>>> for a in ll: #doctest: +NORMALIZE_WHITESPACE
... for b in a:
... print(b, end=' ')
... print(b, end='')
... print('')
...
1 3 5
1 3 5 7
'''
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -71,7 +69,7 @@ def run(args = None):
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print("running...")
import sys

View File

@@ -1,6 +1,7 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
'''
>>> from list_ext import *
@@ -40,7 +41,7 @@ X(22)
['h', 'e', 'l', 'l', 'o', '.']
tuples do not automatically convert to lists when passed as arguments
>>> try: append_list(letters, (1,2))
... except TypeError: pass
... else: print('expected an exception')
@@ -50,7 +51,7 @@ X(22)
['h', 'e', 'l', 'l', 'o', '.', [1, 2]]
Check that subclass functions are properly called
>>> class mylist(list):
... def append(self, o):
... list.append(self, o)
@@ -102,8 +103,6 @@ reverse sorted:
['y', 'x', 'o', 'l', 'l', 'h', 'e', '.']
'''
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -111,7 +110,7 @@ def run(args = None):
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print("running...")
import sys

View File

@@ -1,6 +1,9 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import sys
if (sys.version_info.major >= 3):
long = int
'''
>>> from long_ext import *
>>> print(new_long())
@@ -17,10 +20,6 @@
>>> x = Y(long(4294967295))
'''
import sys
if (sys.version_info.major >= 3):
long = int
def run(args = None):
import sys
import doctest

View File

@@ -1,6 +1,7 @@
# Copyright Joel de Guzman 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
'''
#####################################################################
@@ -24,7 +25,7 @@ foo
# test that a string is implicitly convertible
# to an X
>>> x_value('bochi bochi')
>>> x_value('bochi bochi')
'gotya bochi bochi'
#####################################################################
@@ -32,9 +33,9 @@ foo
#####################################################################
>>> def print_xmap(xmap):
... s = '[ '
... for x in xmap:
... for x in xmap:
... s += repr(x)
... s += ' '
... s += ' '
... s += ']'
... print(s)
@@ -134,7 +135,7 @@ foo
>>> assert not 12345 in xm
#####################################################################
# Some references to the container elements
# Some references to the container elements
#####################################################################
>>> z0 = xm['joel']
@@ -155,7 +156,7 @@ banana
kiwi
#####################################################################
# Delete some container element
# Delete some container element
#####################################################################
>>> del xm['tenji']
@@ -167,7 +168,7 @@ kiwi
[ (joel, apple) (kim, kiwi) (mariel, grape) ]
#####################################################################
# Show that the references are still valid
# Show that the references are still valid
#####################################################################
>>> z0 # proxy
apple
@@ -198,7 +199,7 @@ kiwi
>>> print_xmap(tm)
[ (joel, aaa) (kimpo, bbb) ]
>>> for el in tm: #doctest: +NORMALIZE_WHITESPACE
... print(el.key(), end=' ')
... print(el.key(), end='')
... dom = el.data()
joel kimpo
@@ -215,12 +216,11 @@ joel kimpo
4
#####################################################################
# END....
# END....
#####################################################################
'''
from __future__ import print_function
def run(args = None):
import sys
@@ -236,3 +236,8 @@ if __name__ == '__main__':
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -1,6 +1,7 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
'''
>>> from object_ext import *
@@ -129,14 +130,14 @@
1
Slices
>>> assert check_string_slice()
Operators
>>> def print_args(*args, **kwds):
>>> def print_args(*args, **kwds):
... print(args, kwds)
>>> test_call(print_args, (0, 1, 2, 3), {'a':'A'})
>>> test_call(print_args, (0, 1, 2, 3), {'a':'A'})
(0, 1, 2, 3) {'a': 'A'}
@@ -148,7 +149,7 @@
Now make sure that object is actually managing reference counts
>>> import weakref
>>> class Z: pass
...
@@ -163,8 +164,6 @@
death
'''
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -172,7 +171,7 @@ def run(args = None):
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print("running...")
import sys

View File

@@ -1,6 +1,7 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
r'''>>> import pickle2_ext
>>> import pickle
>>> pickle2_ext.world.__module__
@@ -34,8 +35,6 @@ r'''>>> import pickle2_ext
Incomplete pickle support (__getstate_manages_dict__ not set)
'''
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -43,7 +42,7 @@ def run(args = None):
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print("running...")
import sys

View File

@@ -1,6 +1,7 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
r'''>>> import pickle3_ext
>>> import pickle
>>> pickle3_ext.world.__module__
@@ -29,8 +30,6 @@ r'''>>> import pickle3_ext
Hello from California! 0 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0
'''
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -38,7 +37,7 @@ def run(args = None):
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print("running...")
import sys

View File

@@ -1,10 +1,11 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
"""
>>> from str_ext import *
>>> def printer(*args):
... for x in args: print(x, end=' ')
... for x in args: print(x, end='')
... print('')
...
>>> work_with_string(printer) #doctest: +NORMALIZE_WHITESPACE
@@ -37,8 +38,6 @@ this is a blabla string
aaaaaaaaaaaaaaaaaaaaa
"""
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -46,7 +45,7 @@ def run(args = None):
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print("running...")
import sys

View File

@@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import sys
if (sys.version_info.major >= 3):
long = int
r"""
>>> from builtin_converters_ext import *
@@ -15,7 +17,7 @@ r"""
# Wrappers to simplify tests
>>> def should_pass(method, values):
... result = list(map(method, values[0]))
... result = map(method, values[0])
... if result != values[0]:
... print("Got %s but expected %s" % (result, values[0]))
>>> def test_overflow(method, values):
@@ -134,6 +136,9 @@ True
>>> print(rewrap_value_wstring(u'yo, wassup?'))
yo, wassup?
>>> print(rewrap_value_wstring(u'\U0001f4a9'))
\U0001f4a9
test that overloading on unicode works:
>>> print(rewrap_value_string(u'yo, wassup?'))

View File

@@ -4,17 +4,17 @@
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef TEST_CLASS_DWA2002326_HPP
# define TEST_CLASS_DWA2002326_HPP
# include <boost/assert.hpp>
# include <boost/detail/lightweight_test.hpp>
template <int n = 0>
struct test_class
{
explicit test_class(int x) : x(x), magic(7654321 + n) { ++counter; }
test_class(test_class const& rhs) : x(rhs.x), magic(7654321 + n) { ++counter; }
virtual ~test_class() { BOOST_ASSERT(magic == 7654321 + n); magic = 6666666; x = 9999; --counter; }
virtual ~test_class() { BOOST_TEST(magic == 7654321 + n); magic = 6666666; x = 9999; --counter; }
void set(int _x) { BOOST_ASSERT(magic == 7654321 + n); this->x = _x; }
int value() const { BOOST_ASSERT(magic == 7654321 + n); return x; }
void set(int _x) { BOOST_TEST(magic == 7654321 + n); this->x = _x; }
int value() const { BOOST_TEST(magic == 7654321 + n); return x; }
operator int() const { return x; }
static int count() { return counter; }

View File

@@ -1,6 +1,7 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
"""
>>> from tuple_ext import *
>>> def printer(*args):
@@ -21,8 +22,6 @@
('hello', 42)
"""
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -30,7 +29,7 @@ def run(args = None):
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print("running...")
import sys