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

Compare commits

...

126 Commits

Author SHA1 Message Date
Stefan Seefeld
3e4c518f4d Don't upgrade pip. 2025-10-25 15:49:37 -04:00
Eisuke Kawashima
2b6f667e98 chore: remove meaningless comparison 2025-10-25 15:23:44 -04:00
Eisuke Kawashima
aa458d2ca9 fix(test.properties): use doctest.ELLIPSIS for traceback
Since python 3.11 (PEP 657) traceback info is changed
fix #460
2025-10-25 15:22:21 -04:00
Eisuke Kawashima
16627261f1 fix(test.pickle): fix for change in the return value of object.__reduce__()
https://docs.python.org/3.11/library/pickle.html#object.__reduce__

fix #461
2025-10-25 14:14:07 -04:00
Stefan Seefeld
303299e677 log commands 2025-10-25 13:25:52 -04:00
Stefan Seefeld
cb95b611bb Downgrade run-vcpkg dependency to avoid regression. 2025-10-25 13:25:52 -04:00
Eisuke Kawashima
b4fb28e99a ci: update GitHub Actions 2025-10-23 22:14:55 -04:00
Stefan Seefeld
867f0dddfe Fix windows header path. 2025-10-23 22:08:00 -04:00
Aditya Pillai
a40bb656ee Use Py_REFCNT instead of ob_refcnt on Python 3.9 and above 2025-10-23 19:38:05 -04:00
Eisuke Kawashima
f604eb8d0f fix(test.numpy/ufunc): fix import error and value comparison 2025-04-02 08:21:09 -04:00
Eisuke Kawashima
d30c1bb7a8 refactor: switch to python 3 2025-03-31 21:58:42 -04:00
Aditya Pillai
3e7be69e1e Conditionally use Py_REFCNT 2025-03-10 15:10:12 -04:00
Aditya Pillai
cbdf1ce2a1 Use Py_REFCNT instead of ->ob_refcnt
Py_REFCNT was stabilized in 3.9, uses this official API instead of the
`ob_refcnt` field that doesn't exist in the free-threaded build of 3.13.
2025-03-10 15:10:12 -04:00
Stefan Seefeld
4fe3403584 Make sure to pass C++ version to preprocessor as well. 2025-02-01 22:55:02 -05:00
Stefan Seefeld
b1b43f1e1a Fix homebrew include path. 2025-02-01 22:55:02 -05:00
Peter Dimov
7b1960446b Merge pull request #470 from boostorg/pr/fix-iterator-detail
Replace use of boost/iterator/detail/enable_if.hpp
2025-02-01 19:35:16 +02:00
Peter Dimov
2dc5a92727 Replace use of boost/iterator/detail/enable_if.hpp 2025-01-28 02:27:49 +02:00
sdarwin
4fc3afa3ac Support newer version of Sphinx 2024-10-10 09:28:59 -04:00
Vitaly Buka
ff0ae9b29d dynamic_cast before destructor
Call to the destructor ends lifetime of the object, including vptr
used by dynamic_cast.
2024-09-22 12:30:12 -04:00
Daniel Laügt
b988d70207 Alignment fixes 2024-09-21 21:56:41 -04:00
Stefan Seefeld
b3a28d7033 Use the expected return type. 2024-09-18 21:09:05 -04:00
Stefan Seefeld
3ea0cb8501 Upgrade CI platforms. 2024-09-18 21:09:05 -04:00
Jakob van Santen
95e53011d8 Conditionalize nested test for py2
__qualname__ didn't exist before python 3.3. Skip checks that depend on it if running in earlier Python versions
2024-09-18 10:36:45 -04:00
Jakob van Santen
301256cf1e Avoid setting __doc__ on instance methods 2024-09-18 10:36:45 -04:00
Jakob van Santen
c76d67ef3f Ensure that virtual default implementation has the same kwargs as dispatcher 2024-09-17 17:07:44 -04:00
Jakob van Santen
0102b31945 Unwrap back_reference in get_pytype()
This prevents back_reference parameters from decaying to "object" in py signatures
2024-09-17 17:07:44 -04:00
Jakob van Santen
4c6f40fb82 Add generated docstrings to property fget/fset 2024-09-17 17:07:44 -04:00
Jakob van Santen
d1910f3d65 Avoid degrading slice to object in generated sig 2024-09-17 17:07:44 -04:00
Jakob van Santen
c4e3b13dc2 Use qualname for enum repr 2024-09-17 17:07:44 -04:00
Jakob van Santen
a498e2458c Qualify types defined in other modules 2024-09-17 17:07:44 -04:00
Jakob van Santen
7a3cc07042 Emit qualfied names in docstrings 2024-09-17 17:07:44 -04:00
Jakob van Santen
58b1a010bb Set __qualname__ for Python >= 3.3 2024-09-17 17:07:44 -04:00
Rene Rivera
8ca8724ad9 Update build deps. 2024-08-18 13:16:00 -04:00
Rene Rivera
5a8d096135 Split b2 dependencies into public and private. 2024-08-18 13:16:00 -04:00
Rene Rivera
30bdbf3ae2 Move inter-lib dependencies to a project variable and into the build targets. 2024-08-18 13:16:00 -04:00
Rene Rivera
5a07cdb96b Bump B2 require to 5.2 2024-08-18 13:16:00 -04:00
Rene Rivera
06fa956fe8 Add requires-b2 check to top-level build file. 2024-08-18 13:16:00 -04:00
Rene Rivera
9ab1742c46 Add missing NO_LIB usage requirements. 2024-08-18 13:16:00 -04:00
Rene Rivera
071b0bc964 Switch to library requirements instead of source. As source puts extra source in install targets. 2024-08-18 13:16:00 -04:00
Rene Rivera
d8d9861036 Put back removing qualified boostcpp tag. As we need it until the Jamroot removes the qualified tag. 2024-08-18 13:16:00 -04:00
Rene Rivera
f6d20e1099 Make the library modular usable. 2024-08-18 13:16:00 -04:00
Billy K. Poon
99a5352b5c Another fix for numpy 2.0
- Compare pointers directly instead of using PyArray_EquivTypes
2024-07-16 14:15:12 -04:00
Konstantin Podsvirov
1fed0824ad Fix typo in numpy tutorial 2024-07-01 15:29:32 -04:00
Alexis DUBURCQ
0474de0f6c Support numpy 2.0.0b1 2024-05-06 09:51:13 +02:00
Peter Dimov
6c3f3ecacf Normalize static/dynamic link macros and avoid redefinition warnings 2023-12-22 08:14:53 -05:00
Stefan Seefeld
47d5bc76f6 Revert "Remove obsolete Jamfile" 2022-09-05 21:43:23 -04:00
Stefan Seefeld
508da1d198 Fix windows CI builds. 2022-08-24 13:02:31 -04:00
Stefan Seefeld
271bcea8bf Don't attempt to deploy documentation from PRs. 2022-08-24 13:02:31 -04:00
Stefan Seefeld
fdd3e8b2c1 Remove obsolete Jamfile 2022-08-24 13:02:31 -04:00
Victor Stinner
a218babc8d Fix enum_type_object type on Python 3.11
The enum_type_object type inherits from PyLong_Type which is not tracked
by the GC. Instances doesn't have to be tracked by the GC: remove the
Py_TPFLAGS_HAVE_GC flag.

The Python C API documentation says:

    "To create a container type, the tp_flags field of the type object
    must include the Py_TPFLAGS_HAVE_GC and provide an implementation of
    the tp_traverse handler."

https://docs.python.org/dev/c-api/gcsupport.html

The new exception was introduced in Python 3.11 by:
https://github.com/python/cpython/issues/88429
2022-04-26 09:42:26 -04:00
Denis Arnaud
41e208ecb5 Update call_method.hpp
Was missing from https://github.com/boostorg/python/pull/320
I've tested it on one of my projects with (that patch on) Boost.Python/Boost 1.76.0 and it works well. Without that patch, there is a deprecation error.
2022-03-19 13:06:49 -04:00
Hajo Kirchhoff
f028aa4076 -fix: issue #239 exec_file does not close the FILE handle. Note: Using FILE* is a bad choice here because of possible exceptions, but Py_RunFile is a C function. This fix works, because Py_RunFile - as a C function - does not throw exceptions. 2021-08-10 12:25:40 -04:00
Hajo Kirchhoff
a060d43bf2 -fix: boost::python::exec_file completely broken when PY_VERSION_HEX >= 0x03010000. Bug: char* f pointed to a temporary buffer returned by PyBytes_AsString. This buffer was released when Py_DECREF(fb) was called. As a result, f pointed to invalid memory when being passed to Py_RunFile. 2021-08-10 12:25:40 -04:00
Stefan Seefeld
8dd1511773 Use the /python//numpy target instead of [ numpy.include ] (fixes #361) 2021-07-04 15:29:43 -04:00
Peter Dimov
909a4d1530 Merge branch 'master' into develop 2021-06-10 02:46:19 +03:00
TaWeiTu
aee2667407 Fix deprecated usage of <boost/bind.hpp>
Replace <boost/bind.hpp> with <boost/bind/bind.hpp> and use namespace
boost::placeholders when necessary.
2021-06-09 07:16:19 -04:00
Peter Dimov
209179fa09 Add CMakeLists.txt 2021-06-04 03:10:21 +03:00
Stefan Seefeld
5e77eabb63 Revert previous commit until 'Boost.Build' is ready. 2021-05-26 07:46:42 -04:00
Peter Dimov
ecda18f01e Use the /python//numpy target instead of [ numpy.include ] (fixes #361) 2021-05-24 18:54:56 -04:00
Stefan Seefeld
2a82afdf6d Upgrade base image & build prerequisites. 2021-04-30 22:59:25 -04:00
Stefan Seefeld
aca3c80c4f Respect alignment of by-value storage. 2021-04-30 22:59:25 -04:00
Stefan Seefeld
68fa9dccde Merge branch 'develop' 2021-03-04 11:57:23 -05:00
Dmitry Bely
f5d14ef15e Fix issue #280 2021-02-07 23:07:30 -05:00
Dmitry Bely
f7254f5d8a Add a test case for issue #280 2021-02-07 23:07:30 -05:00
Edward Diener
bffcb99ae7 [skip ci] Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries in order to specify the minumum C++ standard compilation level. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. 2021-01-21 07:25:16 -05:00
Victor Stinner
cbd2d9f033 Fix compatibility with Python 3.10.0a4: fopen
Replace private _Py_fopen() with public fopen(): private _Py_fopen()
function was removed in 3.10.0a4:
https://bugs.python.org/issue32381
2021-01-06 07:55:48 -05:00
Cedric Schmeits
0f1945060f noncopyable is located in the boost namespace 2021-01-04 01:35:25 -05:00
Cedric Schmeits
30dd3fe8b1 added includes for call_method.hpp and def.hpp 2021-01-04 01:35:25 -05:00
Stefan Seefeld
500194edb7 Fix Python 3.10 (PEP-620) incompatibility. 2021-01-04 01:31:40 -05:00
Stefan Seefeld
cd953cff06 Replace appveyor by github actions. 2021-01-04 00:21:07 -05:00
Stefan Seefeld
5e4f6278e0 Remove travis-ci logic. 2020-12-26 14:53:19 -05:00
Stefan Seefeld
108c93f7c3 Deploy documentation via github actions. 2020-12-26 14:53:19 -05:00
Stefan Seefeld
3dd6bcf39f Add OSX tests. 2020-12-26 14:53:19 -05:00
Tom Kent
97a8550a9f Using docker images to execut the github actions for testing (#335)
Introduce github action-based test workflow for Ubuntu.
2020-12-22 16:56:09 -05:00
Thomas Kent
c9521a8ef5 Updated VS2019 to 16.8.3 2020-12-22 16:53:56 -05:00
Thomas Kent
8328a4f535 New VS2019 version on appveyor 2020-12-13 14:14:29 -05:00
Stefan Seefeld
cc973263c4 Merge branch 'develop' 2020-11-02 00:58:26 -05:00
Pat Riehecky
f1320bf30b Add pypy3 to TravisCI matrix 2020-10-16 12:35:44 -04:00
Pat Riehecky
d9f06052e2 Convert Python 3.1+ to use public C API for filenames 2020-10-16 12:35:44 -04:00
Pat Riehecky
9ad5298d0b Use python macros to stay on public API for new pythons 2020-10-16 12:35:44 -04:00
Pat Riehecky
944fa075b3 Stop using deprecated API calls (python-3.9) #319 2020-10-15 21:54:47 -04:00
Stefan Seefeld
b4fbf1840b Fix appveyor builds. 2020-10-15 12:45:35 -04:00
Stefan Seefeld
ec402ea0d7 Merge branch 'develop' 2020-08-14 15:59:10 -04:00
David Seifert
60405cc48c Remove Boost.Python-specific python-tag code 2020-08-08 02:32:07 -04:00
Austin Maliszewski
9e1132f4f5 Handle NULL from call to PyLong_Type
PyLong_Type raises an exception if the argument is not convertible to
long, therefore, this has to be handled as new_reference and not
new_non_null_reference, otherwise a segfault will occur.
2020-08-08 02:30:46 -04:00
Tyler Kieft
bf824c1b98 Ensure all doctests run 2020-08-08 02:19:03 -04:00
Andrey Semashev
01ab510585 Removed usage of deprecated header boost/detail/iterator.hpp.
The header is deprecated in favor of <iterator>. It generates compiler
warnings and will be removed in a future release.
2020-08-07 18:09:31 -04:00
Edward Diener
5e2d55d801 Revert back to original, as __cdecl is fine with the Embarcadero C++ clang-based compilers. 2020-08-07 17:35:12 -04:00
Edward Diener
17886fc296 Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost config for the Embarcadero non-clang-based compilers. 2020-08-07 17:35:12 -04:00
Stefan Seefeld
15115eb1f8 Fix appveyor build failures. 2020-08-07 14:04:30 -04:00
Julien Schueller
1727b67a5a detail/caller.hpp:127:2: error: extra ';' [-Wpedantic] 2019-06-01 19:07:40 -04:00
Peter Dimov
0a9b687e9e Merge pull request #264 from boostorg/pr/fix-numpy-install
Only boost-install boost_numpy when it's being built
2019-04-17 15:08:15 -07:00
Peter Dimov
8c8b0dc215 Only boost-install boost_numpy when it's being built 2019-04-18 00:02:52 +03:00
Nikita Kniazev
fdc9ec760f Fixed module tests fail
Since recently lightweight_test introduced a sanitation to ensure that
`boost::report_errors()` is called, and it does not in module tests.

The problem could be fixed by exporting the function and calling it from
these python tests, but as it already done in other module tests I just
turned those usages lightweight_test to a regular assertation.
2019-03-31 20:36:56 -04:00
Stefan Seefeld
102acf1d34 Merge branch 'develop' 2019-03-29 09:41:46 -04:00
Nikita Kniazev
0b0c0536d6 The right hypot fix for MinGW 2019-03-26 15:56:03 -04:00
Owens
0d0cd711a7 Enable forward declaration of unwind_type() in msvc14.15 and later.
Name lookup in msvc has changed between 14.14 and 14.15 making it consistent with other compilers. Forward declaration of unwind_type() is now required as it is for other compilers.

Resolves compilation errors identified in:

https://github.com/boostorg/python/issues/228
2019-03-25 11:00:48 -04:00
Jonathan Wakely
72e254bf8b Fix name of file in tutorial
I think it's meant to refer to the Jamroot file being discussed, not Jamrules.
2019-03-23 20:38:29 -04:00
Nikita Kniazev
1f1b9b6aef Fix hypot issue on MinGW 2019-03-23 20:37:35 -04:00
Nikita Kniazev
6bd6d71850 Fix -Wregister error on Clang in C++17 mode
Suppresses the warning on GCC, Clang, and MSVC.
2019-03-21 16:40:41 -04:00
Stefan Seefeld
b9c0e58d57 Merge branch 'develop' 2019-03-05 21:39:52 -05:00
Tom Kent
4b01139720 Ssize t warning - trac #3353 (#21)
Fixes msvc unsafe type conversion warning - trac num: 3353
2019-03-03 22:02:57 -05:00
SPKorhonen
65bfec2d97 Fix static object initialization under Visual Studio 2017 (#208)
Fix static object initialization under VS 15.7.2
2019-03-03 21:59:48 -05:00
Orivej Desh
4f6d547c0a clear python exception after expected attribute lookup failure
Python 3.7.0 asserts that attribute lookup functions are called without outstanding exceptions:
https://github.com/python/cpython/blob/v3.7.0a2/Objects/typeobject.c#L3037
Motivation: https://bugs.python.org/issue34068#msg321262
Therefore the error set by the first PyObject_GetItem should be cleared before calling PyObject_GetAttrString.
2019-02-13 23:38:02 -05:00
Stefan Seefeld
90813b1ad7 Merge branch 'develop' 2019-01-10 18:45:39 -05:00
Peter Dimov
b644946368 Add comments explaining the stage/install targets in build/Jamfile 2018-10-12 14:34:15 -04:00
Peter Dimov
c7799aa44f Add empty stage/install targets when Python is not configured 2018-10-12 14:34:15 -04:00
Peter Dimov
02095af952 Use boost-install in build/Jamfile 2018-10-12 09:42:51 -04:00
Stefan Seefeld
6f72675bff Merge branch 'develop' 2018-07-11 19:25:10 -04:00
Moritz Wanzenböck
ed4776b59c Add missing return statement in numpy import
This adds a missing return statement in the python3 specific
import logic of boost.python.numpy.

For python3 wrap_import_array() needs to return a pointer value.
The import_array() macro only returns NULL in case of error. The
missing return statement is UB, so the compiler can assume it does
not happen. This means the compiler can assume the error branch
is always taken, so import_array must always fail.
2018-07-11 16:40:19 -04:00
Markus Gerstel
ac62db1cf1 Drop injector code example from tutorials.
This example depends on the behaviour of ```__metaclass__```. This has
changed in python 3, and the example no longer works. Removing example
code as suggested, see #210 for more details and possible alternatives.

Closes #210.
2018-06-08 14:59:41 -04:00
Stefan Seefeld
b4230e98f6 Fix auto-linking logic for boost_numpy (Windows only). 2018-06-04 09:34:00 -04:00
Stefan Seefeld
467a89eba7 Fix issue 198. 2018-05-06 13:35:16 -04:00
The Gitter Badger
28e2c6512c Add Gitter badge 2018-05-03 10:19:01 -04:00
Stefan Seefeld
b0f512c15a Merge branch 'develop' 2018-04-17 21:32:48 -04:00
Stefan Seefeld
77ff0d6bbc Fix CI OSX build failure. 2018-04-17 20:41:17 -04:00
Stefan Seefeld
24313709a7 Fix auto-linking logic (Windows only). 2018-04-12 23:39:22 -04:00
Stefan Seefeld
ac9fa536c8 Add OSX to CI test matrix. 2018-04-08 21:34:48 -04:00
Gaurav
7352c9c0f7 Remove not reachable condition.
Line no 138-139 suggest if condition satisfy if n_actual <=max_arity :
        if (n_actual + f->m_nkeyword_values >= min_arity
            && n_actual <= max_arity)
So condition at Line no 161 is not reachable.
2018-04-08 21:18:57 -04:00
Stefan Seefeld
26ac881b9d Fix CI links. 2018-04-08 20:41:51 -04:00
Stefan Seefeld
19f6c782aa Improve CI test coverage. 2018-04-08 18:21:22 -04:00
Stefan Seefeld
f3df1bf912 Remove redundant pragma once directives. 2018-04-07 17:05:18 -04:00
Stefan Seefeld
d515eb82c8 Fix build warning. 2018-03-15 15:29:06 -04:00
Stefan Seefeld
0021720a46 Conditionalize targets on Python configuration. 2018-03-11 10:31:21 -04:00
Stefan Seefeld
61591f7ad2 Enable more MSVC versions. 2018-03-09 13:17:24 -05:00
Stefan Seefeld
6b8ab7a5a3 Conditionalize tests. 2018-03-09 13:08:07 -05:00
111 changed files with 1314 additions and 1071 deletions

View File

@@ -1,104 +0,0 @@
environment:
global:
# SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
# /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_63_0
matrix:
# Pre-installed Python versions, which Appveyor may upgrade to
# a later point release.
# See: http://www.appveyor.com/docs/installed-software#python
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x" # currently 2.7.9
PYTHON_ARCH: "32"
MSVC: "14.0"
ARCH: x86
#- PYTHON: "C:\\Python27-x64"
# PYTHON_VERSION: "2.7.x" # currently 2.7.9
# PYTHON_ARCH: "64"
# ARCH: "x86_64"
#- PYTHON: "C:\\Python35"
# PYTHON_VERSION: "3.5.x" # currently 3.4.3
# PYTHON_ARCH: "32"
- PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.x"
PYTHON_ARCH: "64"
MSVC: "12.0"
ARCH: x86_64
install:
# If there is a newer build queued for the same PR, cancel this one.
# The AppVeyor 'rollout builds' option is supposed to serve the same
# purpose but it is problematic because it tends to cancel builds pushed
# directly to master instead of just PR builds (or the converse).
# credits: JuliaLang developers.
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
throw "There are newer queued builds for this pull request, failing early." }
- ECHO "Filesystem root:"
- ps: "ls \"C:/\""
- ECHO "Installed libraries:"
- ps: "ls \"C:/Libraries/\""
- ECHO "Installed SDKs:"
- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
# Install Python (from the official .msi of http://python.org) and pip when
# not already installed.
- ps: if (-not(Test-Path($env:PYTHON))) { & .ci\install.ps1 }
# Prepend newly installed Python to the PATH of this build (this cannot be
# done from inside the powershell script as it would require to restart
# the parent CMD process).
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
# Check that we have the expected version and architecture for Python
- "python --version"
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
# Upgrade to the latest version of pip to avoid it displaying warnings
# about it being out of date.
- "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 faber.tar.gz https://github.com/stefanseefeld/faber/archive/snapshot/2018-03-07.tar.gz
tar xf faber.tar.gz
CD faber-snapshot-2018-03-07
python setup.py install
CD ..
# report the available MSVC compilers
- python -m faber.tools.msvc
- easy_install sphinx
- pip install numpy
build_script:
- faber --with-boost-include=%BOOST_PREFIX% target.arch=%ARCH% msvc.version=%MSVC%
test_script:
- 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.
#- "%CMD_IN_ENV% python setup.py bdist_wheel"
#- "%CMD_IN_ENV% python setup.py bdist_wininst"
#- "%CMD_IN_ENV% python setup.py bdist_msi"
#- ps: "ls dist"
#artifacts:
# Archive the generated packages in the ci.appveyor.com build report.
#- path: dist\*
#on_success:
# - TODO: upload the content of dist/*.whl to a public wheelhouse
#

View File

@@ -1,3 +1,7 @@
# -*- python -*-
from faber.tools.boost import boostbook
from faber.tools.python import python
bb = boostbook(prefix='/usr/share/boostbook')
p = python(command='$PYTHON')

View File

@@ -1,229 +0,0 @@
# Sample script to install Python and pip under Windows
# Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer
# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
$MINICONDA_URL = "http://repo.continuum.io/miniconda/"
$BASE_URL = "https://www.python.org/ftp/python/"
$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
$GET_PIP_PATH = "C:\get-pip.py"
$PYTHON_PRERELEASE_REGEX = @"
(?x)
(?<major>\d+)
\.
(?<minor>\d+)
\.
(?<micro>\d+)
(?<prerelease>[a-z]{1,2}\d+)
"@
function Download ($filename, $url) {
$webclient = New-Object System.Net.WebClient
$basedir = $pwd.Path + "\"
$filepath = $basedir + $filename
if (Test-Path $filename) {
Write-Host "Reusing" $filepath
return $filepath
}
# Download and retry up to 3 times in case of network transient errors.
Write-Host "Downloading" $filename "from" $url
$retry_attempts = 2
for ($i = 0; $i -lt $retry_attempts; $i++) {
try {
$webclient.DownloadFile($url, $filepath)
break
}
Catch [Exception]{
Start-Sleep 1
}
}
if (Test-Path $filepath) {
Write-Host "File saved at" $filepath
} else {
# Retry once to get the error message if any at the last try
$webclient.DownloadFile($url, $filepath)
}
return $filepath
}
function ParsePythonVersion ($python_version) {
if ($python_version -match $PYTHON_PRERELEASE_REGEX) {
return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro,
$matches.prerelease)
}
$version_obj = [version]$python_version
return ($version_obj.major, $version_obj.minor, $version_obj.build, "")
}
function DownloadPython ($python_version, $platform_suffix) {
$major, $minor, $micro, $prerelease = ParsePythonVersion $python_version
if (($major -le 2 -and $micro -eq 0) `
-or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) `
) {
$dir = "$major.$minor"
$python_version = "$major.$minor$prerelease"
} else {
$dir = "$major.$minor.$micro"
}
if ($prerelease) {
if (($major -le 2) `
-or ($major -eq 3 -and $minor -eq 1) `
-or ($major -eq 3 -and $minor -eq 2) `
-or ($major -eq 3 -and $minor -eq 3) `
) {
$dir = "$dir/prev"
}
}
if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) {
$ext = "msi"
if ($platform_suffix) {
$platform_suffix = ".$platform_suffix"
}
} else {
$ext = "exe"
if ($platform_suffix) {
$platform_suffix = "-$platform_suffix"
}
}
$filename = "python-$python_version$platform_suffix.$ext"
$url = "$BASE_URL$dir/$filename"
$filepath = Download $filename $url
return $filepath
}
function InstallPython ($python_version, $architecture, $python_home) {
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
if (Test-Path $python_home) {
Write-Host $python_home "already exists, skipping."
return $false
}
if ($architecture -eq "32") {
$platform_suffix = ""
} else {
$platform_suffix = "amd64"
}
$installer_path = DownloadPython $python_version $platform_suffix
$installer_ext = [System.IO.Path]::GetExtension($installer_path)
Write-Host "Installing $installer_path to $python_home"
$install_log = $python_home + ".log"
if ($installer_ext -eq '.msi') {
InstallPythonMSI $installer_path $python_home $install_log
} else {
InstallPythonEXE $installer_path $python_home $install_log
}
if (Test-Path $python_home) {
Write-Host "Python $python_version ($architecture) installation complete"
} else {
Write-Host "Failed to install Python in $python_home"
Get-Content -Path $install_log
Exit 1
}
}
function InstallPythonEXE ($exepath, $python_home, $install_log) {
$install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home"
RunCommand $exepath $install_args
}
function InstallPythonMSI ($msipath, $python_home, $install_log) {
$install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home"
$uninstall_args = "/qn /x $msipath"
RunCommand "msiexec.exe" $install_args
if (-not(Test-Path $python_home)) {
Write-Host "Python seems to be installed else-where, reinstalling."
RunCommand "msiexec.exe" $uninstall_args
RunCommand "msiexec.exe" $install_args
}
}
function RunCommand ($command, $command_args) {
Write-Host $command $command_args
Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru
}
function InstallPip ($python_home) {
$pip_path = $python_home + "\Scripts\pip.exe"
$python_path = $python_home + "\python.exe"
if (-not(Test-Path $pip_path)) {
Write-Host "Installing pip..."
$webclient = New-Object System.Net.WebClient
$webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
Write-Host "Executing:" $python_path $GET_PIP_PATH
& $python_path $GET_PIP_PATH
} else {
Write-Host "pip already installed."
}
}
function DownloadMiniconda ($python_version, $platform_suffix) {
if ($python_version -eq "3.4") {
$filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe"
} else {
$filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe"
}
$url = $MINICONDA_URL + $filename
$filepath = Download $filename $url
return $filepath
}
function InstallMiniconda ($python_version, $architecture, $python_home) {
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
if (Test-Path $python_home) {
Write-Host $python_home "already exists, skipping."
return $false
}
if ($architecture -eq "32") {
$platform_suffix = "x86"
} else {
$platform_suffix = "x86_64"
}
$filepath = DownloadMiniconda $python_version $platform_suffix
Write-Host "Installing" $filepath "to" $python_home
$install_log = $python_home + ".log"
$args = "/S /D=$python_home"
Write-Host $filepath $args
Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
if (Test-Path $python_home) {
Write-Host "Python $python_version ($architecture) installation complete"
} else {
Write-Host "Failed to install Python in $python_home"
Get-Content -Path $install_log
Exit 1
}
}
function InstallMinicondaPip ($python_home) {
$pip_path = $python_home + "\Scripts\pip.exe"
$conda_path = $python_home + "\Scripts\conda.exe"
if (-not(Test-Path $pip_path)) {
Write-Host "Installing pip..."
$args = "install --yes pip"
Write-Host $conda_path $args
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
} else {
Write-Host "pip already installed."
}
}
function main () {
InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
InstallPip $env:PYTHON
}
main

View File

@@ -1,88 +0,0 @@
:: To build extensions for 64 bit Python 3, we need to configure environment
:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
::
:: To build extensions for 64 bit Python 2, we need to configure environment
:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
::
:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific
:: environment configurations.
::
:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
:: cmd interpreter, at least for (SDK v7.0)
::
:: More details at:
:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
:: http://stackoverflow.com/a/13751649/163740
::
:: Author: Olivier Grisel
:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
::
:: Notes about batch files for Python people:
::
:: Quotes in values are literally part of the values:
:: SET FOO="bar"
:: FOO is now five characters long: " b a r "
:: If you don't want quotes, don't include them on the right-hand side.
::
:: The CALL lines at the end of this file look redundant, but if you move them
:: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y
:: case, I don't know why.
@ECHO OFF
SET COMMAND_TO_RUN=%*
SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf
:: Extract the major and minor versions, and allow for the minor version to be
:: more than 9. This requires the version number to have two dots in it.
SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1%
IF "%PYTHON_VERSION:~3,1%" == "." (
SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1%
) ELSE (
SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2%
)
:: Based on the Python version, determine what SDK version to use, and whether
:: to set the SDK for 64-bit.
IF %MAJOR_PYTHON_VERSION% == 2 (
SET WINDOWS_SDK_VERSION="v7.0"
SET SET_SDK_64=Y
) ELSE (
IF %MAJOR_PYTHON_VERSION% == 3 (
SET WINDOWS_SDK_VERSION="v7.1"
IF %MINOR_PYTHON_VERSION% LEQ 4 (
SET SET_SDK_64=Y
) ELSE (
SET SET_SDK_64=N
IF EXIST "%WIN_WDK%" (
:: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/
REN "%WIN_WDK%" 0wdf
)
)
) ELSE (
ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
EXIT 1
)
)
IF %PYTHON_ARCH% == 64 (
IF %SET_SDK_64% == Y (
ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture
SET DISTUTILS_USE_SDK=1
SET MSSdk=1
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
ECHO Executing: %COMMAND_TO_RUN%
call %COMMAND_TO_RUN% || EXIT 1
) ELSE (
ECHO Using default MSVC build environment for 64 bit architecture
ECHO Executing: %COMMAND_TO_RUN%
call %COMMAND_TO_RUN% || EXIT 1
)
) ELSE (
ECHO Using default MSVC build environment for 32 bit architecture
ECHO Executing: %COMMAND_TO_RUN%
call %COMMAND_TO_RUN% || EXIT 1
)

View File

@@ -1,58 +0,0 @@
#!/bin/bash
set -e # Exit with nonzero exit code if anything fails
SOURCE_BRANCH="master"
TARGET_BRANCH="gh-pages"
# Pull requests and commits to other branches shouldn't try to deploy, just build to verify
if [ "$TRAVIS_PULL_REQUEST" != "false" ] || \
[ "$TRAVIS_BRANCH" != master -a \
"$TRAVIS_BRANCH" != develop -a \
"$TRAVIS_BRANCH" != travis ]; then
echo "No docs to upload."
exit 0
fi
if [ -z "$GH_TOKEN" ]; then
echo "Error: GH_TOKEN is undefined"
exit 1
fi
# Save some useful information
REPO=`git config remote.origin.url`
SHA=`git rev-parse --verify HEAD`
# build happens to contain the "doc/html" tree that we want to push
# into the gh-pages branch. So we step into that directory, create a new repo,
# set the remote appropriately, then commit and push.
cd build
git init
git config user.name "Travis CI"
git config user.email "travis-ci"
# Make sure 'GH_TOKEN' is set (as 'secure' variable) in .travis.yml
git remote add upstream "https://$GH_TOKEN@github.com/boostorg/python.git"
git fetch upstream
git reset upstream/gh-pages
# Prepare version.
if [ "$TRAVIS_BRANCH" = develop -o "$TRAVIS_BRANCH" = travis ]; then
mkdir -p develop/doc/
cp ../index.html develop/
cp ../doc/index.html develop/doc/
cp -a doc/html develop/doc/
git add develop/index.html
git add develop/doc/index.html
git add -A develop/doc/html
else
cp ../index.html .
cp ../doc/index.html doc/
git add index.html
git add doc/index.html
git add -A doc/html
fi
# Commit the new version.
git commit -m "Deploy to GitHub Pages: ${SHA}"
# Now that we're all set up, we can push.
git push -q upstream HEAD:gh-pages

View File

@@ -0,0 +1,37 @@
name: deploy documentation
on: [push]
jobs:
deploy:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- name: setup
run: |
sudo apt-get update
sudo apt-get install \
libboost-tools-dev \
python3 \
python3-numpy \
python3-sphinx \
xsltproc \
docbook-xsl
#sudo python3 -m pip install --upgrade pip
sudo python3 -m pip install faber
- name: build
run: |
sed -e "s/\$PYTHON/python3/g" .ci/faber > ~/.faber
faber --builddir=build doc.html
if [ "${GITHUB_REF##*/}" == master ]; then
echo "destination_dir=doc/html" >> $GITHUB_ENV
else
echo "destination_dir=doc/develop/html" >> $GITHUB_ENV
fi
- name: deploy
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: build/doc/html
destination_dir: ${{ env.destination_dir }}
keep_files: true

50
.github/workflows/test-osx.yml vendored Normal file
View File

@@ -0,0 +1,50 @@
name: Test OSX
on: [push, pull_request]
jobs:
build:
runs-on: macOS-latest
strategy:
fail-fast: false
matrix:
python-version: [3.8.10]
cxx: [clang++]
std: [c++11, c++14] # TODO: c++17 is failing !
steps:
- uses: actions/checkout@v5
- name: setup python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: setup prerequisites
run: |
brew install boost
python -m pip install --upgrade pip
python -m pip install setuptools faber
- name: build
run: |
python --version
${{ matrix.cxx }} --version
brew info boost
faber -v
sed -e "s/\$PYTHON/python/g" .ci/faber > ~/.faber
faber \
--with-boost-include=$(brew --prefix boost)/include \
--builddir=build \
cxx.name=${{ matrix.cxx }} \
cxxflags=-std=${{ matrix.std }} \
cppflags=-std=${{ matrix.std }} \
-j`sysctl -n hw.ncpu`
- name: test
run: |
faber \
--with-boost-include=$(brew --prefix boost)/include \
--builddir=build\
cxx.name=${{ matrix.cxx }} \
cxxflags=-std=${{ matrix.std }} \
cppflags=-std=${{ matrix.std }} \
-j`sysctl -n hw.ncpu` \
test.report

53
.github/workflows/test-ubuntu.yml vendored Normal file
View File

@@ -0,0 +1,53 @@
name: Test Ubuntu
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python: [python, python3]
cxx: [g++, clang++]
std: [c++98, c++11, c++14, c++17]
include:
# Add the appropriate docker image for each compiler.
# The images from teeks99/boost-python-test already have boost::python
# pre-reqs installed, see:
# https://github.com/teeks99/boost-python-test-docker
- cxx: clang++
docker-img: teeks99/boost-python-test:clang-12_1.76.0
- cxx: g++
docker-img: teeks99/boost-python-test:gcc-10_1.76.0
container:
image: ${{ matrix.docker-img }}
steps:
- uses: actions/checkout@v5
- name: build
run: |
${{ matrix.python }} --version
${{ matrix.cxx }} --version
faber -v
sed -e "s/\$PYTHON/${{ matrix.python }}/g" .ci/faber > ~/.faber
faber \
--with-boost-include=${BOOST_PY_DEPS} \
--builddir=build \
cxx.name=${{ matrix.cxx }} \
cxxflags=-std=${{ matrix.std }} \
cppflags=-std=${{ matrix.std }} \
-j`nproc`
- name: test
run: |
faber \
--with-boost-include=${BOOST_PY_DEPS} \
--builddir=build \
cxx.name=${{ matrix.cxx }} \
cxxflags=-std=${{ matrix.std }} \
cppflags=-std=${{ matrix.std }} \
-j`nproc` \
test.report

49
.github/workflows/test-windows.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: Test Windows
on: [push, pull_request]
jobs:
build:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
python-version: [3.7]
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- uses: microsoft/setup-msbuild@v2
- name: setup boost prerequisites
uses: lukka/run-vcpkg@v6
with:
vcpkgGitCommitId: '88b1071e39f13b632644d9d953738d345a4ac055'
vcpkgDirectory: '${{ runner.workspace }}/vcpkg'
vcpkgTriplet: x64-windows
vcpkgArguments: >
boost-config
boost-core
boost-function
boost-graph
boost-iterator
boost-lexical-cast
boost-mpl
boost-preprocessor
boost-smart-ptr
boost-static-assert
boost-align
- name: setup faber
run: |
python -m pip install --upgrade pip
python -m pip install setuptools faber numpy
faber --info=tools cxx
- name: build
shell: cmd
run: |
faber --builddir=build cxx.name=msvc --log=commands --log=output --with-boost-include=${{ runner.workspace }}\vcpkg\installed\x64-windows\include -j4
- name: test
shell: cmd
run: |
faber --builddir=build cxx.name=msvc --with-boost-include=${{ runner.workspace }}\vcpkg\installed\x64-windows\include -j4 test.report

View File

@@ -1,116 +0,0 @@
#
# Copyright (c) 2016 Stefan Seefeld
# All rights reserved.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
sudo: required
dist: trusty
language: cpp
env:
global:
- secure: BRNUkxN3p8f+uYKWC3Hr0VPqZA0PxbWr1DJlcI4hbiZtzKhMCWjDmd9UW9CzzexqeOxpd+9s0G87qvOur+wMSVxugDxtTesZrh1czXHeSVxgQrYD783XJtQJ9aYypbChkiboRD6Xpmbq7itwMuHBJMFtCuDxMynpU1jWwkyTf2Y=
matrix:
include:
- compiler: gcc
env: CXX=g++ PYTHON=python CXXFLAGS=-std=c++98
- compiler: gcc
env: CXX=g++ PYTHON=python CXXFLAGS=-std=c++11
- compiler: gcc
env: CXX=g++ PYTHON=python3 CXXFLAGS=-std=c++98
- compiler: gcc
env: CXX=g++ PYTHON=python3 CXXFLAGS=-std=c++11
- compiler: clang
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++98
- compiler: clang
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++11
- env: PYTHON=python DOC=1
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.8
- g++-4.8
- clang
- python-numpy
- python-sphinx
- python3-dev
- python3-numpy
- libboost-all-dev
- xsltproc
- docbook-xsl
- python-docutils
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).
- |
set -e
if [ ! -d $HOME/Boost/tools/boostbook ]; then
echo "rebuilding Boost prerequisites."
wget https://sourceforge.net/projects/boost/files/boost/1.66.0/boost_1_66_0.tar.gz/download
tar xf download
pushd boost_1_66_0
./bootstrap.sh
./b2 tools/bcp
mkdir -p $HOME/Boost
# Install Boost.Python prerequisites, but not Boost.Python itself.
dist/bin/bcp python tools/boostbook tools/quickbook $HOME/Boost &> /dev/null
rm -rf $HOME/Boost/boost/python*
popd
else
echo "using cached Boost prerequisites."
fi
# Install Faber, the build tool.
date=2018-03-07
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
- $PYTHON --version
- faber -h
- ls -l $HOME/Boost
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
fi
after_success:
# Upload docs only when building upstream.
- |
if [ "$DOC" -a \
"$TRAVIS_REPO_SLUG" = "boostorg/python" -a \
"$TRAVIS_PULL_REQUEST" = "false" ]; then
export GH_TOKEN
.ci/upload_docs.sh
fi

176
CMakeLists.txt Normal file
View File

@@ -0,0 +1,176 @@
# Copyright 2020, 2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.14...3.20)
project(boost_python VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
find_package(Python REQUIRED COMPONENTS Development OPTIONAL_COMPONENTS NumPy)
if(Python_NumPy_FOUND)
message(STATUS "Boost.Python: using Python ${Python_VERSION} with NumPy at ${Python_NumPy_INCLUDE_DIRS}")
else()
message(STATUS "Boost.Python: using Python ${Python_VERSION} without NumPy")
endif()
# boost_pythonXY
set(_pyver ${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
set(_boost_python boost_python${_pyver})
add_library(${_boost_python}
src/dict.cpp
src/errors.cpp
src/exec.cpp
src/import.cpp
src/list.cpp
src/long.cpp
src/module.cpp
src/object_operators.cpp
src/object_protocol.cpp
src/slice.cpp
src/str.cpp
src/tuple.cpp
src/wrapper.cpp
src/converter/from_python.cpp
src/converter/registry.cpp
src/converter/type_id.cpp
src/converter/builtin_converters.cpp
src/converter/arg_to_python_base.cpp
src/object/enum.cpp
src/object/class.cpp
src/object/function.cpp
src/object/inheritance.cpp
src/object/life_support.cpp
src/object/pickle_support.cpp
src/object/iterator.cpp
src/object/stl_iterator.cpp
src/object_protocol.cpp
src/object_operators.cpp
src/object/function_doc_signature.cpp
)
add_library(Boost::python${_pyver} ALIAS ${_boost_python})
target_include_directories(${_boost_python} PUBLIC include)
target_link_libraries(${_boost_python}
PUBLIC
Boost::align
Boost::bind
Boost::config
Boost::conversion
Boost::core
Boost::detail
Boost::foreach
Boost::function
Boost::iterator
Boost::lexical_cast
Boost::mpl
Boost::numeric_conversion
Boost::preprocessor
Boost::smart_ptr
Boost::static_assert
Boost::tuple
Boost::type_traits
Boost::utility
Python::Module
PRIVATE
Boost::graph
Boost::integer
Boost::property_map
)
target_compile_definitions(${_boost_python}
PUBLIC BOOST_PYTHON_NO_LIB
PRIVATE BOOST_PYTHON_SOURCE
)
if(BUILD_SHARED_LIBS)
target_compile_definitions(${_boost_python} PUBLIC BOOST_PYTHON_DYN_LINK)
else()
target_compile_definitions(${_boost_python} PUBLIC BOOST_PYTHON_STATIC_LINK BOOST_PYTHON_STATIC_LIB)
endif()
# Boost::python alias
add_library(boost_python INTERFACE)
add_library(Boost::python ALIAS boost_python)
target_link_libraries(boost_python INTERFACE Boost::python${_pyver})
# Installation
if(BOOST_SUPERPROJECT_VERSION AND NOT CMAKE_VERSION VERSION_LESS 3.13)
boost_install(TARGETS ${_boost_python} boost_python VERSION ${BOOST_SUPERPROJECT_VERSION} HEADER_DIRECTORY include)
endif()
if(Python_NumPy_FOUND)
# boost_numpyXY
set(_boost_numpy boost_numpy${_pyver})
add_library(${_boost_numpy}
src/numpy/dtype.cpp
src/numpy/matrix.cpp
src/numpy/ndarray.cpp
src/numpy/numpy.cpp
src/numpy/scalars.cpp
src/numpy/ufunc.cpp
)
add_library(Boost::numpy${_pyver} ALIAS ${_boost_numpy})
target_include_directories(${_boost_numpy} PUBLIC include)
target_link_libraries(${_boost_numpy}
PUBLIC
Boost::config
Boost::core
Boost::detail
Boost::mpl
Boost::python
Boost::smart_ptr
Python::NumPy
)
target_compile_definitions(${_boost_numpy}
PUBLIC BOOST_NUMPY_NO_LIB
PRIVATE BOOST_NUMPY_SOURCE
)
if(BUILD_SHARED_LIBS)
target_compile_definitions(${_boost_numpy} PUBLIC BOOST_NUMPY_DYN_LINK)
else()
target_compile_definitions(${_boost_numpy} PUBLIC BOOST_NUMPY_STATIC_LINK BOOST_NUMPY_STATIC_LIB)
endif()
# Boost::numpy alias
add_library(boost_numpy INTERFACE)
add_library(Boost::numpy ALIAS boost_numpy)
target_link_libraries(boost_numpy INTERFACE Boost::numpy${_pyver})
# Installation
if(BOOST_SUPERPROJECT_VERSION AND NOT CMAKE_VERSION VERSION_LESS 3.13)
boost_install(TARGETS ${_boost_numpy} boost_numpy VERSION ${BOOST_SUPERPROJECT_VERSION})
endif()
endif()
unset(_pyver)
unset(_boost_python)
unset(_boost_numpy)
# Testing
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()

68
Jamfile
View File

@@ -1,68 +0,0 @@
# 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

@@ -2,6 +2,8 @@
# Synopsis
[![Join the chat at https://gitter.im/boostorg/python](https://badges.gitter.im/boostorg/python.svg)](https://gitter.im/boostorg/python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Welcome to Boost.Python, a C++ library which enables seamless interoperability between C++ and the Python programming language. The library includes support for:
* References and Pointers
@@ -19,7 +21,7 @@ See the [Boost.Python](http://boostorg.github.io/python) documentation for detai
**Hint :** Check out the [development version](http://boostorg.github.io/python/develop) of the documentation to see work in progress.
# Building ![Build Status](https://travis-ci.org/boostorg/python.svg?branch=develop)
# Building ![Test Ubuntu](https://github.com/boostorg/python/workflows/Test%20Ubuntu/badge.svg) ![Test OSX](https://github.com/boostorg/python/workflows/Test%20OSX/badge.svg) ![Test Windows](https://github.com/boostorg/python/workflows/Test%20Windows/badge.svg)
While Boost.Python is part of the Boost C++ Libraries super-project, and thus can be compiled as part of Boost, it can also be compiled and installed stand-alone, i.e. against a pre-installed Boost package.

41
build.jam Normal file
View File

@@ -0,0 +1,41 @@
# Copyright René Ferdinand Rivera Morell 2024
# 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)
require-b2 5.2 ;
constant boost_dependencies :
/boost/align//boost_align
/boost/bind//boost_bind
/boost/config//boost_config
/boost/conversion//boost_conversion
/boost/core//boost_core
/boost/detail//boost_detail
/boost/foreach//boost_foreach
/boost/function//boost_function
/boost/iterator//boost_iterator
/boost/lexical_cast//boost_lexical_cast
/boost/mpl//boost_mpl
/boost/numeric_conversion//boost_numeric_conversion
/boost/preprocessor//boost_preprocessor
/boost/static_assert//boost_static_assert
/boost/tuple//boost_tuple
/boost/type_traits//boost_type_traits
/boost/utility//boost_utility ;
project /boost/python
: common-requirements
<include>include
;
explicit
[ alias boost_python : build//boost_python ]
[ alias boost_numpy : build//boost_numpy ]
[ alias all : boost_python boost_numpy test ]
;
call-if : boost-library python
: install boost_python boost_numpy
;

View File

@@ -30,14 +30,34 @@ else
;
}
project boost/python
constant boost_dependencies_private :
/boost/graph//boost_graph
/boost/integer//boost_integer
/boost/property_map//boost_property_map
/boost/smart_ptr//boost_smart_ptr
;
project
: source-location ../src
: common-requirements <library>$(boost_dependencies)
: requirements <library>$(boost_dependencies_private)
;
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
local rule eq ( a : b ) { if $(a) = $(b) { return 1 ; } }
rule tag ( name : type ? : property-set )
{
if python-tag in [ RULENAMES $(__name__) ]
{
return [ $(__name__).python-tag $(name) : $(type) : $(property-set) ] ;
}
}
if [ python.configured ]
{
lib boost_python
: # sources
list.cpp
@@ -92,8 +112,9 @@ lib boost_python
[ unless [ python.configured ] : <build>no ]
<dependency>config-warning
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
-<tag>@%boostcpp.tag
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(__name__).python-tag
<tag>@tag
<conditional>@python.require-py
: # default build
@@ -101,8 +122,20 @@ lib boost_python
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
<define>BOOST_PYTHON_NO_LIB
;
}
else
{
alias boost_python : config-warning ;
}
if [ python.configured ] && [ python.numpy ]
{
numpy-include = [ python.numpy-include ] ;
lib boost_numpy
: # sources
@@ -117,11 +150,12 @@ lib boost_numpy
<define>BOOST_NUMPY_SOURCE
[ cond [ python.numpy ] : <library>/python//python_for_extensions ]
[ unless [ python.numpy ] : <build>no ]
<include>$(numpy-include)
<library>/python//numpy
<library>boost_python
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
-<tag>@%boostcpp.tag
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(__name__).python-tag
<tag>@tag
<conditional>@python.require-py
: # default build
@@ -129,4 +163,13 @@ lib boost_numpy
: # usage requirements
<link>static:<define>BOOST_NUMPY_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
<define>BOOST_NUMPY_NO_LIB
;
}
else
{
alias boost_numpy : config-warning ;
}

View File

@@ -714,3 +714,23 @@ span.purple { color: purple; }
span.gold { color: gold; }
span.silver { color: silver; } /* lighter gray */
span.gray { color: #808080; } /* light gray */
/* 2022 fix */
ol.simple ol p,
ol.simple ul p,
ul.simple ol p,
ul.simple ul p {
margin-top: 0;
}
ol.simple > li:not(:first-child) > p,
ul.simple > li:not(:first-child) > p {
margin-top: 0;
}
ol.simple p,
ul.simple p {
margin-bottom: 0;
}

View File

@@ -49,6 +49,9 @@
{%- for scriptfile in script_files %}
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
{%- endfor %}
<script data-url_root="{{ pathto('', 1) }}" id="documentation_options" src="{{ pathto('', 1) }}_static/documentation_options.js"></script>
<script src="{{ pathto('', 1) }}_static/searchtools.js"></script>
<script src="{{ pathto('', 1) }}_static/language_data.js"></script>
{%- if use_opensearch %}
<link rel="search" type="application/opensearchdescription+xml"
title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"

View File

@@ -40,8 +40,8 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = u'Boost.Python NumPy extension'
copyright = u'2011, Stefan Seefeld'
project = 'Boost.Python NumPy extension'
copyright = '2011, Stefan Seefeld'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -181,8 +181,8 @@ html_add_permalinks = False
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'BoostPythonNumPy.tex', u'Boost.Python NumPy Documentation',
u'Stefan Seefeld', 'manual'),
('index', 'BoostPythonNumPy.tex', 'Boost.Python NumPy Documentation',
'Stefan Seefeld', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -214,6 +214,6 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'boostnumpy', u'Boost.Python NumPy Documentation',
[u'Stefan Seefeld'], 1)
('index', 'boostnumpy', 'Boost.Python NumPy Documentation',
['Stefan Seefeld'], 1)
]

View File

@@ -48,7 +48,7 @@ Next, create a list, and add this tuple to the list. Then use the list to create
list_for_dtype.append(for_custom_dtype) ;
np::dtype custom_dtype = np::dtype(list_for_dtype) ;
We are now ready to create an ndarray with dimensions specified by \*shape\* and of custom dtpye ::
We are now ready to create an ndarray with dimensions specified by \*shape\* and of custom dtype ::
np::ndarray new_array = np::zeros(shape,custom_dtype);
}

View File

@@ -20,6 +20,8 @@ C++ Module Definition
``
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/def.hpp>
#include <boost/utility.hpp>
#include <cstring>
@@ -28,7 +30,7 @@ class Base
{
public:
virtual char const* class_name() const { return "Base"; }
virtual ~Base();
virtual ~Base() {};
};
bool is_base(Base* b)
@@ -56,7 +58,7 @@ BOOST_PYTHON_MODULE(my_module)
{
def("is_base", is_base);
class_<Base,Base_callback, noncopyable>("Base")
class_<Base,Base_callback, boost::noncopyable>("Base")
.def("class_name", &Base_callback::Base_name)
;

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 Jamrules file above should be sufficient
The comments contained in the Jamroot file above should be sufficient
to get you going.
[h2 Running bjam]
@@ -1871,36 +1871,6 @@ This technique has several advantages:
* Minimize the need to recompile
* Rapid prototyping (you can move the code to C++ if required without changing the interface)
You can even add a little syntactic sugar with the use of metaclasses. Let's
create a special metaclass that "injects" methods in other classes.
# The one Boost.Python uses for all wrapped classes.
# You can use here any class exported by Boost instead of "point"
BoostPythonMetaclass = point.__class__
class injector(object):
class __metaclass__(BoostPythonMetaclass):
def __init__(self, name, bases, dict):
for b in bases:
if type(b) not in (self, type):
for k,v in dict.items():
setattr(b,k,v)
return type.__init__(self, name, bases, dict)
# inject some methods in the point foo
class more_point(injector, point):
def __repr__(self):
return 'Point(x=%s, y=%s)' % (self.x, self.y)
def foo(self):
print 'foo!'
Now let's see how it got:
>>> print point()
Point(x=10, y=10)
>>> point().foo()
foo!
Another useful idea is to replace constructors with factory functions:
_point = point

View File

@@ -3,7 +3,7 @@
# Examples
This directory contains various examples using Boost.Python.
You may compile these using the `bjam` command either in this directory
You may compile these using the `b2` command either in this directory
or in any of the subdirectories.
You may need to adjust the paths in the Jamroot file if Boost.Python
is not installed in a default location.

View File

@@ -3,6 +3,7 @@
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
import numpy
import gaussian
@@ -19,19 +20,19 @@ x, y = numpy.meshgrid(r, r)
z = g(x, y)
s = z.sum() * (r[1] - r[0])**2
print "sum (should be ~ 1):", s
print("sum (should be ~ 1):", s)
xc = (z * x).sum() / z.sum()
print "x centroid (should be ~ %f): %f" % (mu[0], xc)
print("x centroid (should be ~ %f): %f" % (mu[0], xc))
yc = (z * y).sum() / z.sum()
print "y centroid (should be ~ %f): %f" % (mu[1], yc)
print("y centroid (should be ~ %f): %f" % (mu[1], yc))
xx = (z * (x - xc)**2).sum() / z.sum()
print "xx moment (should be ~ %f): %f" % (sigma[0,0], xx)
print("xx moment (should be ~ %f): %f" % (sigma[0,0], xx))
yy = (z * (y - yc)**2).sum() / z.sum()
print "yy moment (should be ~ %f): %f" % (sigma[1,1], yy)
print("yy moment (should be ~ %f): %f" % (sigma[1,1], yy))
xy = 0.5 * (z * (x - xc) * (y - yc)).sum() / z.sum()
print "xy moment (should be ~ %f): %f" % (sigma[0,1], xy)
print("xy moment (should be ~ %f): %f" % (sigma[0,1], xy))

View File

@@ -1,4 +1,4 @@
#! /usr/bin/env python
#!/usr/bin/env python3
# Copyright Stefan Seefeld 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
#! /usr/bin/env python
#!/usr/bin/env python3
# Copyright Ralf W. Grosse-Kunstleve 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

@@ -1,4 +1,4 @@
#! /usr/bin/env python
#!/usr/bin/env python3
# Copyright Joel de Guzman 2002-2007. Distributed under the Boost
# Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
# or copy at http://www.boost.org/LICENSE_1_0.txt)

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=config.use)
test = module('test', features=config.use)
doc = module('doc', features=config.use)
src = module('src', features=features|config.use)
test = module('test', features=features|config.use)
doc = module('doc', features=features|config.use)
default = src.default

View File

@@ -60,7 +60,7 @@ call(PyObject* callable
)
{
PyObject* const result =
PyEval_CallFunction(
PyObject_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 PyEval_CallFunction, its reference
// argument for passing to PyObject_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

@@ -59,7 +59,7 @@ call_method(PyObject* self, char const* name
)
{
PyObject* const result =
PyEval_CallMethod(
PyObject_CallMethod(
self
, const_cast<char*>(name)
, const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")")
@@ -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 PyEval_CallFunction, its reference
// argument for passing to PyObject_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

@@ -372,10 +372,11 @@ class class_ : public objects::class_base
{
typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
return this->make_fn_impl(
return objects::add_doc(
this->make_fn_impl(
detail::unwrap_wrapper((W*)0)
, f, is_obj_or_proxy(), (char*)0, detail::is_data_member_pointer<F>()
);
), NULL);
}
template <class F>
@@ -383,10 +384,11 @@ class class_ : public objects::class_base
{
typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
return this->make_fn_impl(
return objects::add_doc(
this->make_fn_impl(
detail::unwrap_wrapper((W*)0)
, f, is_obj_or_proxy(), (int*)0, detail::is_data_member_pointer<F>()
);
), NULL);
}
template <class T, class F>

View File

@@ -81,9 +81,9 @@ inline object_manager_ref_arg_from_python<Ref>::object_manager_ref_arg_from_pyth
# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243
// needed for warning suppression
python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x);
python::detail::construct_referent<Ref>(&m_result.bytes, x_);
python::detail::construct_referent<Ref>(m_result.bytes, x_);
# else
python::detail::construct_referent<Ref>(&m_result.bytes, (python::detail::borrowed_reference)x);
python::detail::construct_referent<Ref>(m_result.bytes, (python::detail::borrowed_reference)x);
# endif
}

View File

@@ -9,7 +9,7 @@
# include <boost/python/converter/registered.hpp>
# include <boost/python/detail/unwind_type.hpp>
# include <boost/python/detail/type_traits.hpp>
# include <boost/python/back_reference.hpp>
namespace boost { namespace python {
@@ -46,6 +46,12 @@ inline python::type_info unwind_type_id_(boost::type<T>* = 0, mpl::false_ * =0)
return boost::python::detail::unwind_type<unwind_type_id_helper, T> ();
}
template <class T>
inline python::type_info unwind_type_id_(boost::type<back_reference<T> >* = 0, mpl::false_ * =0)
{
return boost::python::detail::unwind_type<unwind_type_id_helper, T> ();
}
inline python::type_info unwind_type_id_(boost::type<void>* = 0, mpl::true_* =0)
{
return type_id<void>();

View File

@@ -9,6 +9,7 @@
# include <boost/python/detail/referent_storage.hpp>
# include <boost/python/detail/destroy.hpp>
# include <boost/python/detail/type_traits.hpp>
# include <boost/align/align.hpp>
# include <boost/static_assert.hpp>
# include <cstddef>
@@ -132,7 +133,13 @@ template <class T>
inline rvalue_from_python_data<T>::~rvalue_from_python_data()
{
if (this->stage1.convertible == this->storage.bytes)
python::detail::destroy_referent<ref_type>(this->storage.bytes);
{
size_t allocated = sizeof(this->storage);
void *ptr = this->storage.bytes;
void *aligned_storage =
::boost::alignment::align(boost::python::detail::alignment_of<T>::value, 0, ptr, allocated);
python::detail::destroy_referent<ref_type>(aligned_storage);
}
}
}}} // namespace boost::python::converter

View File

@@ -49,13 +49,17 @@ struct shared_ptr_from_python
new (storage) SP<T>();
else
{
SP<void> hold_convertible_ref_count(
(void*)0, shared_ptr_deleter(handle<>(borrowed(source))) );
// use aliasing constructor
new (storage) SP<T>(hold_convertible_ref_count,
static_cast<T*>(data->convertible));
void *const storage = ((converter::rvalue_from_python_storage<SP<T> >*)data)->storage.bytes;
// Deal with the "None" case.
if (data->convertible == source)
new (storage) SP<T>();
else
{
SP<void> hold_convertible_ref_count((void*)0, shared_ptr_deleter(handle<>(borrowed(source))) );
// use aliasing constructor
new (storage) SP<T>(hold_convertible_ref_count, static_cast<T*>(data->convertible));
}
}
data->convertible = storage;
}
};

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(__BORLANDC__, BOOST_TESTED_AT(0x551))
|| BOOST_WORKAROUND(BOOST_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(__BORLANDC__, BOOST_TESTED_AT(0x551))
|| BOOST_WORKAROUND(BOOST_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,6 +109,23 @@ 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
@@ -229,16 +246,12 @@ 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>();
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 };
py_func_sig_info res = {sig, ret };
#else
py_func_sig_info res = {sig, sig };
#endif

View File

@@ -57,9 +57,15 @@
****************************************************************************/
// backwards compatibility:
#ifdef BOOST_PYTHON_STATIC_LIB
# define BOOST_PYTHON_STATIC_LINK
# elif !defined(BOOST_PYTHON_DYNAMIC_LIB)
#if defined(BOOST_PYTHON_STATIC_LINK) && !defined(BOOST_PYTHON_STATIC_LIB)
# define BOOST_PYTHON_STATIC_LIB
#endif
#if defined(BOOST_PYTHON_DYNAMIC_LINK) && !defined(BOOST_PYTHON_DYNAMIC_LIB)
# define BOOST_PYTHON_DYNAMIC_LIB
#endif
#if !defined(BOOST_PYTHON_STATIC_LIB) && !defined(BOOST_PYTHON_DYNAMIC_LIB)
# define BOOST_PYTHON_DYNAMIC_LIB
#endif
@@ -105,7 +111,9 @@
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#define BOOST_LIB_NAME boost_python##PY_MAJOR_VERSION##PY_MINOR_VERSION
#define _BOOST_PYTHON_CONCAT(N, M, m) N ## M ## m
#define BOOST_PYTHON_CONCAT(N, M, m) _BOOST_PYTHON_CONCAT(N, M, m)
#define BOOST_LIB_NAME BOOST_PYTHON_CONCAT(boost_python, PY_MAJOR_VERSION, PY_MINOR_VERSION)
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
@@ -118,6 +126,9 @@
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#undef BOOST_PYTHON_CONCAT
#undef _BOOST_PYTHON_CONCAT
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
#define BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // enables smooth transition
#endif

View File

@@ -5,39 +5,21 @@
#ifndef REFERENT_STORAGE_DWA200278_HPP
# define REFERENT_STORAGE_DWA200278_HPP
# include <boost/mpl/if.hpp>
# include <boost/type_traits/aligned_storage.hpp>
# include <cstddef>
namespace boost { namespace python { namespace detail {
struct alignment_dummy;
typedef void (*function_ptr)();
typedef int (alignment_dummy::*member_ptr);
typedef int (alignment_dummy::*member_function_ptr)();
# define BOOST_PYTHON_ALIGNER(T, n) \
typename mpl::if_c< \
sizeof(T) <= size, T, char>::type t##n
// Storage for size bytes, aligned to all fundamental types no larger than size
template <std::size_t size>
union aligned_storage
template <std::size_t size, std::size_t alignment = std::size_t(-1)>
struct aligned_storage
{
BOOST_PYTHON_ALIGNER(char, 0);
BOOST_PYTHON_ALIGNER(short, 1);
BOOST_PYTHON_ALIGNER(int, 2);
BOOST_PYTHON_ALIGNER(long, 3);
BOOST_PYTHON_ALIGNER(float, 4);
BOOST_PYTHON_ALIGNER(double, 5);
BOOST_PYTHON_ALIGNER(long double, 6);
BOOST_PYTHON_ALIGNER(void*, 7);
BOOST_PYTHON_ALIGNER(function_ptr, 8);
BOOST_PYTHON_ALIGNER(member_ptr, 9);
BOOST_PYTHON_ALIGNER(member_function_ptr, 10);
union type
{
typename ::boost::aligned_storage<size, alignment>::type data;
char bytes[size];
};
};
# undef BOOST_PYTHON_ALIGNER
// Compute the size of T's referent. We wouldn't need this at all,
// but sizeof() is broken in CodeWarriors <= 8.0
template <class T> struct referent_size;
@@ -50,15 +32,12 @@ union aligned_storage
std::size_t, value = sizeof(T));
};
// A metafunction returning a POD type which can store U, where T ==
// U&. If T is not a reference type, returns a POD which can store T.
template <class T>
struct referent_storage
{
typedef aligned_storage<
::boost::python::detail::referent_size<T>::value
> type;
typedef typename aligned_storage<referent_size<T>::value, alignment_of<T>::value>::type type;
};
}}} // namespace boost::python::detail

View File

@@ -11,13 +11,15 @@
namespace boost { namespace python { namespace detail {
#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
#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
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
// forward declaration, required (at least) by Tru64 cxx V6.5-042 and msvc14.15
template <class Generator, class U>
inline typename Generator::result_type
unwind_type(boost::type<U>*p = 0, Generator* = 0);
@@ -83,7 +85,7 @@ struct unwind_helper<false>
template <class Generator, class U>
inline typename Generator::result_type
#ifndef _MSC_VER
#if (!defined(_MSC_VER) || _MSC_VER >= 1915)
unwind_type(U const& p, Generator*)
#else
unwind_type(U const& p, Generator* = 0)
@@ -148,7 +150,7 @@ struct unwind_helper2<reference_to_pointer_>
// why bother?
template <class Generator, class U>
inline typename Generator::result_type
#ifndef _MSC_VER
#if (!defined(_MSC_VER) || _MSC_VER >= 1915)
unwind_type(boost::type<U>*, Generator*)
#else
unwind_type(boost::type<U>*p =0, Generator* =0)

View File

@@ -47,6 +47,13 @@
# 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
@@ -83,6 +90,7 @@
// than MSVC on Win32
//
#if defined(_WIN32) || defined(__CYGWIN__)
# if defined(__GNUC__) && defined(__CYGWIN__)
# if defined(__LP64__)
@@ -138,19 +146,45 @@ typedef int pid_t;
# undef hypot // undo the evil #define left by Python.
# elif defined(__BORLANDC__)
# elif defined(__BORLANDC__) && !defined(__clang__)
# 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
@@ -193,7 +227,11 @@ typedef int pid_t;
# define PyVarObject_HEAD_INIT(type, size) \
PyObject_HEAD_INIT(type) size,
#endif
#if PY_VERSION_HEX < 0x030900A4
# define Py_SET_TYPE(obj, type) ((Py_TYPE(obj) = (type)), (void)0)
# define Py_SET_SIZE(obj, size) ((Py_SIZE(obj) = (size)), (void)0)
#endif

View File

@@ -7,7 +7,7 @@
# include <boost/python/detail/prefix.hpp>
# include <boost/bind.hpp>
# include <boost/bind/bind.hpp>
# include <boost/bind/placeholders.hpp>
# include <boost/type.hpp>
# include <boost/python/detail/translate_exception.hpp>
@@ -18,6 +18,7 @@ namespace boost { namespace python {
template <class ExceptionType, class Translate>
void register_exception_translator(Translate translate, boost::type<ExceptionType>* = 0)
{
using namespace boost::placeholders;
detail::register_exception_handler(
boost::bind<bool>(detail::translate_exception<ExceptionType,Translate>(), _1, _2, translate)
);

View File

@@ -38,7 +38,7 @@ struct BOOST_PYTHON_DECL instance_holder : private noncopyable
// Allocate storage for an object of the given size at the given
// offset in the Python instance<> object if bytes are available
// there. Otherwise allocate size bytes of heap memory.
static void* allocate(PyObject*, std::size_t offset, std::size_t size);
static void* allocate(PyObject*, std::size_t offset, std::size_t size, std::size_t alignment = 1);
// Deallocate storage from the heap if it was not carved out of
// the given Python object by allocate(), above.

View File

@@ -22,7 +22,7 @@ works correctly. */
# pragma warning(disable: 4180)
# endif
# include <boost/bind.hpp>
# include <boost/bind/bind.hpp>
# include <boost/bind/protect.hpp>
namespace boost { namespace python {
@@ -40,6 +40,7 @@ namespace detail
, Target&(*)()
)
{
using namespace boost::placeholders;
return objects::make_iterator_function<Target>(
boost::protect(boost::bind(get_start, _1))
, boost::protect(boost::bind(get_finish, _1))

View File

@@ -73,7 +73,7 @@ class list : public detail::list_base
}
template <class T>
long count(T const& value) const
ssize_t 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_non_null_reference call(object const&);
static detail::new_non_null_reference call(object const&, object const&);
static detail::new_reference call(object const&);
static detail::new_reference call(object const&, object const&);
};
}

View File

@@ -61,7 +61,8 @@ namespace detail
typedef objects::pointer_holder<Ptr,value_type> holder;
typedef objects::instance<holder> instance_t;
void* memory = holder::allocate(this->m_self, offsetof(instance_t, storage), sizeof(holder));
void* memory = holder::allocate(this->m_self, offsetof(instance_t, storage), sizeof(holder),
boost::python::detail::alignment_of<holder>::value);
try {
#if defined(BOOST_NO_CXX11_SMART_PTR)
(new (memory) holder(x))->install(this->m_self);

View File

@@ -62,7 +62,9 @@
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#define BOOST_LIB_NAME boost_numpy##PY_MAJOR_VERSION##PY_MINOR_VERSION
#define _BOOST_PYTHON_CONCAT(N, M, m) N ## M ## m
#define BOOST_PYTHON_CONCAT(N, M, m) _BOOST_PYTHON_CONCAT(N, M, m)
#define BOOST_LIB_NAME BOOST_PYTHON_CONCAT(boost_numpy, PY_MAJOR_VERSION, PY_MINOR_VERSION)
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
@@ -75,6 +77,9 @@
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#undef BOOST_PYTHON_CONCAT
#undef _BOOST_PYTHON_CONCAT
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#endif // CONFIG_NUMPY20170215_H_

View File

@@ -18,6 +18,8 @@ BOOST_PYTHON_DECL void add_to_namespace(
BOOST_PYTHON_DECL void add_to_namespace(
object const& name_space, char const* name, object const& attribute, char const* doc);
BOOST_PYTHON_DECL object const& add_doc(object const& attribute, char const* doc);
}}} // namespace boost::python::objects
#endif // ADD_TO_NAMESPACE_DWA200286_HPP

View File

@@ -35,6 +35,8 @@ struct BOOST_PYTHON_DECL function : PyObject
static void add_to_namespace(
object const& name_space, char const* name, object const& attribute, char const* doc);
static object const& add_doc(object const& attribute, char const* doc);
object const& doc() const;
void doc(object const& x);
@@ -42,6 +44,8 @@ struct BOOST_PYTHON_DECL function : PyObject
object const& get_namespace() const { return m_namespace; }
object const& get_module() const { return m_module; }
private: // helper functions
object signature(bool show_return_type=false) const;
object signatures(bool show_return_type=false) const;
@@ -53,6 +57,7 @@ struct BOOST_PYTHON_DECL function : PyObject
handle<function> m_overloads;
object m_name;
object m_namespace;
object m_module;
object m_doc;
object m_arg_names;
unsigned m_nkeyword_values;

View File

@@ -18,13 +18,13 @@
namespace boost { namespace python { namespace objects {
class function_doc_signature_generator{
static const char * py_type_str(const python::detail::signature_element &s);
static str py_type_str(const python::detail::signature_element &s, const object& current_module_name);
static bool arity_cmp( function const *f1, function const *f2 );
static bool are_seq_overloads( function const *f1, function const *f2 , bool check_docs);
static std::vector<function const*> flatten(function const *f);
static std::vector<function const*> split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change);
static str raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
static str parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types);
static str parameter_string(py_function const &f, size_t n, object arg_names, const object& module_name, bool cpp_types);
static str pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
public:

View File

@@ -6,7 +6,7 @@
# define INSTANCE_DWA200295_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/detail/type_traits.hpp>
# include <cstddef>
namespace boost { namespace python
@@ -28,7 +28,7 @@ struct instance
typedef typename boost::python::detail::type_with_alignment<
boost::python::detail::alignment_of<Data>::value
>::type align_t;
union
{
align_t align;
@@ -41,9 +41,10 @@ struct additional_instance_size
{
typedef instance<Data> instance_data;
typedef instance<char> instance_char;
BOOST_STATIC_CONSTANT(
std::size_t, value = sizeof(instance_data)
- BOOST_PYTHON_OFFSETOF(instance_char,storage));
BOOST_STATIC_CONSTANT(std::size_t,
value = sizeof(instance_data) -
BOOST_PYTHON_OFFSETOF(instance_char,storage) +
boost::python::detail::alignment_of<Data>::value);
};
}}} // namespace boost::python::object

View File

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

View File

@@ -89,8 +89,9 @@ struct make_holder<N>
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, t, a))
{
typedef instance<Holder> instance_t;
void* memory = Holder::allocate(p, offsetof(instance_t, storage), sizeof(Holder));
void* memory = Holder::allocate(p, offsetof(instance_t, storage), sizeof(Holder),
boost::python::detail::alignment_of<Holder>::value);
try {
(new (memory) Holder(
p BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_DO_FORWARD_ARG, nil)))->install(p);

View File

@@ -43,11 +43,14 @@ struct make_instance_impl
// construct the new C++ object and install the pointer
// in the Python object.
Derived::construct(&instance->storage, (PyObject*)instance, x)->install(raw_result);
Holder *holder =Derived::construct(instance->storage.bytes, (PyObject*)instance, x);
holder->install(raw_result);
// Note the position of the internally-stored Holder,
// for the sake of destruction
Py_SIZE(instance) = offsetof(instance_t, storage);
const size_t offset = reinterpret_cast<size_t>(holder) -
reinterpret_cast<size_t>(instance->storage.bytes) + offsetof(instance_t, storage);
Py_SET_SIZE(instance, offset);
// Release ownership of the python object
protect.cancel();
@@ -69,7 +72,10 @@ struct make_instance
static inline Holder* construct(void* storage, PyObject* instance, reference_wrapper<T const> x)
{
return new (storage) Holder(instance, x);
size_t allocated = objects::additional_instance_size<Holder>::value;
void* aligned_storage = ::boost::alignment::align(boost::python::detail::alignment_of<Holder>::value,
sizeof(Holder), storage, allocated);
return new (aligned_storage) Holder(instance, x);
}
};

View File

@@ -9,7 +9,7 @@
# include <boost/python/object_core.hpp>
# include <boost/python/call.hpp>
# include <boost/iterator/detail/enable_if.hpp>
# include <boost/type_traits/enable_if.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/iterator/detail/config_def.hpp>
@@ -40,7 +40,7 @@ struct is_object_operators
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
template <class L, class R, class T>
struct enable_binary
: boost::iterators::enable_if<is_object_operators<L,R>, T>
: boost::enable_if_<is_object_operators<L,R>::value, T>
{};
# define BOOST_PYTHON_BINARY_RETURN(T) typename enable_binary<L,R,T>::type
# else

View File

@@ -1,5 +1,5 @@
#ifndef OTHER_DWA20020601_HPP
# define OTHER_DWA20020601_HPP
#ifndef BOOST_PYTHON_OTHER_HPP
# define BOOST_PYTHON_OTHER_HPP
# include <boost/python/detail/prefix.hpp>
// Copyright David Abrahams 2002.
@@ -7,8 +7,6 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
# pragma once
# include <boost/config.hpp>
namespace boost { namespace python {
@@ -51,4 +49,4 @@ namespace detail
}} // namespace boost::python
#endif // #ifndef OTHER_DWA20020601_HPP
#endif

View File

@@ -97,7 +97,7 @@ class override : public object
operator()() const
{
detail::method_result x(
PyEval_CallFunction(
PyObject_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(
PyEval_CallFunction(
PyObject_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

@@ -1,5 +1,5 @@
#ifndef PTR_DWA20020601_HPP
# define PTR_DWA20020601_HPP
#ifndef BOOST_PYTHON_PTR_HPP
# define BOOST_PYTHON_PTR_HPP
# include <boost/python/detail/prefix.hpp>
// Copyright David Abrahams 2002.
@@ -11,8 +11,6 @@
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2001 Peter Dimov
# pragma once
# include <boost/config.hpp>
# include <boost/mpl/bool.hpp>
@@ -64,4 +62,4 @@ class unwrap_pointer<pointer_wrapper<T> >
}} // namespace boost::python
#endif // #ifndef PTR_DWA20020601_HPP
#endif

View File

@@ -96,6 +96,7 @@ namespace detail
, make_function(
detail::nullary_function_adaptor<void(*)()>(pure_virtual_called)
, default_call_policies()
, options.keywords()
, detail::error_signature<held_type>(detail::get_signature(m_pmf))
)
);

View File

@@ -216,7 +216,13 @@ namespace boost { namespace python { namespace detail {
{
for (const_iterator i = proxies.begin(); i != proxies.end(); ++i)
{
if ((*i)->ob_refcnt <= 0)
if (
#if PY_VERSION_HEX < 0x03090000
(*i)->ob_refcnt
#else
Py_REFCNT(*i)
#endif
<= 0)
{
PyErr_SetString(PyExc_RuntimeError,
"Invariant: Proxy vector in an inconsistent state");

View File

@@ -10,5 +10,6 @@
],
"maintainers": [
"Stefan Seefeld <stefan -at- seefeld.name>"
]
],
"cxxstd": "03"
}

View File

@@ -222,7 +222,13 @@ namespace
, char const* ref_type)
{
handle<> holder(source);
if (source->ob_refcnt <= 1)
if (
#if PY_VERSION_HEX < 0x03090000
source->ob_refcnt
#else
Py_REFCNT(source)
#endif
<= 1)
{
handle<> msg(
#if PY_VERSION_HEX >= 0x3000000

View File

@@ -104,14 +104,22 @@ 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);
// 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
#if PY_VERSION_HEX >= 0x03010000
// Let python manage any UTF bits to avoid potential incompatibilities.
PyObject *fo = Py_BuildValue("s", f);
FILE *fs = _Py_fopen(fo, "r");
PyObject *fb = Py_None;
PyUnicode_FSConverter(fo, &fb);
char *f_as_uft = PyBytes_AsString(fb);
FILE *fs = fopen(f_as_uft, "r");
Py_DECREF(fo);
Py_DECREF(fb);
#elif PY_VERSION_HEX >= 0x03000000
// Let python open the file to avoid potential binary incompatibilities.
PyObject *fo = Py_BuildValue("s", f);
FILE *fs = 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);
@@ -121,6 +129,7 @@ object BOOST_PYTHON_DECL exec_file(char const *filename, object global, object l
f,
Py_file_input,
global.ptr(), local.ptr());
fclose(fs);
if (!result) throw_error_already_set();
return object(detail::new_reference(result));
}

View File

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

View File

@@ -21,7 +21,7 @@ namespace
object m_obj(((borrowed_reference_t*)m));
scope current_module(m_obj);
handle_exception(init_function);
if (handle_exception(init_function)) return NULL;
}
return m;

View File

@@ -98,35 +98,16 @@ python::detail::new_reference dtype::convert(object const & arg, bool align)
return python::detail::new_reference(reinterpret_cast<PyObject*>(obj));
}
int dtype::get_itemsize() const { return reinterpret_cast<PyArray_Descr*>(ptr())->elsize;}
int dtype::get_itemsize() const {
#if NPY_ABI_VERSION < 0x02000000
return reinterpret_cast<PyArray_Descr*>(ptr())->elsize;
#else
return PyDataType_ELSIZE(reinterpret_cast<PyArray_Descr*>(ptr()));
#endif
}
bool equivalent(dtype const & a, dtype const & b) {
// On Windows x64, the behaviour described on
// http://docs.scipy.org/doc/numpy/reference/c-api.array.html for
// PyArray_EquivTypes unfortunately does not extend as expected:
// "For example, on 32-bit platforms, NPY_LONG and NPY_INT are equivalent".
// This should also hold for 64-bit platforms (and does on Linux), but not
// on Windows. Implement an alternative:
#ifdef _MSC_VER
if (sizeof(long) == sizeof(int) &&
// Manually take care of the type equivalence.
((a == dtype::get_builtin<long>() || a == dtype::get_builtin<int>()) &&
(b == dtype::get_builtin<long>() || b == dtype::get_builtin<int>()) ||
(a == dtype::get_builtin<unsigned int>() || a == dtype::get_builtin<unsigned long>()) &&
(b == dtype::get_builtin<unsigned int>() || b == dtype::get_builtin<unsigned long>()))) {
return true;
} else {
return PyArray_EquivTypes(
reinterpret_cast<PyArray_Descr*>(a.ptr()),
reinterpret_cast<PyArray_Descr*>(b.ptr())
);
}
#else
return PyArray_EquivTypes(
reinterpret_cast<PyArray_Descr*>(a.ptr()),
reinterpret_cast<PyArray_Descr*>(b.ptr())
);
#endif
return a == b;
}
namespace

View File

@@ -19,6 +19,7 @@ static void wrap_import_array()
static void * wrap_import_array()
{
import_array();
return NULL;
}
#endif

View File

@@ -5,6 +5,7 @@
#include <boost/python/detail/prefix.hpp>
#include <boost/mpl/lambda.hpp> // #including this first is an intel6 workaround
#include <boost/cstdint.hpp>
#include <boost/python/object/class.hpp>
#include <boost/python/object/instance.hpp>
@@ -208,7 +209,7 @@ namespace objects
{
if (static_data_object.tp_dict == 0)
{
Py_TYPE(&static_data_object) = &PyType_Type;
Py_SET_TYPE(&static_data_object, &PyType_Type);
static_data_object.tp_base = &PyProperty_Type;
if (PyType_Ready(&static_data_object))
return 0;
@@ -316,7 +317,7 @@ namespace objects
{
if (class_metatype_object.tp_dict == 0)
{
Py_TYPE(&class_metatype_object) = &PyType_Type;
Py_SET_TYPE(&class_metatype_object, &PyType_Type);
class_metatype_object.tp_base = &PyType_Type;
if (PyType_Ready(&class_metatype_object))
return type_handle();
@@ -332,8 +333,9 @@ namespace objects
for (instance_holder* p = kill_me->objects, *next; p != 0; p = next)
{
next = p->next();
void* q = dynamic_cast<void*>(p);
p->~instance_holder();
instance_holder::deallocate(inst, dynamic_cast<void*>(p));
instance_holder::deallocate(inst, q);
}
// Python 2.2.1 won't add weak references automatically when
@@ -374,12 +376,7 @@ 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.
#if PY_VERSION_HEX >= 0x02060000
Py_SIZE(result) =
#else
result->ob_size =
#endif
-(static_cast<int>(offsetof(instance<>,storage) + instance_size));
Py_SET_SIZE(result,-static_cast<int>(offsetof(instance<>,storage) + instance_size));
}
return (PyObject*)result;
}
@@ -470,7 +467,7 @@ namespace objects
{
if (class_type_object.tp_dict == 0)
{
Py_TYPE(&class_type_object) = incref(class_metatype().get());
Py_SET_TYPE(&class_type_object, incref(class_metatype().get()));
class_type_object.tp_base = &PyBaseObject_Type;
if (PyType_Ready(&class_type_object))
return type_handle();
@@ -506,6 +503,16 @@ namespace objects
);
}
object qualname(const char *name)
{
#if PY_VERSION_HEX >= 0x03030000
if (PyObject_HasAttrString(scope().ptr(), "__qualname__")) {
return str("%s.%s" % make_tuple(scope().attr("__qualname__"), name));
}
#endif
return str(name);
}
namespace
{
// Find a registered class object corresponding to id. Return a
@@ -568,6 +575,9 @@ namespace objects
object m = module_prefix();
if (m) d["__module__"] = m;
#if PY_VERSION_HEX >= 0x03030000
d["__qualname__"] = qualname(name);
#endif
if (doc != 0)
d["__doc__"] = doc;
@@ -618,7 +628,7 @@ namespace objects
{
object property(
(python::detail::new_reference)
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("Osss"), fget.ptr(), 0, 0, docstr));
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("Osss"), fget.ptr(), (char*)NULL, (char*)NULL, docstr));
this->setattr(name, property);
}
@@ -628,7 +638,7 @@ namespace objects
{
object property(
(python::detail::new_reference)
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("OOss"), fget.ptr(), fset.ptr(), 0, docstr));
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("OOss"), fget.ptr(), fset.ptr(), (char*)NULL, docstr));
this->setattr(name, property);
}
@@ -726,28 +736,46 @@ namespace objects
} // namespace objects
void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size)
typedef unsigned int alignment_marker_t;
void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size, std::size_t alignment)
{
assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_)), &class_metatype_object));
objects::instance<>* self = (objects::instance<>*)self_;
int total_size_needed = holder_offset + holder_size;
int total_size_needed = holder_offset + holder_size + alignment - 1;
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));
size_t allocated = holder_size + alignment;
void* storage = (char*)self + holder_offset;
void* aligned_storage = ::boost::alignment::align(alignment, holder_size, storage, allocated);
// Record the fact that the storage is occupied, noting where it starts
Py_SIZE(self) = holder_offset;
return (char*)self + holder_offset;
const size_t offset = reinterpret_cast<uintptr_t>(aligned_storage) - reinterpret_cast<uintptr_t>(storage) + holder_offset;
Py_SET_SIZE(self, offset);
return (char*)self + offset;
}
else
{
void* const result = PyMem_Malloc(holder_size);
if (result == 0)
const size_t base_allocation = sizeof(alignment_marker_t) + holder_size + alignment - 1;
void* const base_storage = PyMem_Malloc(base_allocation);
if (base_storage == 0)
throw std::bad_alloc();
return result;
const uintptr_t x = reinterpret_cast<uintptr_t>(base_storage) + sizeof(alignment_marker_t);
// Padding required to align the start of a data structure is: (alignment - (x % alignment)) % alignment
// Since the alignment is a power of two, the formula can be simplified with bitwise AND operator as follow:
const uintptr_t padding = (alignment - (x & (alignment - 1))) & (alignment - 1);
const size_t aligned_offset = sizeof(alignment_marker_t) + padding;
void* const aligned_storage = (char *)base_storage + aligned_offset;
BOOST_ASSERT((char *) aligned_storage + holder_size <= (char *)base_storage + base_allocation);
alignment_marker_t* const marker_storage = reinterpret_cast<alignment_marker_t *>((char *)aligned_storage - sizeof(alignment_marker_t));
*marker_storage = static_cast<alignment_marker_t>(padding);
return aligned_storage;
}
}
@@ -757,7 +785,9 @@ void instance_holder::deallocate(PyObject* self_, void* storage) throw()
objects::instance<>* self = (objects::instance<>*)self_;
if (storage != (char*)self + Py_SIZE(self))
{
PyMem_Free(storage);
alignment_marker_t* marker_storage = reinterpret_cast<alignment_marker_t *>((char *)storage - sizeof(alignment_marker_t));
void *malloced_storage = (char *) storage - sizeof(alignment_marker_t) - (*marker_storage);
PyMem_Free(malloced_storage);
}
}

View File

@@ -49,7 +49,9 @@ extern "C"
if (!self->name)
{
return
#if PY_VERSION_HEX >= 0x03000000
#if PY_VERSION_HEX >= 0x03030000
PyUnicode_FromFormat("%S.%S(%ld)", mod, ((PyHeapTypeObject*)(self_->ob_type))->ht_qualname, PyLong_AsLong(self_));
#elif 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_));
@@ -62,7 +64,9 @@ extern "C"
return 0;
return
#if PY_VERSION_HEX >= 0x03000000
#if PY_VERSION_HEX >= 0x03030000
PyUnicode_FromFormat("%S.%S.%S", mod, ((PyHeapTypeObject*)(self_->ob_type))->ht_qualname, name);
#elif PY_VERSION_HEX >= 0x03000000
PyUnicode_FromFormat("%S.%s.%S", mod, self_->ob_type->tp_name, name);
#else
PyString_FromFormat("%s.%s.%s",
@@ -113,7 +117,6 @@ static PyTypeObject enum_type_object = {
#if PY_VERSION_HEX < 0x03000000
| Py_TPFLAGS_CHECKTYPES
#endif
| Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
@@ -146,6 +149,7 @@ static PyTypeObject enum_type_object = {
};
object module_prefix();
object qualname(const char *name);
namespace
{
@@ -153,7 +157,7 @@ namespace
{
if (enum_type_object.tp_dict == 0)
{
Py_TYPE(&enum_type_object) = incref(&PyType_Type);
Py_SET_TYPE(&enum_type_object, incref(&PyType_Type));
#if PY_VERSION_HEX >= 0x03000000
enum_type_object.tp_base = &PyLong_Type;
#else
@@ -176,6 +180,11 @@ namespace
object module_name = module_prefix();
if (module_name)
d["__module__"] = module_name;
#if PY_VERSION_HEX >= 0x03030000
object q = qualname(name);
if (q)
d["__qualname__"] = q;
#endif
if (doc)
d["__doc__"] = doc;

View File

@@ -21,7 +21,7 @@
#include <boost/python/detail/none.hpp>
#include <boost/mpl/vector/vector10.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <algorithm>
#include <cstring>
@@ -107,7 +107,7 @@ function::function(
PyObject* p = this;
if (Py_TYPE(&function_type) == 0)
{
Py_TYPE(&function_type) = &PyType_Type;
Py_SET_TYPE(&function_type, &PyType_Type);
::PyType_Ready(&function_type);
}
@@ -158,15 +158,9 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
{
// no argument preprocessing
}
else if (n_actual > max_arity)
{
// too many arguments
inner_args = handle<>();
}
else
{
// build a new arg tuple, will adjust its size later
assert(max_arity <= static_cast<std::size_t>(ssize_t_max));
inner_args = handle<>(
PyTuple_New(static_cast<ssize_t>(max_arity)));
@@ -424,6 +418,30 @@ namespace detail
extern char cpp_signature_tag[];
}
object const& function::add_doc(object const& attribute, char const* doc)
{
str _doc;
if (docstring_options::show_py_signatures_)
{
_doc += str(const_cast<const char*>(detail::py_signature_tag));
}
if (doc != 0 && docstring_options::show_user_defined_)
_doc += doc;
if (docstring_options::show_cpp_signatures_)
{
_doc += str(const_cast<const char*>(detail::cpp_signature_tag));
}
if(_doc)
{
object mutable_attribute(attribute);
mutable_attribute.attr("__doc__")= _doc;
}
return attribute;
}
void function::add_to_namespace(
object const& name_space, char const* name_, object const& attribute, char const* doc)
{
@@ -449,7 +467,9 @@ 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)
{
@@ -490,16 +510,28 @@ 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__"))));
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>(
#if PY_VERSION_HEX < 0x03030000
"__name__"
#else
"__qualname__"
#endif
))));
PyErr_Clear();
if (name_space_name)
new_func->m_namespace = object(name_space_name);
object module_name(
PyObject_IsInstance(name_space.ptr(), upcast<PyObject>(&PyModule_Type))
? object(name_space.attr("__name__"))
: api::getattr(name_space, "__module__", str())
);
new_func->m_module = module_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();
@@ -536,24 +568,7 @@ void function::add_to_namespace(
"C++ signature:", f->signature(true)));
}
*/
str _doc;
if (docstring_options::show_py_signatures_)
{
_doc += str(const_cast<const char*>(detail::py_signature_tag));
}
if (doc != 0 && docstring_options::show_user_defined_)
_doc += doc;
if (docstring_options::show_cpp_signatures_)
{
_doc += str(const_cast<const char*>(detail::cpp_signature_tag));
}
if(_doc)
{
object mutable_attribute(attribute);
mutable_attribute.attr("__doc__")= _doc;
}
add_doc(attribute, doc);
}
BOOST_PYTHON_DECL void add_to_namespace(
@@ -568,6 +583,18 @@ BOOST_PYTHON_DECL void add_to_namespace(
function::add_to_namespace(name_space, name, attribute, doc);
}
BOOST_PYTHON_DECL object const& add_doc(object const& attribute, char const* doc)
{
#if PY_VERSION_HEX >= 0x03000000
if (PyInstanceMethod_Check(attribute.ptr())) {
#else
if (PyMethod_Check(attribute.ptr())) {
#endif
return attribute;
}
return function::add_doc(attribute, doc);
}
namespace
{
@@ -674,7 +701,7 @@ extern "C"
static PyObject* function_get_module(PyObject* op, void*)
{
function* f = downcast<function>(op);
object const& ns = f->get_namespace();
object const& ns = f->get_module();
if (!ns.is_none()) {
return python::incref(ns.ptr());
}

View File

@@ -114,23 +114,47 @@ namespace boost { namespace python { namespace objects {
return res;
}
const char * function_doc_signature_generator::py_type_str(const python::detail::signature_element &s)
static str get_qualname(const PyTypeObject *py_type)
{
# if PY_VERSION_HEX >= 0x03030000
if ( py_type->tp_flags & Py_TPFLAGS_HEAPTYPE )
return str(handle<>(borrowed(((PyHeapTypeObject*)(py_type))->ht_qualname)));
# endif
return str(py_type->tp_name);
}
str function_doc_signature_generator::py_type_str(const python::detail::signature_element &s, const object &current_module_name)
{
if (s.basename==std::string("void")){
static const char * none = "None";
return none;
return str(none);
}
PyTypeObject const * py_type = s.pytype_f?s.pytype_f():0;
if ( py_type )
return py_type->tp_name;
else{
if ( py_type ) {
str name(get_qualname(py_type));
if ( py_type->tp_flags & Py_TPFLAGS_HEAPTYPE ) {
// Qualify the type name if it is defined in a different module.
PyObject *type_module_name = PyDict_GetItemString(py_type->tp_dict, "__module__");
if (
type_module_name
&& PyObject_RichCompareBool(
type_module_name,
current_module_name.ptr(),
Py_NE
) != 0
) {
return str("%s.%s" % make_tuple(handle<>(borrowed(type_module_name)), name));
}
}
return name;
} else {
static const char * object = "object";
return object;
return str(object);
}
}
str function_doc_signature_generator::parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types)
str function_doc_signature_generator::parameter_string(py_function const &f, size_t n, object arg_names, const object& current_module_name, bool cpp_types)
{
str param;
@@ -156,12 +180,12 @@ namespace boost { namespace python { namespace objects {
{
object kv;
if ( arg_names && (kv = arg_names[n-1]) )
param = str( " (%s)%s" % make_tuple(py_type_str(s[n]),kv[0]) );
param = str( " (%s)%s" % make_tuple(py_type_str(s[n], current_module_name),kv[0]) );
else
param = str(" (%s)%s%d" % make_tuple(py_type_str(s[n]),"arg", n) );
param = str(" (%s)%s%d" % make_tuple(py_type_str(s[n], current_module_name),"arg", n) );
}
else //we are processing the return type
param = py_type_str(f.get_return_type());
param = py_type_str(f.get_return_type(), current_module_name);
}
//an argument - check for default value and append it
@@ -199,7 +223,7 @@ namespace boost { namespace python { namespace objects {
str param;
formal_params.append(
parameter_string(impl, n, f->m_arg_names, cpp_types)
parameter_string(impl, n, f->m_arg_names, f->get_module(), cpp_types)
);
// find all the arguments with default values preceeding the arity-n_overloads

View File

@@ -11,7 +11,7 @@
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/reverse_graph.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/integer_traits.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
@@ -184,6 +184,7 @@ namespace
// map a type to a position in the index
inline type_index_t::iterator type_position(class_id type)
{
using namespace boost::placeholders;
typedef index_entry entry;
return std::lower_bound(

View File

@@ -5,7 +5,7 @@
#include <boost/python/object/iterator_core.hpp>
#include <boost/python/object/function_object.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/mpl/vector/vector10.hpp>
namespace boost { namespace python { namespace objects {

View File

@@ -93,7 +93,7 @@ PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient)
if (Py_TYPE(&life_support_type) == 0)
{
Py_TYPE(&life_support_type) = &PyType_Type;
Py_SET_TYPE(&life_support_type, &PyType_Type);
PyType_Ready(&life_support_type);
}

View File

@@ -34,4 +34,14 @@ slice_base::step() const
((PySliceObject*)this->ptr())->step));
}
static struct register_slice_pytype_ptr
{
register_slice_pytype_ptr()
{
const_cast<converter::registration &>(
converter::registry::lookup(boost::python::type_id<boost::python::slice>())
).m_class_object = &PySlice_Type;
}
}register_slice_pytype_ptr_;
} } } // !namespace boost::python::detail

View File

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

View File

@@ -2,14 +2,16 @@
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
require-b2 5.0.1 ;
import-search /boost/config/checks ;
import python ;
import os ;
import ../../config/checks/config : requires ;
import config : requires ;
lib socket ;
use-project /boost/python : ../build ;
project /boost/python/test
project
: requirements
<toolset>gcc:<cxxflags>-Wextra
<target-os>qnxnto:<library>socket
@@ -28,7 +30,7 @@ rule py-run ( sources * : input-file ? )
: $(input-file)
: #requirements
<define>BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
] ;
}
@@ -50,6 +52,20 @@ rule require-windows ( properties * )
}
}
if [ python.configured ]
{
alias base_deps : usage-requirements
<library>/boost/align//boost_align
<library>/boost/assert//boost_assert
<library>/boost/config//boost_config
<library>/boost/core//boost_core
<library>/boost/detail//boost_detail
<library>/boost/function//boost_function
<library>/boost/mpl//boost_mpl
<library>/boost/preprocessor//boost_preprocessor
<library>/boost/static_assert//boost_static_assert
<library>/boost/type_traits//boost_type_traits
;
test-suite python
:
@@ -95,14 +111,18 @@ bpl-test crossmod_exception
[ 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 polymorphism2_auto_ptr
: polymorphism2_auto_ptr.py polymorphism2.py polymorphism2_auto_ptr.cpp
: [ requires auto_ptr ]
]
[ bpl-test polymorphism ]
[ bpl-test polymorphism2 ]
[ bpl-test auto_ptr ]
[ bpl-test auto_ptr
: # files
: [ requires auto_ptr ]
]
[ bpl-test minimal ]
[ bpl-test args ]
@@ -113,7 +133,7 @@ bpl-test crossmod_exception
[ bpl-test try : newtest.py m1.cpp m2.cpp ]
[ bpl-test const_argument ]
[ bpl-test keywords : keywords.cpp keywords_test.py ]
[ python-extension builtin_converters_ext : builtin_converters.cpp /boost/python//boost_python ]
[ bpl-test builtin_converters : test_builtin_converters.py builtin_converters_ext ]
@@ -126,6 +146,7 @@ bpl-test crossmod_exception
[ bpl-test object ]
[ bpl-test class ]
[ bpl-test aligned_class ]
[ bpl-test list ]
[ bpl-test long ]
[ bpl-test dict ]
@@ -185,13 +206,13 @@ bpl-test crossmod_opaque
# Whenever the cause for the failure of the polymorphism test is found
# and fixed, this should be retested.
<toolset>hp_cxx:<build>no ]
[ python-extension map_indexing_suite_ext
: map_indexing_suite.cpp int_map_indexing_suite.cpp a_map_indexing_suite.cpp
/boost/python//boost_python ]
[ bpl-test
[ bpl-test
map_indexing_suite : map_indexing_suite.py map_indexing_suite_ext ]
[ run import_.cpp /boost/python//boost_python $(PY) : : import_.py ]
# if $(TEST_BIENSTMAN_NON_BUGS)
@@ -205,28 +226,29 @@ bpl-test crossmod_opaque
# --- unit tests of library components ---
[ compile indirect_traits_test.cpp ]
[ run destroy_test.cpp ]
[ compile indirect_traits_test.cpp : <use>base_deps ]
[ run destroy_test.cpp : : : <use>base_deps ]
[ py-run pointer_type_id_test.cpp ]
[ py-run bases.cpp ]
[ run if_else.cpp ]
[ run if_else.cpp : : : <use>base_deps ]
[ py-run pointee.cpp ]
[ run result.cpp ]
[ run result.cpp : : : <use>base_deps ]
[ compile string_literal.cpp ]
[ compile string_literal.cpp : <use>base_deps ]
[ py-compile borrowed.cpp ]
[ py-compile object_manager.cpp ]
[ py-compile copy_ctor_mutates_rhs.cpp ]
[ py-run upcast.cpp ]
[ py-compile select_holder.cpp ]
[ run select_from_python_test.cpp ../src/converter/type_id.cpp
:
[ run select_from_python_test.cpp ../src/converter/type_id.cpp
:
:
: <define>BOOST_PYTHON_STATIC_LIB
<use>$(PY)
<use>base_deps
]
@@ -248,3 +270,4 @@ bpl-test crossmod_opaque
;
}

33
test/aligned_class.cpp Normal file
View File

@@ -0,0 +1,33 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/object.hpp>
#include <boost/python/class.hpp>
#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
using namespace boost::python;
struct BOOST_ALIGNMENT(32) X
{
int x;
BOOST_ALIGNMENT(32) float f;
X(int n, float _f) : x(n), f(_f)
{
BOOST_ASSERT((reinterpret_cast<uintptr_t>(&f) % 32) == 0);
}
};
int x_function(X& x) { return x.x;}
float f_function(X& x) { return x.f;}
BOOST_PYTHON_MODULE(aligned_class_ext)
{
class_<X>("X", init<int, float>());
def("x_function", x_function);
def("f_function", f_function);
}
#include "module_tail.cpp"

44
test/aligned_class.py Executable file
View File

@@ -0,0 +1,44 @@
# 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 aligned_class_ext import *
Ensure sanity:
>>> x = X(42, 16)
>>> x_function(x)
42
>>> f_function(x)
16.0
Demonstrate extraction in the presence of metaclass changes:
>>> class MetaX(X.__class__):
... def __new__(cls, *args):
... return super(MetaX, cls).__new__(cls, *args)
>>> class XPlusMetatype(X):
... __metaclass__ = MetaX
>>> x = XPlusMetatype(42, 16)
>>> x_function(x)
42
>>> f_function(x)
16.0
'''
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print("running...")
import sys
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -1,15 +1,19 @@
# Copyright David Abrahams 2004. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
from __future__ import print_function
"""
>>> from args_ext import *
>>> raw(3, 4, foo = 'bar', baz = 42)
((3, 4), {'foo': 'bar', 'baz': 42})
>>> args, kwargs = raw(3, 4, foo = 'bar', baz = 42)
>>> args
(3, 4)
>>> kwargs['foo']
'bar'
>>> kwargs['baz']
42
Prove that we can handle empty keywords and non-keywords
>>> raw(3, 4)
((3, 4), {})
@@ -76,7 +80,7 @@ from __future__ import print_function
... 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)
@@ -123,10 +127,16 @@ from __future__ import print_function
1
>>> y = Y(value = 33)
>>> y.raw(this = 1, that = 'the other')[1]
{'this': 1, 'that': 'the other'}
>>> _, kwargs = y.raw(this = 1, that = 'the other')
>>> kwargs['this']
1
>>> kwargs['that']
'the other'
"""
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -143,6 +153,3 @@ if __name__ == '__main__':
import args_ext
help(args_ext)
sys.exit(status)

View File

@@ -21,11 +21,13 @@ object new_dict()
object data_dict()
{
dict tmp1;
tmp1["key1"] = "value1";
dict tmp2;
tmp2["key2"] = "value2";
tmp1[1] = tmp2;
tmp1["key1"] = "value1";
return tmp1;
}
@@ -60,22 +62,20 @@ void work_with_dict(dict data1, dict data2)
void test_templates(object print)
{
std::string key = "key";
dict tmp;
tmp[1] = "a test string";
print(tmp.get(1));
//print(tmp[1]);
tmp[1.5] = 13;
print(tmp.get(1.5));
tmp[1] = "a test string";
print(tmp.get(1));
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,7 +1,6 @@
# 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):
@@ -22,14 +21,16 @@ from __future__ import print_function
>>> print(dict_from_sequence([(1,1),(2,2),(3,3)]))
{1: 1, 2: 2, 3: 3}
>>> test_templates(printer) #doctest: +NORMALIZE_WHITESPACE
a test string
13
a test string
None
{1.5: 13, 1: 'a test string'}
default
default
"""
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -37,7 +38,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, ext=[], script=None, np=False,
def extension_test(name, exts=[], script=None, numpy=False,
features=features, condition=None):
"""Create a Python extension test `name`.
Arguments:
* name: the name of the test.
* ext: extensions to be compiled, <name> if none are given.
* exts: extensions to be compiled, <name> if none are given.
* script: the test script to execute, <name>.py if none is given.
* np: if true, add boost_numpy to sources
* numpy: 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, ext=[], script=None, np=False,
features=features.copy()
extensions = []
libs = [src.bnl, src.bpl] if np else [src.bpl]
for e in ext or [name]:
if type(e) is str: # build from a single source file
n = e if e != name else e + '_ext'
s = [e + '.cpp']
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']
else: # build from a list of source files
n = e[0] if e[0] != name else e[0] + '_ext'
s = [n + '.cpp' for n in e]
e = extension(n, s + libs, features=features)
features |= pythonpath(e.path, base='')
extensions.append(e)
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)
if not script:
script = name+'.py'
return test(name, script, run=python.run, dependencies=extensions,
@@ -67,6 +67,7 @@ for t in [('injected',),
('args',),
('raw_ctor',),
('exception_translator',),
('module_init_exception',),
('test_enum', ['enum_ext']),
('test_cltree', ['cltree']),
('newtest', ['m1', 'm2']),
@@ -78,6 +79,8 @@ for t in [('injected',),
('callbacks',),
('defaults',),
('object',),
('class',),
('aligned_class',),
('list',),
('long',),
('dict',),
@@ -123,9 +126,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%
$(>[1]) $(>[2])"""
$(>[0]) $(>[1])"""
else:
command = 'LD_LIBRARY_PATH=$(runpath) $(>[1]) $(>[2])'
command = 'LD_LIBRARY_PATH=$(runpath) $(>[0]) $(>[1])'
tests.append(test('import', [import_, 'import_.py'],
run=action('run', command),
@@ -167,7 +170,7 @@ for t in ['numpy/dtype',
'numpy/ndarray',
'numpy/indexing',
'numpy/shapes']:
tests.append(extension_test(t, np=True,
tests.append(extension_test(t, numpy=True,
condition=set.define.contains('HAS_NUMPY')))
default = report('report', tests, fail_on_failures=True)

View File

@@ -6,7 +6,7 @@
#include <boost/python.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
#include <sstream>

View File

@@ -1,7 +1,6 @@
# 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 *
@@ -25,7 +24,7 @@ from __future__ import print_function
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)
@@ -56,12 +55,15 @@ from __future__ import print_function
>>> 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
@@ -69,7 +71,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,6 @@
# 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 *
@@ -41,7 +40,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')
@@ -51,7 +50,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)
@@ -103,6 +102,8 @@ reverse sorted:
['y', 'x', 'o', 'l', 'l', 'h', 'e', '.']
'''
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -110,7 +111,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,9 +1,6 @@
# 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())
@@ -20,6 +17,10 @@ if (sys.version_info.major >= 3):
>>> 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,7 +1,6 @@
# 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
'''
#####################################################################
@@ -25,7 +24,7 @@ foo
# test that a string is implicitly convertible
# to an X
>>> x_value('bochi bochi')
>>> x_value('bochi bochi')
'gotya bochi bochi'
#####################################################################
@@ -33,9 +32,9 @@ foo
#####################################################################
>>> def print_xmap(xmap):
... s = '[ '
... for x in xmap:
... for x in xmap:
... s += repr(x)
... s += ' '
... s += ' '
... s += ']'
... print(s)
@@ -135,7 +134,7 @@ foo
>>> assert not 12345 in xm
#####################################################################
# Some references to the container elements
# Some references to the container elements
#####################################################################
>>> z0 = xm['joel']
@@ -156,7 +155,7 @@ banana
kiwi
#####################################################################
# Delete some container element
# Delete some container element
#####################################################################
>>> del xm['tenji']
@@ -168,7 +167,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
@@ -199,7 +198,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
@@ -216,11 +215,19 @@ joel kimpo
4
#####################################################################
# END....
# Test signature...
#####################################################################
>>> AMap.__iter__.__doc__.strip().split("\\n")[0]
'__iter__( (AMap)arg1) -> __main__.iterator :'
#####################################################################
# END....
#####################################################################
'''
from __future__ import print_function
def run(args = None):
import sys
@@ -236,8 +243,3 @@ if __name__ == '__main__':
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)

View File

@@ -0,0 +1,14 @@
// Copyright (C) 2003 Rational Discovery LLC
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <stdexcept>
using namespace boost::python;
BOOST_PYTHON_MODULE(module_init_exception_ext)
{
throw std::runtime_error("Module init failed");
}

View File

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

View File

@@ -4,6 +4,8 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/def.hpp>
#include <boost/python/enum.hpp>
#include <boost/python/operators.hpp>
#include <boost/python/scope.hpp>
#include "test_class.hpp"
@@ -16,6 +18,8 @@
typedef test_class<> X;
typedef test_class<1> Y;
enum color { red = 0, blue = 1, green = 2 };
std::ostream& operator<<(std::ostream& s, X const& x)
{
return s << x.value();
@@ -26,11 +30,13 @@ std::ostream& operator<<(std::ostream& s, Y const& x)
return s << x.value();
}
void test_function(const X& x, const Y& y) {}
BOOST_PYTHON_MODULE(nested_ext)
{
using namespace boost::python;
{
// Establish X as the current scope.
scope x_class
= class_<X>("X", init<int>())
@@ -42,6 +48,17 @@ BOOST_PYTHON_MODULE(nested_ext)
class_<Y>("Y", init<int>())
.def(str(self))
;
// so will the enum `color`
enum_<color>("color")
.value("red", red)
.value("green", green)
.value("blue", blue)
;
}
// The generated docstring will use the fully-qualified name of Y
def("test_function", &test_function);
}

View File

@@ -13,14 +13,35 @@
>>> X.__name__
'X'
>>> X.Y
>>> X.Y # doctest: +py2
<class 'nested_ext.Y'>
>>> X.Y # doctest: +py3
<class 'nested_ext.X.Y'>
>>> X.Y.__module__
'nested_ext'
>>> X.Y.__name__
'Y'
>>> getattr(X.color, "__qualname__", None) # doctest: +py3
'X.color'
>>> repr(X.color.red) # doctest: +py2
'nested_ext.color.red'
>>> repr(X.color.red) # doctest: +py3
'nested_ext.X.color.red'
>>> repr(X.color(1)) # doctest: +py2
'nested_ext.color(1)'
>>> repr(X.color(1)) # doctest: +py3
'nested_ext.X.color(1)'
>>> test_function.__doc__.strip().split('\\n')[0] # doctest: +py3
'test_function( (X)arg1, (X.Y)arg2) -> None :'
'''
@@ -30,7 +51,23 @@ def run(args = None):
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
py2 = doctest.register_optionflag("py2")
py3 = doctest.register_optionflag("py3")
class ConditionalChecker(doctest.OutputChecker):
def check_output(self, want, got, optionflags):
if (optionflags & py3) and (sys.version_info[0] < 3):
return True
if (optionflags & py2) and (sys.version_info[0] >= 3):
return True
return doctest.OutputChecker.check_output(self, want, got, optionflags)
runner = doctest.DocTestRunner(ConditionalChecker())
for test in doctest.DocTestFinder().find(sys.modules.get(__name__)):
runner.run(test)
return doctest.TestResults(runner.failures, runner.tries)
if __name__ == '__main__':
print("running...")

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright Jim Bosch & Ankit Daftery 2010-2012.
# Distributed under the Boost Software License, Version 1.0.
@@ -15,7 +15,7 @@ if (sys.version_info.major >= 3):
class DtypeTestCase(unittest.TestCase):
def assertEquivalent(self, a, b):
return self.assert_(dtype_ext.equivalent(a, b), "%r is not equivalent to %r")
return self.assertTrue(dtype_ext.equivalent(a, b), "%r is not equivalent to %r")
def testIntegers(self):
for bits in (8, 16, 32, 64):

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright Jim Bosch & Ankit Daftery 2010-2012.
# Distributed under the Boost Software License, Version 1.0.

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright Jim Bosch & Ankit Daftery 2010-2012.
# Distributed under the Boost Software License, Version 1.0.
@@ -19,7 +19,7 @@ class TestNdarray(unittest.TestCase):
a1 = ndarray_ext.zeros(shape,dt)
a2 = v.reshape(a1.shape)
self.assertEqual(shape,a1.shape)
self.assert_((a1 == a2).all())
self.assertTrue((a1 == a2).all())
def testNdzeros_matrix(self):
for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128):
@@ -28,7 +28,7 @@ class TestNdarray(unittest.TestCase):
a1 = ndarray_ext.zeros_matrix(shape, dt)
a2 = numpy.matrix(numpy.zeros(shape, dtype=dtp))
self.assertEqual(shape,a1.shape)
self.assert_((a1 == a2).all())
self.assertTrue((a1 == a2).all())
self.assertEqual(type(a1), type(a2))
def testNdarray(self):
@@ -38,8 +38,8 @@ class TestNdarray(unittest.TestCase):
dt = numpy.dtype(dtp)
a1 = ndarray_ext.array(a)
a2 = ndarray_ext.array(a,dt)
self.assert_((a1 == v).all())
self.assert_((a2 == v).all())
self.assertTrue((a1 == v).all())
self.assertTrue((a2 == v).all())
for shape in ((60,),(6,10),(4,3,5),(2,2,3,5)):
a1 = a1.reshape(shape)
self.assertEqual(shape,a1.shape)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright Jim Bosch & Ankit Daftery 2010-2012.
# Distributed under the Boost Software License, Version 1.0.

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright Jim Bosch & Ankit Daftery 2010-2012.
# Distributed under the Boost Software License, Version 1.0.
@@ -18,7 +18,7 @@ class TestTemplates(unittest.TestCase):
a1 = numpy.zeros(shape, dtype=dtype)
a2 = v.reshape(a1.shape)
templates_ext.fill(a1)
self.assert_((a1 == a2).all())
self.assertTrue((a1 == a2).all())
a1 = numpy.zeros((12,), dtype=numpy.float64)
self.assertRaises(TypeError, templates_ext.fill, a1)
a1 = numpy.zeros((12,2,3), dtype=numpy.float32)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright Jim Bosch & Ankit Daftery 2010-2012.
# Distributed under the Boost Software License, Version 1.0.
@@ -8,7 +8,10 @@
import ufunc_ext
import unittest
import numpy
from numpy.testing.utils import assert_array_almost_equal
try:
from numpy.testing import assert_array_almost_equal
except ImportError:
from numpy.testing.utils import assert_array_almost_equal
class TestUnary(unittest.TestCase):
@@ -24,7 +27,7 @@ class TestUnary(unittest.TestCase):
assert_array_almost_equal(b, a*2.0)
c = numpy.zeros(5, dtype=float)
d = f(a,output=c)
self.assert_(c is d)
self.assertTrue((c == d).all())
assert_array_almost_equal(d, a*2.0)
def testList(self):
@@ -47,7 +50,7 @@ class TestBinary(unittest.TestCase):
assert_array_almost_equal(f(a,b), (a*2+b*3))
c = numpy.zeros(5, dtype=float)
d = f(a,b,output=c)
self.assert_(c is d)
self.assertTrue((c == d).all())
assert_array_almost_equal(d, a*2 + b*3)
assert_array_almost_equal(f(a, 2.0), a*2 + 6.0)
assert_array_almost_equal(f(1.0, b), 2.0 + b*3)

View File

@@ -1,7 +1,6 @@
# 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 *
@@ -130,14 +129,14 @@ from __future__ import print_function
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'}
@@ -149,7 +148,7 @@ from __future__ import print_function
Now make sure that object is actually managing reference counts
>>> import weakref
>>> class Z: pass
...
@@ -164,6 +163,8 @@ from __future__ import print_function
death
'''
from __future__ import print_function
def run(args = None):
import sys
import doctest
@@ -171,7 +172,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

@@ -9,8 +9,10 @@ r'''>>> import pickle1_ext
1
>>> pickle1_ext.world.__name__
'world'
>>> pickle1_ext.world('Hello').__reduce__()
>>> pickle1_ext.world('Hello').__reduce__() # doctest: +PY310
(<class 'pickle1_ext.world'>, ('Hello',))
>>> pickle1_ext.world('Hello').__reduce__() # doctest: +PY311
(<class 'pickle1_ext.world'>, ('Hello',), None)
>>> wd = pickle1_ext.world('California')
>>> pstr = pickle.dumps(wd)
>>> wl = pickle.loads(pstr)
@@ -31,7 +33,27 @@ def run(args = None):
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
# > https://docs.python.org/3.11/library/pickle.html#object.__reduce__
# object.__reduce__() returns
# - python 3.10 or prior: a 2-element tuple
# - python 3.11 or later: a 3-element tuple (object's state added)
PY310 = doctest.register_optionflag("PY310")
PY311 = doctest.register_optionflag("PY311")
class ConditionalChecker(doctest.OutputChecker):
def check_output(self, want, got, optionflags):
if (optionflags & PY311) and (sys.version_info[:2] < (3, 11)):
return True
if (optionflags & PY310) and (sys.version_info[:2] >= (3, 11)):
return True
return doctest.OutputChecker.check_output(self, want, got, optionflags)
runner = doctest.DocTestRunner(ConditionalChecker())
for test in doctest.DocTestFinder().find(sys.modules.get(__name__)):
runner.run(test)
return doctest.TestResults(runner.failures, runner.tries)
if __name__ == '__main__':
print("running...")

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