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

Compare commits

...

104 Commits

Author SHA1 Message Date
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
a383ecdd88 Fix build warning. 2018-03-19 13:58:48 -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
Stefan Seefeld
02e079cf4d Merge branch 'develop' 2018-03-08 07:07:42 -05:00
Stefan Seefeld
9039286937 Remove references to scons from README. 2018-03-07 16:54:10 -05:00
Stefan Seefeld
429ac28c4a Streamline CI logic. 2018-03-07 15:09:02 -05:00
Stefan Seefeld
1db3871f50 Remove obsolete scons-based build logic. 2018-03-07 15:09:02 -05:00
Stefan Seefeld
66dad425aa Build docs with faber. 2018-03-07 15:09:02 -05:00
Stefan Seefeld
ed3cbf8a60 Start to collect release notes. 2018-02-25 17:39:18 -05:00
Stefan Seefeld
2f6e728de5 Fix misspelled operator name. 2018-02-20 16:43:58 -05:00
Stefan Seefeld
65be0e0f0f Only iterate over multiple calling conventions on x86. 2018-02-15 22:17:04 -05:00
Stefan Seefeld
d4d41d94ae Add Python version to library suffix. 2018-02-13 17:22:34 -05:00
Bernhard Rosenkränzer
660487c43f Fix build with Python 3.7
Python 3.7 changes the return type of _PyUnicode_AsString()
from void* to const char* -- causing the build of boost-python
to fail.

Signed-off-by: Bernhard Rosenkränzer <bero@lindev.ch>
2018-02-09 15:09:27 -05:00
Stefan Seefeld
d6d54ce483 This is an object, not a function declaration. Really. 2017-12-18 15:04:23 -05:00
Stefan Seefeld
7c33ff0c59 Merge branch 'develop' 2017-11-17 10:06:54 -05:00
Stefan Seefeld
b9d0d97499 Fix MSVC compilation failure. 2017-11-16 10:26:30 -05:00
Stefan Seefeld
fc978f085b Merge branch 'develop' 2017-11-11 08:04:54 -05:00
Stefan Seefeld
ebba009a9f First attempt at faber-based build system. 2017-11-10 07:41:21 -05:00
Stefan Seefeld
9ad3313d1f Fix deprecated elementwise comparison warning / error. 2017-11-07 19:43:16 -05:00
Stefan Seefeld
bf9a03399b Revert "Avoid multiple template instances of boost::python::details::get_signature when multiple calling conventions are enabled"
This reverts commit b49a186b6f.
2017-10-30 08:04:01 -04:00
Stefan Seefeld
2d9871fc5a Fix unresolved symbol error with MSVC. 2017-10-27 13:58:56 -04:00
Gary Furnish
30c9eb1fb6 Fix c++11 detection. 2017-10-25 08:07:17 -04:00
Gary Furnish
7c5e478432 Fix autoptr/unique_ptr ifdef for VS2017. 2017-10-25 08:07:17 -04:00
Krzysztof Trzciński
2b7842a39f Fix memory leaks in enum.cpp
Unfortunately due to optimised build of Python3 libraries and executable I got only partial stack from [http://clang.llvm.org/docs/AddressSanitizer.html], however digging into and reducing my code I tracked it down to be issue with `boost/libs/python/src/object/enum.cpp`.

It has to bits that leak (and comment mentioning there is one):

    PyObject *mod = PyObject_GetAttrString( self_, "__module__");

Leaks reference, as it never decreases it.
It also stores a new string object under object's `name` that ref count never gets decremented.

That commit fixes both issues.
2017-10-25 08:04:35 -04:00
Raffi Enficiaud
8d37630cc8 Fix warning: returning the proper type for object sizes 2017-10-25 08:03:18 -04:00
Marvin Schmidt
9d2903cd5e Fix symbol visibility of init method
This was properly an oversight when switching to the BOOST_SYMBOL_*
symbols from Boost.Config in commit 0224f54a (see #1)

Since Boost.Config is already doing the differentiation between
different platforms and compilers we can simplify this bit and just
use BOOST_SYMBOL_EXPORT
2017-10-24 20:18:59 -04:00
Frank Richter
b09d80a93e Fix exec(), eval() not passing through arguments 2017-10-18 07:37:03 -04:00
Mark Borgerding
135c025484 fixed nuisance warning when calling from_data(...,bob) with an ndarray bob, "FutureWarning: comparison to None will result in an elementwise object comparison in the future." 2017-09-25 09:08:38 -04:00
Mark Borgerding
ecf05c4a90 ndarray.shape(k),strides(k) act more like their python counterparts (negative indexing, bounds checking) (issue #157) 2017-09-25 09:08:14 -04:00
Edward Diener
00b7ed03a7 Remove executable attribute for files. 2017-09-18 08:21:30 -04:00
Stefan Seefeld
c2424bcc8f Fix version number. 2017-08-13 20:45:13 -04:00
Stefan Seefeld
b3b67273b0 Fix traits qualification. 2017-08-13 20:44:52 -04:00
Stefan Seefeld
31c8b7f1b4 Remove 'numeric' documentation. 2017-07-31 11:37:52 -04:00
177 changed files with 1432 additions and 2980 deletions

7
.ci/faber Normal file
View File

@@ -0,0 +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`
# bin.SCons 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 bin.SCons
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, pull_request]
jobs:
deploy:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: setup
run: |
sudo apt-get update
sudo apt-get install \
libboost1.71-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@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: build/doc/html
destination_dir: ${{ env.destination_dir }}
keep_files: true

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

@@ -0,0 +1,45 @@
name: Test OSX
on: [push, pull_request]
jobs:
build:
runs-on: macOS-latest
strategy:
fail-fast: false
matrix:
python-version: [3.6]
cxx: [clang++]
std: [c++98, c++11, c++14] # TODO: c++17 is failing !
steps:
- uses: actions/checkout@v2
- name: setup python
uses: actions/setup-python@v2
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
faber -v
sed -e "s/\$PYTHON/python/g" .ci/faber > ~/.faber
faber \
--builddir=build \
cxx.name=${{ matrix.cxx }} \
cxxflags=-std=${{ matrix.std }} \
-j`sysctl -n hw.ncpu`
- name: test
run: |
faber \
--builddir=build\
cxx.name=${{ matrix.cxx }} \
cxxflags=-std=${{ matrix.std }} \
-j`sysctl -n hw.ncpu` \
test.report

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

@@ -0,0 +1,51 @@
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@v2
- 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 }} \
-j`nproc`
- name: test
run: |
faber \
--with-boost-include=${BOOST_PY_DEPS} \
--builddir=build \
cxx.name=${{ matrix.cxx }} \
cxxflags=-std=${{ matrix.std }} \
-j`nproc` \
test.report

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

@@ -0,0 +1,39 @@
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@v2
- uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: setup boost prerequisites
uses: lukka/run-vcpkg@v6
with:
vcpkgGitCommitId: '8a9a97315aefb3f8bc5d81bf66ca0025938b9c91'
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
#shell: 'bash'
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 --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,99 +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
# clang generates an 'illegal instruction' error in the NumPy check.
# Perhaps we need to upgrade clang to a newer version ?
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++98 OPTIONS=--no-numpy
- compiler: clang
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++11 OPTIONS=--no-numpy
- env: PYTHON=python DOC=1
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- scons
- 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).
- rm -rf $HOME/Boost
- |
set -e
if [ ! -d $HOME/Boost ]; then
echo "rebuilding Boost prerequisites"
wget https://sourceforge.net/projects/boost/files/boost/1.61.0/boost_1_61_0.tar.gz/download
tar xf download
pushd boost_1_61_0
./bootstrap.sh
./b2 tools/bcp
mkdir -p $HOME/Boost
dist/bin/bcp python tools/boostbook tools/quickbook $HOME/Boost &> /dev/null
popd
fi
before_script:
- scons --version
script:
- scons config --python=$PYTHON --boost-include=$HOME/Boost $OPTIONS
- if [ "$DOC" ]; then scons doc; else scons && scons test; 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()

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.
@@ -27,27 +29,14 @@ While Boost.Python is part of the Boost C++ Libraries super-project, and thus ca
* [Python](http://www.python.org)
* [Boost](http://www.boost.org)
* [SCons](http://www.scons.org)
## Configure
Simply run
```
scons config [options]
```
to prepare a build. See `scons -h` for a description of the available options. For example
```
scons config --boost=/path/to/boost --python=/path/to/python
```
will configure Boost.Python to be built against the two specific versions of Boost and Python.
* [Faber](https://stefanseefeld.github.io/faber)
## Build
Run
```
scons
faber
```
to build the library.
@@ -56,7 +45,7 @@ to build the library.
Run
```
scons test
faber test.report
```
to run the tests.
@@ -65,6 +54,6 @@ to run the tests.
Run
```
scons doc
faber doc.html
```
to build the documentation.

View File

@@ -1,101 +0,0 @@
# -*- python -*-
#
# 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)
import SCons.Script.Main
import config
import config.ui
import platform
import os
import subprocess
import re
#
# We try to mimic the typical autotools-workflow.
#
# * In a 'configure' step all the essential build parameters are established
# (either by explicit command-line arguments or from configure checks)
# * A subsequent build step can then simply read the cached variables, so
# users don't have to memorize and re-issue the arguments on each subsequent
# invocation, and neither do the config checks need to be re-run.
#
# The essential part here is to define a 'config' target, which removes any
# caches that may still be lingering around, then runs the checks.
if 'config' in COMMAND_LINE_TARGETS:
# Clear the cache
try: os.remove('bin.SCons/config.py')
except: pass
if not os.path.exists('bin.SCons/'):
os.mkdir('bin.SCons/')
vars = Variables('bin.SCons/config.py', ARGUMENTS)
config.add_options(vars)
arch = ARGUMENTS.get('arch', platform.machine())
env_vars = {}
if 'CXX' in os.environ: env_vars['CXX'] = os.environ['CXX']
if 'CXXFLAGS' in os.environ: env_vars['CXXFLAGS'] = os.environ['CXXFLAGS'].split()
env_vars['ENV'] = os.environ #{'PATH': os.environ['PATH'], 'TMP' : os.environ['TMP']}
env = Environment(toolpath=['config/tools'],
tools=['default', 'libs', 'tests', 'doc', 'sphinx4scons'],
variables=vars,
TARGET_ARCH=arch,
**env_vars)
if 'gcc' in env['TOOLS']:
# Earlier SCons versions (~ 2.3.0) can't handle CXX=clang++.
version = subprocess.check_output([env['CXX'], '--version'])
match = re.search(r'[0-9]+(\.[0-9]+)+', version)
if match:
version = match.group(0)
else:
version = 'unknown'
env['CXXVERSION'] = version
Help(config.ui.help(vars, env) + """
Variables are saved in bin.SCons/config.py and persist between scons invocations.
""")
if GetOption('help'):
Return()
build_dir = config.prepare_build_dir(env)
config_log = '{}/config.log'.format(build_dir)
# configure
SConsignFile('{}/.sconsign'.format(build_dir))
#env.Decider('MD5-timestamp')
env.Decider('timestamp-newer')
checks = config.get_checks(env)
if 'config' in COMMAND_LINE_TARGETS:
conf=env.Configure(custom_tests=checks, log_file=config_log, conf_dir=build_dir)
if False in (getattr(conf, c)() for c in checks):
Exit(1)
env = conf.Finish()
vars.Save('bin.SCons/config.py', env)
if not os.path.exists(config_log):
print('Please run `scons config` first. (See `scons -h` for available options.)')
Exit(1)
if not GetOption('verbose'):
config.ui.pretty_output(env)
# build
env['BPL_VERSION'] = '1.65'
for e in config.variants(env):
variant_dir=e.subst("$BOOST_CURRENT_VARIANT_DIR")
e.SConscript('src/SConscript', variant_dir=variant_dir + '/src',
exports = { 'env' : e.Clone(BOOST_LIB = 'python') })
if 'test' in COMMAND_LINE_TARGETS:
test_env = e.Clone(BOOST_LIB = 'python', BOOST_TEST = True)
test_env.BoostUseLib('python')
e.SConscript('test/SConscript', variant_dir=variant_dir + '/test',
exports = { 'env' : test_env })
if 'doc' in COMMAND_LINE_TARGETS:
env.SConscript('doc/SConscript', variant_dir='bin.SCons/doc',
exports = { 'env' : e.Clone(BOOST_LIB = 'python') })

View File

@@ -1,100 +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_60_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"
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:\\Python35-x64"
# PYTHON_VERSION: "3.5.x" # currently 3.4.3
# PYTHON_ARCH: "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
- easy_install scons
- easy_install sphinx
- pip install numpy
#- "%CMD_IN_ENV% pip install -r dev-requirements.txt"
build_script:
# Build the compiled extension
#- "%CMD_IN_ENV% python setup.py build"
- scons config arch=%ARCH% --boost-include=%BOOST_PREFIX%
- scons arch=%ARCH% --verbose
test_script:
# Run the project tests
#- "%CMD_IN_ENV% python setup.py nosetests"
- scons test arch=%ARCH% --verbose
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

@@ -7,7 +7,6 @@ import indirect ;
import modules ;
import feature ;
import property ;
import python ;
if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
@@ -31,9 +30,6 @@ else
;
}
py2-version = [ py-version 2 ] ;
py3-version = [ py-version 3 ] ;
project boost/python
: source-location ../src
;
@@ -42,146 +38,130 @@ rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { retu
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
local rule eq ( a : b ) { if $(a) = $(b) { return 1 ; } }
lib_boost_python(2) = boost_python ;
lib_boost_python(3) = boost_python3 ;
lib boost_python
: # sources
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
lib_boost_python($(py2-version)) = $(lib_boost_python(2)) ;
lib_boost_python($(py3-version)) = $(lib_boost_python(3)) ;
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
object/enum.cpp
object/class.cpp
object/function.cpp
object/inheritance.cpp
object/life_support.cpp
object/pickle_support.cpp
errors.cpp
module.cpp
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object/stl_iterator.cpp
object_protocol.cpp
object_operators.cpp
wrapper.cpp
import.cpp
exec.cpp
object/function_doc_signature.cpp
: # requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<define>BOOST_PYTHON_SOURCE
rule lib_boost_python ( version )
# On Windows, all code using Python has to link to the Python
# import library.
#
# On *nix we never link libboost_python to libpython. When
# extending Python, all Python symbols are provided by the
# Python interpreter executable. When embedding Python, the
# client executable is expected to explicitly link to
# /python//python (the target representing libpython) itself.
#
# python_for_extensions is a target defined by Boost.Build to
# provide the Python include paths, and on Windows, the Python
# import library, as usage requirements.
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
# we prevent building when there is no python available
# as it's not possible anyway, and to cause dependents to
# fail to build
[ unless [ python.configured ] : <build>no ]
<dependency>config-warning
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@python-tag
<conditional>@python.require-py
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
numpy-include = [ python.numpy-include ] ;
lib boost_numpy
: # sources
numpy/dtype.cpp
numpy/matrix.cpp
numpy/ndarray.cpp
numpy/numpy.cpp
numpy/scalars.cpp
numpy/ufunc.cpp
: # requirements
<link>static:<define>BOOST_NUMPY_STATIC_LIB
<define>BOOST_NUMPY_SOURCE
[ cond [ python.numpy ] : <library>/python//python_for_extensions ]
[ unless [ python.numpy ] : <build>no ]
<library>/python//numpy
<library>boost_python
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@python-tag
<conditional>@python.require-py
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_NUMPY_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
# boost-install creates `stage` and `install` targets
#
# `stage` stages (builds and copies into `stage/lib`) the given libraries
# `boost_python` and `boost_numpy` and their dependencies and is similar
# to issuing `b2 --with-python stage` from top level
#
# `install` installs the two libraries and their dependencies and is similar
# to issuing `b2 --with-python install` from top level
if [ python.configured ]
{
lib $(lib_boost_python($(version)))
: # sources
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
object/enum.cpp
object/class.cpp
object/function.cpp
object/inheritance.cpp
object/life_support.cpp
object/pickle_support.cpp
errors.cpp
module.cpp
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object/stl_iterator.cpp
object_protocol.cpp
object_operators.cpp
wrapper.cpp
import.cpp
exec.cpp
object/function_doc_signature.cpp
: # requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<define>BOOST_PYTHON_SOURCE
# On Windows, all code using Python has to link to the Python
# import library.
#
# On *nix we never link libboost_python to libpython. When
# extending Python, all Python symbols are provided by the
# Python interpreter executable. When embedding Python, the
# client executable is expected to explicitly link to
# /python//python (the target representing libpython) itself.
#
# python_for_extensions is a target defined by Boost.Build to
# provide the Python include paths, and on Windows, the Python
# import library, as usage requirements.
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
# we prevent building when there is no python available
# as it's not possible anyway, and to cause dependents to
# fail to build
[ unless [ python.configured ] : <build>no ]
<dependency>config-warning
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
<python>$(version)
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).python-tag
<conditional>@python.require-py
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
}
lib_boost_numpy(2) = boost_numpy ;
lib_boost_numpy(3) = boost_numpy3 ;
lib_boost_numpy($(py2-version)) = $(lib_boost_numpy(2)) ;
lib_boost_numpy($(py3-version)) = $(lib_boost_numpy(3)) ;
rule lib_boost_numpy ( version )
{
numpy-include = [ python.numpy-include ] ;
lib $(lib_boost_numpy($(version)))
: # sources
numpy/dtype.cpp
numpy/matrix.cpp
numpy/ndarray.cpp
numpy/numpy.cpp
numpy/scalars.cpp
numpy/ufunc.cpp
: # requirements
<link>static:<define>BOOST_NUMPY_STATIC_LIB
<define>BOOST_NUMPY_SOURCE
[ cond [ python.numpy ] : <library>/python//python_for_extensions ]
[ unless [ python.numpy ] : <build>no ]
<include>$(numpy-include)
<library>$(lib_boost_python($(version)))
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
<python>$(version)
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).python-tag
<conditional>@python.require-py
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_NUMPY_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
}
libraries = ;
for local N in 2 3
{
if $(py$(N)-version)
if [ python.numpy ]
{
lib_boost_python $(py$(N)-version) ;
libraries += $(lib_boost_python($(py$(N)-version))) ;
boost-install boost_python boost_numpy ;
}
else
{
alias $(lib_boost_python($(N))) ;
}
if $(py$(N)-version) && [ python.numpy ]
{
lib_boost_numpy $(py$(N)-version) ;
libraries += $(lib_boost_numpy($(py$(N)-version))) ;
}
else
{
alias $(lib_boost_numpy($(N))) ;
boost-install boost_python ;
}
}
else
{
boost-install $(libraries) ;
# When Python isn't configured, the above `boost-install` is not executed,
# so we create empty `stage` and `install` targets that do nothing but issue
# a warning message unless `--without-python` is given
alias stage : config-warning ;
explicit stage ;
alias install : config-warning ;
explicit install ;
}

View File

@@ -1,140 +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)
from SCons.Variables import *
from SCons.Script import AddOption
from collections import OrderedDict
import platform
from . import ui
from . import cxx
from . import python
from . import numpy
from . import boost
def add_options(vars):
ui.add_option('-V', '--verbose', dest='verbose', action='store_true', help='verbose mode: print full commands.')
ui.add_option('--no-numpy', dest='numpy', action='store_false', help='do not attempt to build NumPy bindings.')
python.add_options(vars)
numpy.add_options(vars)
boost.add_options(vars)
vars.Add('CXX')
vars.Add('CPPPATH', converter=lambda v:v.split())
vars.Add('CCFLAGS', converter=lambda v:v.split())
vars.Add('CXXFLAGS', converter=lambda v:v.split())
vars.Add('LIBPATH', converter=lambda v:v.split())
vars.Add('LIBS', converter=lambda v:v.split())
vars.Add('PYTHON')
vars.Add('PYTHONLIBS')
vars.Add('prefix')
vars.Add('boostbook_prefix')
vars.Add('CXX11')
vars.Add('NUMPY')
vars.Add('NUMPY_CPPPATH', converter=lambda v:v.split())
ui.add_variable(vars, ("arch", "target architeture", platform.machine()))
ui.add_variable(vars, ("toolchain", "toolchain to use", 'gcc'))
ui.add_variable(vars, ListVariable("variant", "Build configuration", "release", ["release", "debug", "profile"]))
ui.add_variable(vars, ListVariable("link", "Library linking", "dynamic", ["static", "dynamic"]))
ui.add_variable(vars, ListVariable("threading", "Multi-threading support", "multi", ["single", "multi"]))
ui.add_variable(vars, EnumVariable("layout", "Layout of library names and header locations", "versioned", ["versioned", "system"]))
ui.add_variable(vars, PathVariable("stagedir", "If --stage is passed install only compiled library files in this location", "stage", PathVariable.PathAccept))
ui.add_variable(vars, PathVariable("prefix", "Install prefix", "/usr/local", PathVariable.PathAccept))
def get_checks(env):
checks = OrderedDict()
checks['cxx'] = cxx.check
checks['python'] = python.check
if env.GetOption('numpy') is not False:
checks['numpy'] = numpy.check
else:
env['NUMPY'] = False
checks['boost'] = boost.check
return checks
def set_property(env, **kw):
from toolchains.gcc import features as gcc_features
from toolchains.msvc import features as msvc_features
if 'gcc' in env['TOOLS']: features = gcc_features
elif 'msvc' in env['TOOLS']: features = msvc_features
else: raise Error('unknown toolchain')
features.init_once(env)
for (prop,value) in kw.items():
getattr(features, prop, lambda x, y : None)(env, value)
env[prop.upper()] = value
def boost_suffix(env):
suffix = str()
if env["layout"] == "versioned":
if "gcc" in env["TOOLS"]:
if env['CXX'] in ('clang', 'clang++'):
suffix += "-clang" + "".join(env["CXXVERSION"].split(".")[0:2])
else: # assume g++
suffix += "-gcc" + "".join(env["CXXVERSION"].split(".")[0:2])
if env["THREADING"] == "multi":
suffix += "-mt"
if env["DEBUG"]:
suffix += "-d"
if env["layout"] == "versioned":
suffix += "-" + "_".join(env["BPL_VERSION"].split("."))
return suffix
def prepare_build_dir(env):
vars = {}
env["boost_suffix"] = boost_suffix
build_dir="bin.SCons"
# FIXME: Support 'toolchain' variable properly.
# For now, we simply check whether $CXX refers to clang or gcc.
if "gcc" in env["TOOLS"]:
if env['CXX'] in ('clang', 'clang++'):
build_dir+="/clang-%s"%env["CXXVERSION"]
else: # assume g++
build_dir+="/gcc-%s"%env["CXXVERSION"]
default_cxxflags = ['-ftemplate-depth-128', '-Wall', '-g', '-O2']
vars['CXXFLAGS'] = env.get('CXXFLAGS', default_cxxflags)
elif "msvc" in env["TOOLS"]:
build_dir+="/msvc-%s"%env["MSVS_VERSION"]
vars['BOOST_BUILD_DIR'] = build_dir
vars['BOOST_SUFFIX'] = "${boost_suffix(__env__)}"
env.Replace(**vars)
return build_dir
def variants(env):
env.Prepend(CPPPATH = "#/include", CPPDEFINES = ["BOOST_ALL_NO_LIB=1"])
set_property(env, architecture = env['TARGET_ARCH'])
for variant in env["variant"]:
e = env.Clone()
e["current_variant"] = variant
set_property(env, profile = False)
if variant == "release":
set_property(e, optimize = "speed", debug = False)
elif variant == "debug":
set_property(e, optimize = "no", debug = True)
elif variant == "profile":
set_property(e, optimize = "speed", profile = True, debug = True)
for linking in env["link"]:
e["linking"] = linking
if linking == "dynamic":
e["LINK_DYNAMIC"] = True
else:
e["LINK_DYNAMIC"] = False
for threading in e["threading"]:
e["current_threading"] = threading
set_property(e, threading = threading)
yield e

View File

@@ -1,45 +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)
from . import ui
import os
def add_options(vars):
ui.add_option("--boost-prefix", dest="boost_prefix", type="string", nargs=1, action="store",
metavar="DIR", default=os.environ.get("BOOST_DIR"),
help="prefix for Boost libraries; should have 'include' and 'lib' subdirectories, 'boost' and 'stage\\lib' subdirectories on Windows")
ui.add_option("--boost-include", dest="boost_include", type="string", nargs=1, action="store",
metavar="DIR", help="location of Boost header files")
ui.add_option("--boostbook-prefix", dest="boostbook_prefix", type="string",
nargs=1, action="store",
metavar="DIR", default="/usr/share/boostbook",
help="prefix for BoostBook stylesheets")
def check(context):
boost_source_file = r"#include <boost/config.hpp>"
context.Message('Checking for Boost...')
boost_prefix = context.env.GetOption('boost_prefix')
boost_include = context.env.GetOption('boost_include')
boostbook_prefix = context.env.GetOption('boostbook_prefix')
incpath=None
if boost_include:
incpath=boost_include
elif boost_prefix:
incpath=boost_prefix
if incpath:
context.env.AppendUnique(CPPPATH=[incpath])
if not context.TryCompile(boost_source_file, '.cpp'):
context.Result(0)
return False
context.env.AppendUnique(boostbook_prefix=boostbook_prefix)
context.Result(1)
return True

View File

@@ -1,30 +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)
from . import ui
import os
def add_options(vars):
pass
def check(context):
source = r"""#if __cplusplus < 201103L
#error no C++11
#endif"""
context.Message('Checking for C++11 support...')
if not context.TryCompile(source, '.cpp'):
context.env['CXX11'] = False
context.Result(0)
else:
context.env['CXX11'] = True
context.Result(1)
return True

View File

@@ -1,86 +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)
from . import ui
from contextlib import contextmanager
@contextmanager
def saved(context):
save_cpppath = context.env.get('CPPPATH', [])
save_libs = context.env.get('LIBS', [])
yield context
context.env.Replace(LIBS=save_libs)
context.env.Replace(CPPPATH=save_cpppath)
def add_options(vars):
pass
def check(context):
numpy_source_file = r"""
// If defined, enforces linking againg PythonXXd.lib, which
// is usually not included in Python environments.
#undef _DEBUG
#include "Python.h"
#include "numpy/arrayobject.h"
#if PY_VERSION_HEX >= 0x03000000
void *initialize() { import_array();}
#else
void initialize() { import_array();}
#endif
int main()
{
int result = 0;
Py_Initialize();
initialize();
if (PyErr_Occurred())
{
result = 1;
}
else
{
npy_intp dims = 2;
PyObject * a = PyArray_SimpleNew(1, &dims, NPY_INT);
if (!a) result = 1;
Py_DECREF(a);
}
Py_Finalize();
return result;
}
"""
import platform
import subprocess
import re, os
def check_python(cmd):
try:
return True, subprocess.check_output([python, '-c', cmd]).strip()
except subprocess.CalledProcessError as e:
return False, e
context.Message('Checking for NumPy...')
with saved(context):
python = context.env['PYTHON']
result, numpy_incpath = check_python('import numpy; print(numpy.get_include())')
if result:
context.env.AppendUnique(CPPPATH=numpy_incpath)
context.env.AppendUnique(LIBS=context.env['PYTHONLIBS'])
result, output = context.TryRun(numpy_source_file,'.cpp')
if not result:
context.Result(0)
return False
context.env['NUMPY'] = True
context.env['NUMPY_CPPPATH'] = numpy_incpath
context.Result(1)
return True

View File

@@ -1,98 +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)
from . import ui
def add_options(vars):
ui.add_option('--python', help='the python executable')
def check(context):
python_source_file = r"""
// If defined, enforces linking againg PythonXXd.lib, which
// is usually not included in Python environments.
#undef _DEBUG
#include "Python.h"
int main()
{
Py_Initialize();
Py_Finalize();
return 0;
}
"""
import platform
import subprocess
import re, os
def check_python(cmd):
return subprocess.check_output([python, '-c', cmd]).strip()
def check_sysconfig(cmd):
r = check_python('import distutils.sysconfig as c; print(c.%s)'%cmd)
return r if r != 'None' else ''
context.Message('Checking for Python...')
python = context.env.GetOption('python') or 'python'
context.env['PYTHON'] = python
incpath = check_sysconfig('get_python_inc()')
context.env.AppendUnique(CPPPATH=[incpath])
if platform.system() == 'Windows':
version = check_python('import sys; print("%d%d"%sys.version_info[0:2])')
prefix = check_python('import sys; print(sys.prefix)')
libfile = os.path.join(prefix, 'libs', 'python%s.lib'%version)
libpath = os.path.join(prefix, 'libs')
lib = 'python%s'%version
context.env.AppendUnique(LIBS=[lib])
else:
libpath = check_sysconfig('get_config_var("LIBDIR")')
libfile = check_sysconfig('get_config_var("LIBRARY")')
match = re.search('(python.*)\.(a|so|dylib)', libfile)
lib = None
if match:
lib = match.group(1)
context.env.AppendUnique(PYTHONLIBS=[lib])
if match.group(2) == 'a':
flags = check_sysconfig('get_config_var("LINKFORSHARED")')
if flags is not None:
context.env.AppendUnique(LINKFLAGS=flags.split())
context.env.AppendUnique(LIBPATH=[libpath])
oldlibs = context.AppendLIBS([lib])
flags = check_sysconfig('get_config_var("MODLIBS")')
flags += ' ' + check_sysconfig('get_config_var("SHLIBS")')
flags = [f[2:] for f in flags.strip().split() if f.startswith('-l')]
if flags:
context.AppendLIBS([flags])
result = context.TryLink(python_source_file,'.cpp')
if not result and context.env['PLATFORM'] == 'darwin':
# Sometimes we need some extra stuff on Mac OS
frameworkDir = libpath # search up the libDir tree for the proper home for frameworks
while frameworkDir and frameworkDir != "/":
frameworkDir, d2 = os.path.split(frameworkDir)
if d2 == "Python.framework":
if not "Python" in os.listdir(os.path.join(frameworkDir, d2)):
context.Result(0)
print((
"Expected to find Python in framework directory %s, but it isn't there"
% frameworkDir))
return False
break
context.env.AppendUnique(LINKFLAGS="-F%s" % frameworkDir)
result = context.TryLink(python_source_file,'.cpp')
if not result:
context.Result(0)
print("Cannot link program with Python.")
return False
if context.env['PLATFORM'] == 'darwin':
context.env['LDMODULESUFFIX'] = '.so'
context.Result(1)
context.SetLIBS(oldlibs)
context.env.AppendUnique(PYTHONLIBS=[lib] + flags)
return True

View File

@@ -1,18 +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)
import traceback
def append_feature_flag(env, **kw):
stack = traceback.extract_stack(limit = 3)
feature = stack[0][2].upper()
for (key, val) in kw.items():
feature_var = feature + "_" + key
env.AppendUnique(**{ key : "$" + feature_var })
env[feature_var] = val

View File

@@ -1,55 +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)
from . import append_feature_flag
class features:
@classmethod
def init_once(cls, env):
pass
@staticmethod
def architecture(env, arch):
if arch:
flag = {'x86' : '-m32',
'x86_64' : '-m64',}.get(arch)
if flag:
append_feature_flag(env, CCFLAGS = flag)
@staticmethod
def optimize(env, optimize):
if not optimize or optimize == "no":
append_feature_flag(env, CCFLAGS = "-O0 -fno-inline")
elif optimize == "speed":
append_feature_flag(env, CCFLAGS = "-O3 -finline-functions -Wno-inline")
elif optimize == "space":
append_feature_flag(env, CCFLAGS = "-Os")
else:
append_feature_flag(env, CCFLAGS = "")
@staticmethod
def profile(env, profile):
if profile:
append_feature_flag(env, CCFLAGS = "-pg", LINKFLAGS = "-pg")
else:
append_feature_flag(env, CCFLAGS = "", LINKFLAGS = "")
@staticmethod
def threading(env, threading):
if threading == "multi":
append_feature_flag(env, CCFLAGS = "-pthread", LINKFLAGS = "-pthread")
else:
append_feature_flag(env, CCFLAGS = "", LINKFLAGS = "")
@staticmethod
def debug(env, debug):
if debug:
append_feature_flag(env, CCFLAGS = "-g", CPPDEFINES = [])
else:
append_feature_flag(env, CCFLAGS = "", CPPDEFINES = "NDEBUG")

View File

@@ -1,57 +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)
from . import append_feature_flag
class features:
@classmethod
def init_once(cls, env):
env.AppendUnique(CCFLAGS = ['-TP', '/Z7', '/W3' ,'/GR', '/MDd', '/Zc:forScope', '/Zc:wchar_t', '/wd4675', '/EHs'])
env.AppendUnique(LINKFLAGS = ['/subsystem:console'])
@staticmethod
def architecture(env, arch):
if arch:
flag = {'x86' : '/MACHINE:X86',
'x86_64' : '/MACHINE:X64',}.get(arch)
if flag:
append_feature_flag(env, LINKFLAGS = flag)
@staticmethod
def optimize(env, optimize):
#if not optimize or optimize == "no":
# append_feature_flag(env, CCFLAGS = "-O0 -fno-inline")
#elif optimize == "speed":
# append_feature_flag(env, CCFLAGS = "-O3 -finline-functions -Wno-inline")
#elif optimize == "space":
# append_feature_flag(env, CCFLAGS = "-Os")
#else:
append_feature_flag(env, CCFLAGS = "")
@staticmethod
def profile(env, profile):
#if profile:
# append_feature_flag(env, CCFLAGS = "-pg", LINKFLAGS = "-pg")
#else:
append_feature_flag(env, CCFLAGS = "", LINKFLAGS = "")
@staticmethod
def threading(env, threading):
#if threading == "multi":
# append_feature_flag(env, CCFLAGS = "/MT")
#else:
# append_feature_flag(env, CCFLAGS = "", LINKFLAGS = "")
pass
@staticmethod
def debug(env, debug):
#if debug:
# append_feature_flag(env, CCFLAGS = "-g", CPPDEFINES = [])
#else:
append_feature_flag(env, CCFLAGS = "", CPPDEFINES = "NDEBUG")

View File

@@ -1,44 +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)
# Based on SCons/Tool/gcc.py
import os
import re
import subprocess
import SCons.Util
import SCons.Tool.cc
compilers = ['clang']
def generate(env):
"""Add Builders and construction variables for clang to an Environment."""
SCons.Tool.cc.generate(env)
env['CC'] = env.Detect(compilers) or 'clang'
if env['PLATFORM'] in ['cygwin', 'win32']:
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
else:
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC')
# determine compiler version
if env['CC']:
#pipe = SCons.Action._subproc(env, [env['CC'], '-dumpversion'],
pipe = SCons.Action._subproc(env, [env['CC'], '--version'],
stdin = 'devnull',
stderr = 'devnull',
stdout = subprocess.PIPE)
if pipe.wait() != 0: return
# clang -dumpversion is of no use
line = pipe.stdout.readline()
match = re.search(r'clang +version +([0-9]+(?:\.[0-9]+)+)', line)
if match:
env['CCVERSION'] = match.group(1)
def exists(env):
return env.Detect(compilers)

View File

@@ -1,75 +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)
from SCons.Script import AddOption, Flatten
from SCons.Script import Builder
from SCons.Action import Action
from SCons.Defaults import Copy
from SCons.Script import *
from subprocess import check_output, STDOUT, CalledProcessError
import sys
import os
def QuickBook(env, target, source, dependencies=[]):
"""Compile a QuickBook document to BoostBook."""
for d in dependencies:
env.Depends(target, d)
env.Command(target, source, 'quickbook --input-file=$SOURCE --output-file=$TARGET')
def BoostBook(env, target, source, resources=[], args=[]):
"""Compile a BoostBook document to DocBook."""
bb_prefix = env.GetOption('boostbook_prefix')
stylesheet = bb_prefix + '/xsl/docbook.xsl'
env.Command(target, source,
'xsltproc {} -o $TARGET {} $SOURCE'.format(' '.join(args), stylesheet))
def BoostHTML(env, target, source, resources=[], args=[]):
"""Compile a DocBook document to HTML."""
bb_prefix = env.GetOption('boostbook_prefix')
stylesheet = bb_prefix + '/xsl/html.xsl'
env.Command(target, source,
'xsltproc {} -o $TARGET/ {} $SOURCE'.format(' '.join(args), stylesheet))
prefix=Dir('.').path
for r in resources:
r = File(r).path[len(prefix)+1:]
env.Depends(target, target + r)
env.Command(target + r, r, Copy('$TARGET', '$SOURCE'))
def BoostRST(env, target, source, resources=[]):
"""Compile an RST document to HTML."""
prefix=Dir('.').path
for r in resources:
r = File(r).path[len(prefix)+1:]
env.Depends('html/' + r, r)
env.Command('html/' + r, r, Copy('$TARGET', '$SOURCE'))
env.Command(target, source,
'rst2html --link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript --stylesheet=rst.css $SOURCE $TARGET')
def BoostSphinx(env, target, source):
env.Sphinx(target, source)
def exists(env):
return True
def generate(env):
env.AddMethod(QuickBook)
env.AddMethod(BoostBook)
env.AddMethod(BoostHTML)
env.AddMethod(BoostRST)
env.AddMethod(BoostSphinx)

View File

@@ -1,85 +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)
from SCons.Script import AddOption, COMMAND_LINE_TARGETS, BUILD_TARGETS
import distutils.sysconfig
import platform
def BoostLibrary(env, lib, sources, make_aliases = True, **kw):
if env["LINK_DYNAMIC"]:
lib_node = env.SharedLibrary("boost_" + lib + env["BOOST_SUFFIX"], sources, **kw)
else:
lib_node = env.StaticLibrary("boost_" + lib + env["BOOST_SUFFIX"], sources, **kw)
if make_aliases:
if env.GetOption("stage"):
env.Alias(lib, env.Install(env.Dir("$stagedir", "#"), lib_node))
env.Default(env.Alias(lib, lib_node))
if env.GetOption("install"):
env.Alias(lib, env.Install("$prefix/lib", lib_node))
env.Alias(lib, env.Install('$prefix/include/boost', '#/include/boost/python'))
env.Alias(lib, env.Install('$prefix/include/boost', '#/include/boost/python.hpp'))
return lib_node
def BoostUseLib(env, lib):
build_dir = env.Dir('$BOOST_CURRENT_VARIANT_DIR/src')
env.AppendUnique(LIBPATH = [build_dir],
LIBS = ["boost_" + lib + env["BOOST_SUFFIX"]])
if env.get("BOOST_TEST"):
env.AppendUnique(RPATH = [build_dir])
if platform.system() == 'Windows':
env.PrependENVPath('PATH', build_dir.abspath)
else:
env.PrependENVPath('LD_LIBRARY_PATH', build_dir.abspath)
def PythonExtension(env, lib, sources, **kw):
if env["LINK_DYNAMIC"]:
ext = env.SharedLibrary(lib, sources, SHLIBPREFIX='', SHLIBSUFFIX=distutils.sysconfig.get_config_var("SO"), **kw)
return ext
def boost_copy_func(dest, source, env):
import os, stat, shutil
if os.path.isdir(source):
if os.path.exists(dest):
if not os.path.isdir(dest):
raise SCons.Errors.UserError, "cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source))
else:
os.makedirs(dest)
for file in os.listdir(source):
if file == ".svn": continue
boost_copy_func(os.path.join(dest, file), os.path.join(source, file), env)
else:
shutil.copy2(source, dest)
st = os.stat(source)
os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
return 0
def exists(env):
return True
def generate(env):
env.AddMethod(BoostLibrary)
env.AddMethod(BoostUseLib)
env.AddMethod(PythonExtension)
env.Replace(
INSTALL = boost_copy_func,
BOOST_CURRENT_VARIANT_DIR = "#/$BOOST_BUILD_DIR/$current_variant/$linking/threading-$current_threading"
)
AddOption('--stage', dest='stage', action="store_true")
AddOption('--install', dest='install', action="store_true")

View File

@@ -1,592 +0,0 @@
"""SCons.Tool.spinx4scons
Tool-specific initialization for the Sphinx document build system.
There normally shouldn't be any need to import this module directly.
It will usually be imported through the generic SCons.Tool.Tool()
selection method.
It should be placed in e.g. ~/site_scons/site_tools/sphinx4scons/
directory. Then it may be loaded by placing
sphinx = Tool('sphinx4scons')
sphinx(env)
in your SConstruct file.
For further details, please see the SCons documentation on how to
install and enable custom tools.
"""
#
# This package is provided under the Expat license
#
# Copyright (c) 2012 Orlando Wingbrant
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
__author__ = "Orlando Wingbrant"
__email__ = "orlando@widesite.org"
__url__ = "https://bitbucket.org/wingbrant/sphinx4scons"
__license__ = "Expat license"
import SCons.Action
import SCons.Builder
import SCons.Defaults
import SCons.Util
import SCons.Node.FS
import os
from sphinx.util.matching import patfilter, compile_matchers
from sphinx.util.osutil import make_filename
class ToolSphinxWarning(SCons.Warnings.Warning):
pass
class SphinxBuilderNotFound(ToolSphinxWarning):
pass
SCons.Warnings.enableWarningClass(ToolSphinxWarning)
def exists(env):
return _detect(env)
def _detect(env):
"""Try to detect the sphinx-build script."""
try:
return env['SPHINXBUILD']
except KeyError:
pass
sphinx = env.WhereIs('sphinx-build')
if sphinx:
return sphinx
raise SCons.Errors.StopError(
SphinxBuilderNotFound,
"Could not detect sphinx-build script")
return None
def generate(env):
"""Add Builders and construction variables to the Environment."""
env['SPHINXBUILD'] = _detect(env)
sphinx = _create_sphinx_builder(env)
env.SetDefault(
# Additional command-line flags
SPHINXFLAGS = '',
# Tag definitions, each entry will appear on the command line preceded by -t
SPHINXTAGS = [],
# Directory for doctrees
SPHINXDOCTREE = '',
# Path to sphinx configuration file
SPHINXCONFIG = '',
# Config file override settings, each entry will be preceded by -D
SPHINXSETTINGS = {},
# Default sphinx builder,
SPHINXBUILDER = 'html',
# Sphinx command
SPHINXCOM = "$SPHINXBUILD $_SPHINXOPTIONS ${SOURCE.attributes.root} ${TARGET.attributes.root}",
# Alternate console output when building sphinx documents
SPHINXCOMSTR = ""
)
try:
env.AddMethod(Sphinx, "Sphinx")
except AttributeError:
# Looks like we use a pre-0.98 version of SCons...
from SCons.Script.SConscript import SConsEnvironment
SConsEnvironment.Sphinx = Sphinx
def Sphinx(env, target, source, **kw):
"""A pseudo-builder wrapper for the sphinx builder."""
builder = env['BUILDERS']['Sphinx4Scons']
env_kw = env.Override(kw)
options = _get_sphinxoptions(env_kw, target, source)
output = builder(env, target, source, _SPHINXOPTIONS=options, **kw)
return output
def _get_sphinxoptions(env, target, source):
"""Concatenates all the options for the sphinx command line."""
options = []
builder = _get_sphinxbuilder(env)
options.append("-b %s" % env.subst(builder, target=target, source=source))
flags = env.get('options', env.get('SPHINXFLAGS', ''))
options.append(env.subst(flags, target=target, source=source))
tags = env.get('tags', env.get('SPHINXTAGS', None))
if tags is not None:
if not SCons.SCons.Util.is_List(tags):
tags = [tags]
for tag in tags:
if tag != '':
tag = env.subst(tag, target=target, source=source)
options.append("-t %s" % tag)
settings = env.get('settings', env.get('SPHINXSETTINGS', None))
if settings is not None:
if not SCons.SCons.Util.is_Dict(settings):
raise TypeError('SPHINXSETTINGS and/or settings argument must be a dictionary')
for key, value in settings.iteritems():
if value != '':
value = env.subst(value, target=target, source=source)
options.append('-D "%s=%s"' % (key, value))
doctree = env.get('doctree', env.get("SPHINXDOCTREE", None))
if isinstance(doctree, SCons.Node.FS.Dir):
options.append("-d %s" % doctree.get_abspath())
elif doctree is not None and doctree != '':
doctree = env.subst(doctree, target=target, source=source)
options.append("-d %s" % env.Dir(doctree).get_abspath())
config = _get_sphinxconfig_path(env, None)
if config is not None and config != '':
config = env.subst(config, target=target, source=source)
options.append("-c %s" % env.Dir(config).File('conf.py').rfile().dir.get_abspath())
return " ".join(options)
def _create_sphinx_builder(env):
try:
sphinx = env['BUILDERS']['Sphinx4Scons']
except KeyError:
fs = SCons.Node.FS.get_default_fs()
sphinx_com = SCons.Action.Action('$SPHINXCOM', '$SPHINXCOMSTR')
sphinx = SCons.Builder.Builder(action=sphinx_com,
emitter=sphinx_emitter,
target_factory=fs.Dir,
source_factory=fs.Dir
)
env['BUILDERS']['Sphinx4Scons'] = sphinx
return sphinx
def sphinx_emitter(target, source, env):
target[0].must_be_same(SCons.Node.FS.Dir)
targetnode = target[0]
source[0].must_be_same(SCons.Node.FS.Dir)
srcnode = source[0]
configdir = _get_sphinxconfig_path(env, None)
if not configdir:
confignode = srcnode
else:
confignode = env.Dir(configdir)
srcinfo = SourceInfo(srcnode, confignode, env)
targets, sources = _get_emissions(env, target, srcinfo)
env.Clean(targets, target[0])
return targets, sources
def sphinx_path(os_path):
"""Create sphinx-style path from os-style path."""
return os_path.replace(os.sep, "/")
def os_path(sphinx_path):
"""Create os-style path from sphinx-style path."""
return sphinx_path.replace("/", os.sep)
class SourceInfo(object):
"""
Data container for all different kinds of source files used in
a sphinx project.
"""
def __init__(self, srcnode, confignode, env):
self.confignode = confignode
self.config = self._get_config(self.confignode, env)
self.templates = self._get_templates(self.confignode, self.config)
self.statics = self._get_statics(self.confignode, self.config)
self.srcnode = srcnode
self.sources = self._get_sources(self.srcnode, self.config)
self.srcroot = srcnode
if not srcnode.duplicate:
self.srcroot = srcnode.srcnode().rdir()
def _get_config(self, confignode, env):
config = {}
execfile(confignode.File('conf.py').rfile().get_abspath(), config)
return config
def _get_templates(self, confignode, config):
"""Returns template files defined in the project."""
templates = []
for path in config.get('templates_path', []):
# Check if path is dir or file.
# We can't use FS.Entry since that will create nodes, and
# these nodes don't know about the source tree and will
# get disambiguated to files even if they are directories in the
# source tree.
p = confignode.File('conf.py').rfile().dir.srcnode().get_abspath()
p = os.path.join(p, os_path(path))
if os.path.isfile(p):
templates.append(confignode.File(path))
elif os.path.isdir(p):
node = confignode.Dir(path)
for root, dirs, files in os.walk(p):
mydir = node.Dir(os.path.relpath(root, p))
templates += [mydir.File(f) for f in files]
return templates
def _get_statics(self, confignode, config):
"""Returns static files, filtered through exclude_patterns."""
statics = []
matchers = compile_matchers(config.get('exclude_patterns', []))
for path in config.get('html_static_path', []):
# Check _get_templates() why we use this construction.
p = confignode.File('conf.py').rfile().dir.srcnode().get_abspath()
p = os.path.join(p, os_path(path))
if os.path.isfile(p):
statics.append(confignode.File(path))
elif os.path.isdir(p):
node = confignode.Dir(path)
for root, dirs, files in os.walk(p):
relpath = os.path.relpath(root, p)
for entry in [d for d in dirs if
self._anymatch(matchers,
sphinx_path(os.path.join(relpath, d)))]:
dirs.remove(entry)
statics += [node.File(os_path(f)) for f in
self._exclude(matchers,
[sphinx_path(os.path.join(relpath, name))
for name in files])]
return statics
def _get_sources(self, srcnode, config):
"""Returns all source files in the project filtered through exclude_patterns."""
suffix = config.get('source_suffix', '.rst')
matchers = compile_matchers(config.get('exclude_patterns', []))
srcfiles = []
scannode = srcnode.srcnode().rdir()
for root, dirs, files in os.walk(scannode.get_abspath()):
relpath = os.path.relpath(root, scannode.get_abspath())
for entry in [d for d in dirs if
self._anymatch(matchers,
sphinx_path(os.path.join(relpath, d)))]:
dirs.remove(entry)
srcfiles += [srcnode.File(os_path(f)) for f in
self._exclude(matchers,
[sphinx_path(os.path.join(relpath, name))
for name in files if name.endswith(suffix)])]
return srcfiles
def _exclude(self, matchers, items):
result = items
for matcher in matchers:
result = filter(lambda x: not matcher(x), result)
return result
def _anymatch(self, matchers, item):
for matcher in matchers:
if matcher(item):
return True
return False
def _get_sphinxconfig_path(env, default):
path = env.get('config', env.get('SPHINXCONFIG', None))
if path is None or path == '':
path = default
return path
def _get_emissions(env, target, srcinfo):
targets = []
sources = []
builder = _get_sphinxbuilder(env)
if builder == 'changes':
targets, sources = _get_changes_emissions(env, target, srcinfo)
if builder == 'devhelp':
targets, sources = _get_help_emissions(env, target, srcinfo,
['.devhelp.gz'])
elif builder == 'dirhtml':
targets, sources = _get_dirhtml_emissions(env, target, srcinfo)
elif builder == 'doctest':
targets, sources = _get_doctest_emissions(env, target, srcinfo)
elif builder == 'epub':
targets, sources = _get_epub_emissions(env, target, srcinfo)
elif builder == 'html':
targets, sources = _get_serialize_emissions(env, target, srcinfo)
elif builder == 'htmlhelp':
targets, sources = _get_help_emissions(env, target, srcinfo,
['.hhp'], 'htmlhelp_basename')
elif builder == 'gettext':
targets, sources = _get_gettext_emissions(env, target, srcinfo)
elif builder == 'json':
targets, sources = _get_serialize_emissions(env, target, srcinfo,
'.fjson',
['globalcontext.json',
'searchindex.json',
'self.environment.pickle'])
elif builder == 'latex':
targets, sources = _get_latex_emissions(env, target, srcinfo)
elif builder == 'linkcheck':
targets, sources = _get_linkcheck_emissions(env, target, srcinfo)
elif builder == 'man':
targets, sources = _get_man_emissions(env, target, srcinfo)
elif builder == 'pickle':
targets, sources = _get_serialize_emissions(env, target, srcinfo,
'.fpickle',
['globalcontext.pickle',
'searchindex.pickle',
'environment.pickle'])
elif builder == 'qthelp':
targets, sources = _get_help_emissions(env, target, srcinfo,
['.qhp', '.qhcp'])
elif builder == 'singlehtml':
targets, sources = _get_singlehtml_emissions(env, target, srcinfo)
elif builder == 'texinfo':
targets, sources = _get_texinfo_emissions(env, target, srcinfo)
elif builder == 'text':
targets, sources = _get_text_emissions(env, target, srcinfo)
sources.append(srcinfo.confignode.File('conf.py'))
for s in sources:
s.attributes.root = srcinfo.srcroot
for t in targets:
t.attributes.root = target[0]
return targets, sources
def _get_sphinxbuilder(env):
builder = env.get('builder', env["SPHINXBUILDER"])
if builder is None or builder == '':
raise SCons.Errors.UserError(("Missing construction variable " +
"SPHINXBUILDER or variable is empty."))
return builder
def _get_changes_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = [target[0].File("changes.html")]
return targets, sources
def _get_dirhtml_emissions(env, target, srcinfo):
suffix = srcinfo.config.get('html_file_suffix', ".html")
def get_outfilename(pagename):
pagename = os.path.splitext(pagename)[0]
#Special treatment of files named "index". Don't create directory.
if pagename == 'index' or pagename.endswith(os.sep + 'index'):
outfilename = pagename + suffix
else:
outfilename = os.path.join(pagename, 'index' + suffix)
return outfilename
sources = []
sources.extend(srcinfo.sources)
sources.extend(srcinfo.templates)
sources.extend(srcinfo.statics)
targets = []
for s in srcinfo.sources:
t = os.path.relpath(str(s), str(srcinfo.srcroot))
targets.append(target[0].File(get_outfilename(t)))
for key in srcinfo.config.get('html_additional_pages', {}):
t = target[0].File(get_outfilename(key))
targets.append(t)
return targets, sources
def _get_doctest_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = [target[0].File("output.txt")]
return targets, sources
def _get_epub_emissions(env, target, srcinfo):
epubPreFiles = srcinfo.config.get('epub_pre_files', [])
epubPostFiles = srcinfo.config.get('epub_post_files', [])
epubCover = srcinfo.config.get('epub_cover', (None, None))
sources = []
sources.extend(srcinfo.sources)
sources.extend([srcinfo.srcroot.File(os_path(f[0])) for f in epubPreFiles])
sources.extend([srcinfo.srcroot.File(os_path(f[0])) for f in epubPostFiles])
if not (epubCover[0] is None or epubCover[0] == ''):
sources.append(srcinfo.srcroot.File(os_path(epubCover[0])))
if not (epubCover[1] is None or epubCover[1] == ''):
sources.append(srcinfo.srcroot.File(os_path(epubCover[1])))
t = srcinfo.config.get('epub_basename',
srcinfo.config.get('project',
'Python'))
targets = [target[0].File("%s.epub" % make_filename(t))]
return targets, sources
def _get_gettext_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = [os.path.relpath(str(s), str(srcinfo.srcroot)) for s in sources]
targets = [os.path.splitext(t)[0] for t in targets]
targets = set([t.split(os.sep)[0] for t in targets])
targets = [target[0].File(t + ".pot") for t in targets]
return targets, sources
def _get_help_emissions(env, target, srcinfo, suffixes, basenameConfigKey='project'):
basename = make_filename(
srcinfo.config.get(basenameConfigKey, srcinfo.config['project']))
sources = []
sources.extend(srcinfo.sources)
sources.extend(srcinfo.templates)
sources.extend(srcinfo.statics)
targets = [target[0].File(basename + s) for s in suffixes]
return targets, sources
def _get_latex_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = map(lambda x: target[0].File(os_path(x[1])),
srcinfo.config.get('latex_documents'))
return targets, sources
def _get_linkcheck_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = [target[0].File("output.txt")]
return targets, sources
def _get_man_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = map(lambda x: target[0].File(os_path("%s.%s" % (x[1], x[4]))),
srcinfo.config.get('man_pages'))
return targets, sources
def _get_serialize_emissions(env, target, srcinfo, suffix=None, extrafiles=[]):
if suffix is None:
suffix = srcinfo.config.get('html_file_suffix', '.html')
sources = []
sources.extend(srcinfo.sources)
sources.extend(srcinfo.templates)
sources.extend(srcinfo.statics)
targets = []
for s in srcinfo.sources:
t = os.path.splitext(str(s))[0] + suffix
t = os.path.relpath(t, str(srcinfo.srcroot))
targets.append(t)
for key in srcinfo.config.get('html_additional_pages', {}):
targets.append(os_path("%s%s" % (key, suffix)))
targets.extend(extrafiles)
targets = [target[0].File(t) for t in targets]
return targets, sources
def _get_singlehtml_emissions(env, target, srcinfo):
suffix = srcinfo.config.get('html_file_suffix', ".html")
sources = []
sources.extend(srcinfo.sources)
sources.extend(srcinfo.templates)
sources.extend(srcinfo.statics)
t = os.path.relpath(srcinfo.config['master_doc'] + suffix,
str(srcinfo.srcroot))
targets = [target[0].File(t)]
return targets, sources
def _get_texinfo_emissions(env, target, srcinfo):
suffix = srcinfo.config.get('source_suffix', '.rst')
sources = []
sources.extend(srcinfo.sources)
sources.extend(map(lambda x: source[0].File(os_path(x + suffix)),
srcinfo.config.get('texinfo_appendices', [])))
targets = map(lambda x: target[0].File(os_path("%s.texi" % x[1])),
srcinfo.config.get('texinfo_documents'))
return targets, sources
def _get_text_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = []
for s in sources:
t = os.path.relpath(str(s), str(srcinfo.srcroot))
t = os.path.splitext(t)[0] + ".txt"
targets.append(target[0].File(t))
return targets, sources

View File

@@ -1,123 +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)
from SCons.Script import AddOption, Flatten
from SCons.Script import Builder
from SCons.Action import Action
from subprocess import check_output, STDOUT, CalledProcessError
import sys
import os
def BoostCompileTest(env, test, source = None, **kw):
def gen_result(target, source, env=env):
target_file = target[0].abspath
result_file = os.path.splitext(target_file)[0] + '.result'
if sys.stdout.isatty():
env['RESULT']='\033[92mPASS\033[0m'
else:
env['RESULT']='PASS'
with open(result_file, 'w+') as result:
result.write('Result: {}\n'.format('pass'))
obj = env.Object(test, source if source is not None else test + '.cpp')
env.AddPostAction(obj, Action(gen_result, cmdstr=None))
env.AddPostAction(obj, Action('@echo $RESULT'))
return obj
def BoostRun(env, prog, target, command = '$SOURCE'):
def call(target, source, env=env):
cmd = env.subst(command, target=target, source=source)
result_file = env.subst('$TARGET', target=target)
output=''
try:
output=check_output(cmd, stderr=STDOUT, shell=True, env=env['ENV'])
success=True
except CalledProcessError as e:
output=e.output
success=False
with open(result_file, 'w+') as result:
result.write('Result: {}\n'.format(success and 'pass' or 'fail'))
result.write('Output: {}\n'.format(output))
if sys.stdout.isatty():
env['RESULT']=success and '\033[92mPASS\033[0m' or '\033[91mFAIL\033[0m'
else:
env['RESULT']=success and 'PASS' or 'FAIL'
testcomstr = env.get('TESTCOMSTR')
if testcomstr:
run = env.Command(target, prog, Action(call, cmdstr=testcomstr))
else:
run = env.Command(target, prog, Action(call, cmdstr=command))
env.AddPostAction(target, Action('@echo $RESULT'))
return run
def BoostRunPythonScript(env, script):
return env.BoostRun(env.File(script), script.replace('.py', '.result'), '"${PYTHON}" $SOURCE')
def BoostRunTest(env, test, source = None, command = '$SOURCE', command_sources = [], **kw):
test_prog = env.Program(test, (source is None) and (test + ".cpp") or source, **kw)
command += '> $TARGET'
run = env.BoostRun([test_prog, command_sources], test + '.result', command)
return run
def BoostRunTests(env, tests, **kw):
run = []
for test in Flatten(tests):
run += env.BoostRunTest(test, **kw)
return run
def BoostCompileTests(env, tests, **kw):
comp = []
for test in Flatten(tests):
comp += env.BoostCompileTest(test, **kw)
return comp
def BoostTestSummary(env, tests, **kw):
def print_summary(target, source, **kw):
results = tests
failures = [r for r in results
if r.get_path().endswith('.result') and not 'Result: pass' in r.get_contents()]
print('%s tests; %s pass; %s fails'%(len(results), len(results)-len(failures), len(failures)))
if failures:
print('For detailed failure reports, see:')
for f in failures:
print(f.get_path())
testsumcomstr = env.get('TESTSUMCOMSTR')
if testsumcomstr:
run = env.Command('summary', tests, Action(print_summary, cmdstr=testsumcomstr))
else:
run = env.Command('summary', tests, print_summary, cmdstr='')
def exists(env):
return True
def generate(env):
AddOption('--test', dest='test', action="store_true")
env.AddMethod(BoostCompileTest)
env.AddMethod(BoostRun)
env.AddMethod(BoostRunPythonScript)
env.AddMethod(BoostRunTest)
env.AddMethod(BoostRunTests)
env.AddMethod(BoostCompileTests)
env.AddMethod(BoostTestSummary)

View File

@@ -1,96 +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)
from SCons.Script import AddOption
import sys
variables=[] # remember 'public' variables
options=[]
def add_option(*args, **kwds):
"""Capture the help messages so we can produce a helpful usage text."""
options.append('{:25} {}'.format(', '.join(args), kwds.get('help', '')))
AddOption(*args, **kwds)
def add_variable(vars, var):
variables.append(var[0])
vars.Add(var)
def options_help(env):
return '\n '.join(options)
def variables_help(vars, env):
"""This is cloned from SCons' Variables.GenerateHelpText, to only report 'public' variables."""
opts = [o for o in vars.options if o.key in variables]
def format(opt):
if opt.key in env:
actual = env.subst('${%s}' % opt.key)
else:
actual = None
return vars.FormatVariableHelpText(env, opt.key, opt.help, opt.default, actual, opt.aliases)
text = ''.join([f for f in map(format, opts) if f])
lines = [' %s'%l for l in text.split('\n')] # Add some indentation
return '\n'.join(lines)
def help(vars, env):
return """Usage: scons [--option...] [variable=value...] [target...]
available options:
{}
available variables:
{}
""".format(options_help(env), variables_help(vars, env))
def pretty_output(env):
colors = {}
colors['red'] = '\033[31m'
colors['green'] = '\033[32m'
colors['blue'] = '\033[34m'
colors['yellow'] = '\033[93m'
colors['Red'] = '\033[91m'
colors['Green'] = '\033[92m'
colors['Blue'] = '\033[94m'
colors['Purple'] = '\033[95m'
colors['Cyan'] = '\033[96m'
colors['end'] = '\033[0m'
#If the output is not a terminal, remove the colors
if not sys.stdout.isatty():
for key, value in colors.iteritems():
colors[key] = ''
compile_source_message = '{green}Compiling $TARGET{end}'.format(**colors)
compile_shared_source_message = '{green}Compiling $TARGET{end}'.format(**colors)
link_program_message = '{blue}Linking $TARGET{end}'.format(**colors)
link_library_message = '{blue}Linking $TARGET{end}'.format(**colors)
ranlib_library_message = '{blue}Ranlib $TARGET{end}'.format(**colors)
link_shared_library_message = '{blue}Linking $TARGET{end}'.format(**colors)
test_message = '{blue}Testing $SOURCE{end}'.format(**colors)
testsum_message = '{Blue}Test Summary{end}'.format(**colors)
env.Replace(CXXCOMSTR = compile_source_message,
CCCOMSTR = compile_source_message,
SHCCCOMSTR = compile_shared_source_message,
SHCXXCOMSTR = compile_shared_source_message,
ARCOMSTR = link_library_message,
RANLIBCOMSTR = ranlib_library_message,
SHLINKCOMSTR = link_shared_library_message,
LINKCOMSTR = link_program_message,
TESTCOMSTR = test_message,
TESTSUMCOMSTR = testsum_message)

View File

@@ -1,52 +0,0 @@
# -*- python -*-
#
# 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)
Import('env')
env.QuickBook('python.bbk', 'python.qbk',
['building.qbk',
'configuration.qbk',
'support.qbk',
'faq.qbk',
'glossary.qbk'])
env.QuickBook('tutorial.bbk', 'tutorial.qbk')
env.QuickBook('reference.bbk', 'reference.qbk',
Glob('reference/*.qbk'))
env.BoostBook('python.dbk', 'python.bbk')
env.BoostBook('tutorial.dbk', 'tutorial.bbk')
env.BoostBook('reference.dbk', 'reference.bbk')
images = Glob('images/*.*') + Glob('images/callouts/*.*')
env.BoostHTML('html/', 'python.dbk',
resources=['boostbook.css'] + images,
args=['--stringparam', 'generate.toc', '"library nop; chapter toc; section toc;"',
'--stringparam', 'html.stylesheet', 'boostbook.css',
'--stringparam', 'boost.image.src', 'images/bpl.png',
'--stringparam', 'boost.graphics.root', 'images/',
'--stringparam', 'boost.defaults', 'none',
'--param', 'toc.max.depth', '3',
'--param', 'toc.section.depth' ,'2',
'--param', 'chunk.section.depth', '1'])
env.BoostHTML('html/tutorial/', 'tutorial.dbk',
args=['--stringparam', 'html.stylesheet', '../boostbook.css',
'--stringparam', 'boost.image.src', '../images/bpl.png',
'--stringparam', 'boost.graphics.root', '../images/'])
env.BoostHTML('html/reference/', 'reference.dbk',
args=['--stringparam', 'html.stylesheet', '../boostbook.css',
'--stringparam', 'boost.image.src', '../images/bpl.png',
'--stringparam', 'boost.graphics.root', '../images/'])
env.BoostRST('html/article.html', 'article.rst', resources=['rst.css'])
if env['NUMPY']:
env.BoostSphinx('html/numpy', 'numpy/')

83
doc/fabscript Normal file
View File

@@ -0,0 +1,83 @@
# -*- python -*-
#
# 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)
from faber.tools.xslt import xsltflags
from faber.tools.boost import quickbook, boostbook
from faber.artefacts import html
from glob import glob as G
from os import makedirs
from os.path import relpath, dirname, exists
from shutil import copyfile
def glob(pattern):
prefix = srcdir + '/'
p = len(prefix)+1
return [f[p:] for f in G(prefix + pattern)]
class make_html(action):
def __init__(self):
action.__init__(self, 'make_html', self.process)
def map(self, fs):
return boostbook.html.map(fs)
def process(self, target, source):
boostbook.html(target, source[0:1])
for s in source[1:]:
t = target[0]._filename + relpath(s._filename, srcdir)
d = dirname(t)
if not exists(d):
makedirs(d)
copyfile(s._filename, t)
sphinx_build = action('sphinx-build', 'sphinx-build -b html $(>) $(<)')
rst2html = action('rst2html', 'rst2html --trim-footnote-reference-space --footnote-references=superscript --stylesheet=$(>:D)/rst.css $(>) $(<)')
python_bbk = rule(quickbook.process, 'python.bbk', 'python.qbk',
dependencies=['release_notes.qbk',
'building.qbk',
'configuration.qbk',
'suport.qbk',
'faq.qbk',
'glossary.qbk'])
tutorial_bbk = rule(quickbook.process, 'tutorial.bbk', 'tutorial.qbk')
reference_bbk = rule(quickbook.process, 'reference.bbk', 'reference.qbk')
python_db = rule(boostbook.db, 'python.db', python_bbk)
tutorial_db = rule(boostbook.db, 'tutorial.db', tutorial_bbk)
reference_db = rule(boostbook.db, 'reference.db', reference_bbk)
python = html.dir(make_html(), 'html', [python_db, 'boostbook.css'] + glob('/images/*.*') + glob('/images/callouts/*.*'),
features=xsltflags('--stringparam generate.toc "library nop; chaper toc; section toc;"',
'--stringparam html.stylesheet boostbook.css',
'--stringparam boost.image.src images/bpl.png',
'--stringparam boost.graphics.root images/',
'--stringparam boost.defaults none',
'--param toc.max.depth 3',
'--param toc.section.depth 2',
'--param chunk.section.depth 1'))
tutorial = html.dir(boostbook.html, 'html/tutorial', tutorial_db, dependencies=[python],
features=xsltflags('--stringparam html.stylesheet ../boostbook.css',
'--stringparam boost.image.src ../images/bpl.png',
'--stringparam boost.graphics.root ../images/'))
reference = html.dir(boostbook.html, 'html/reference', reference_db, dependencies=[python],
features=xsltflags('--stringparam html.stylesheet ../boostbook.css',
'--stringparam boost.image.src ../images/bpl.png',
'--stringparam boost.graphics.root ../images/'))
numpy = rule(sphinx_build, 'html/numpy', 'numpy', attrs=always, dependencies=[python])
article = rule(rst2html, 'html/article.html', 'article.rst')
html = alias('html', [python, tutorial, reference, numpy, article])
default = html

0
doc/html/images/python_cpp_mix.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

0
doc/internals.html Executable file → Normal file
View File

0
doc/internals.rst Executable file → Normal file
View File

View File

@@ -43,6 +43,7 @@ The development of these features was funded in part by grants to `Boost Consult
[section Contents]
* [link rn Release Notes]
* _tutorial_
* [link building Building and Testing]
* _reference_
@@ -58,6 +59,7 @@ The development of these features was funded in part by grants to `Boost Consult
[@article.html Building Hybrid Systems With Boost Python], by Dave Abrahams and Ralf W. Grosse-Kunstleve
[include release_notes.qbk]
[include building.qbk]
[include configuration.qbk]
[include support.qbk]

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

@@ -86,8 +86,8 @@ The column of Python Expressions illustrates the expressions that will be suppor
[[C++ Expression][Python Method Name][C++ Implementation][Python Expression (primary, secondary)]]
[[`self == r`][`__eq__`][`x == y`][`x == y`, `y == x`]]
[[`l == self`][`__eq__`][`y == x`][`y == x`, `x == y`]]
[[`self != r`][`__nq__`][`x != y`][`x != y`, `y != x`]]
[[`l != self`][`__nq__`][`y != x`][`y != x`, `x != y`]]
[[`self != r`][`__ne__`][`x != y`][`x != y`, `y != x`]]
[[`l != self`][`__ne__`][`y != x`][`y != x`, `x != y`]]
[[`self < r`][`__lt__`][`x < y`][`x < y`, `y > x`]]
[[`l < self`][`__gt__`][`y < x`][`y > x`, `x < y`]]
[[`self > r`][`__gt__`][`x > y`][`x > y`, `y < x`]]

11
doc/release_notes.qbk Normal file
View File

@@ -0,0 +1,11 @@
[chapter Release Notes
[quickbook 1.7]
[id rn]
]
[section Version 1.67]
* The Boost.Python library names now contain the Python version suffix.
A variant compiled with Python 2.7 will thus produce library names
`boost_python27` and `boost_numpy27`, etc., making it possible to host
variants for multiple Python versions next to each other.

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

82
fabscript Normal file
View File

@@ -0,0 +1,82 @@
# -*- python -*-
#
# 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)
from faber.feature import set
from faber.types import cxx
from faber.tools.compiler import cxxflags, define, include
from faber.tools.python import python
from faber.config import report, cxx_checks
from faber.config.try_run import try_run
features += include('include')
features += define('BOOST_ALL_NO_LIB') # disable auto-linking
boost_include = options.get_with('boost-include')
if boost_include:
features += include(boost_include)
python = python.instance()
py_suffix = '{}{}'.format(*python.version.split('.')[:2])
features |= set(python.include, python.linkpath, python.libs)
class has_numpy(try_run):
src = r"""
// If defined, enforces linking against PythonXXd.lib, which
// is usually not included in Python environments.
#undef _DEBUG
#include "Python.h"
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "numpy/arrayobject.h"
#if PY_VERSION_HEX >= 0x03000000
void *initialize() { import_array();}
#else
void initialize() { import_array();}
#endif
int main()
{
int result = 0;
Py_Initialize();
initialize();
if (PyErr_Occurred())
{
result = 1;
}
else
{
npy_intp dims = 2;
PyObject * a = PyArray_SimpleNew(1, &dims, NPY_INT);
if (!a) result = 1;
Py_DECREF(a);
}
Py_Finalize();
return result;
}
"""
def __init__(self, features=()):
inc = ''
try:
inc = python.check_python('import numpy; print(numpy.get_include())')
features |= include(inc)
except Exception:
# ignore errors, the check will fail during compilation...
pass
try_run.__init__(self, 'has_numpy', has_numpy.src, cxx, features,
if_=(include(inc), define('HAS_NUMPY')))
checks = [cxx_checks.has_cxx11(features, define('HAS_CXX11')),
has_numpy(features)]
config = report('config', checks)
src = module('src', features=features|config.use)
test = module('test', features=features|config.use)
doc = module('doc', features=features|config.use)
default = src.default

0
include/boost/python/arg_from_python.hpp Executable file → Normal file
View File

0
include/boost/python/base_type_traits.hpp Executable file → Normal file
View File

0
include/boost/python/borrowed.hpp Executable file → Normal file
View File

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

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

0
include/boost/python/cast.hpp Executable file → Normal file
View File

0
include/boost/python/converter/arg_to_python.hpp Executable file → Normal file
View File

View File

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
}

0
include/boost/python/converter/pytype_function.hpp Executable file → Normal file
View File

View File

@@ -76,7 +76,7 @@ namespace detail
registry::lookup_shared_ptr(type_id<shared_ptr<T> >());
}
#if __cplusplus >= 201103L
#if !defined(BOOST_NO_CXX11_SMART_PTR)
template <class T>
inline void
register_shared_ptr0(std::shared_ptr<T>*)

0
include/boost/python/converter/return_from_python.hpp Executable file → Normal file
View File

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

@@ -25,7 +25,7 @@ PyObject* shared_ptr_to_python(shared_ptr<T> const& x)
return converter::registered<shared_ptr<T> const&>::converters.to_python(&x);
}
#if __cplusplus >= 201103L
#if !defined(BOOST_NO_CXX11_SMART_PTR)
template <class T>
PyObject* shared_ptr_to_python(std::shared_ptr<T> const& x)
{

4
include/boost/python/def_visitor.hpp Executable file → Normal file
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

@@ -48,7 +48,7 @@ inline PyObject* get(mpl::int_<N>, PyObject* const& args_)
return PyTuple_GET_ITEM(args_,N);
}
inline unsigned arity(PyObject* const& args_)
inline Py_ssize_t arity(PyObject* const& args_)
{
return PyTuple_GET_SIZE(args_);
}
@@ -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

@@ -105,11 +105,9 @@
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if PY_MAJOR_VERSION == 2
# define BOOST_LIB_NAME boost_python
#elif PY_MAJOR_VERSION == 3
# define BOOST_LIB_NAME boost_python3
#endif
#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:
//
@@ -122,6 +120,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

0
include/boost/python/detail/convertible.hpp Executable file → Normal file
View File

0
include/boost/python/detail/copy_ctor_mutates_rhs.hpp Executable file → Normal file
View File

0
include/boost/python/detail/def_helper_fwd.hpp Executable file → Normal file
View File

2
include/boost/python/detail/is_shared_ptr.hpp Executable file → Normal file
View File

@@ -13,7 +13,7 @@
namespace boost { namespace python { namespace detail {
BOOST_PYTHON_IS_XXX_DEF(shared_ptr, shared_ptr, 1)
#if __cplusplus >= 201103L
#if !defined(BOOST_NO_CXX11_SMART_PTR)
template <typename T>
struct is_shared_ptr<std::shared_ptr<T> > : std::true_type {};
#endif

0
include/boost/python/detail/is_wrapper.hpp Executable file → Normal file
View File

View File

0
include/boost/python/detail/prefix.hpp Executable file → Normal file
View File

0
include/boost/python/detail/python_type.hpp Executable file → Normal file
View File

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

0
include/boost/python/detail/sfinae.hpp Executable file → Normal file
View File

View File

@@ -7,7 +7,8 @@
# define BOOST_PYTHON_DETAIL_TYPE_TRAITS_HPP
#if __cplusplus < 201103L
#include <boost/config.hpp>
#ifdef BOOST_NO_CXX11_HDR_TYPE_TRAITS
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/same_traits.hpp>
# include <boost/type_traits/cv_traits.hpp>
@@ -34,7 +35,7 @@
namespace boost { namespace python { namespace detail {
#if __cplusplus < 201103L
#ifdef BOOST_NO_CXX11_HDR_TYPE_TRAITS
using boost::alignment_of;
using boost::add_const;
using boost::add_cv;
@@ -98,8 +99,8 @@ namespace boost { namespace python { namespace detail {
using std::remove_cv;
using std::remove_const;
using true_ = std::integral_constant<bool, true>;
using false_ = std::integral_constant<bool, false>;
typedef std::integral_constant<bool, true> true_;
typedef std::integral_constant<bool, false> false_;
#endif
using boost::is_base_and_derived;
using boost::type_with_alignment;

12
include/boost/python/detail/unwind_type.hpp Executable file → Normal file
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)

0
include/boost/python/detail/unwrap_type_id.hpp Executable file → Normal file
View File

0
include/boost/python/detail/unwrap_wrapper.hpp Executable file → Normal file
View File

0
include/boost/python/detail/value_arg.hpp Executable file → Normal file
View File

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

0
include/boost/python/docstring_options.hpp Executable file → Normal file
View File

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)
);

0
include/boost/python/handle_fwd.hpp Executable file → Normal file
View File

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

@@ -45,7 +45,7 @@ namespace detail
template <class U>
void dispatch(U* x, detail::true_) const
{
#if __cplusplus < 201103L
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<U> owner(x);
dispatch(owner, detail::false_());
#else
@@ -63,7 +63,7 @@ namespace detail
void* memory = holder::allocate(this->m_self, offsetof(instance_t, storage), sizeof(holder));
try {
#if __cplusplus < 201103L
#if defined(BOOST_NO_CXX11_SMART_PTR)
(new (memory) holder(x))->install(this->m_self);
#else
(new (memory) holder(std::move(x)))->install(this->m_self);

View File

@@ -66,25 +66,9 @@ BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
# endif
# if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(BOOST_PYTHON_STATIC_MODULE)
# define BOOST_PYTHON_MODULE_INIT(name) \
void BOOST_PP_CAT(init_module_,name)(); \
extern "C" __declspec(dllexport) _BOOST_PYTHON_MODULE_INIT(name)
# elif BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY
# define BOOST_PYTHON_MODULE_INIT(name) \
void BOOST_PP_CAT(init_module_,name)(); \
extern "C" __attribute__ ((__visibility__("default"))) _BOOST_PYTHON_MODULE_INIT(name)
# else
# define BOOST_PYTHON_MODULE_INIT(name) \
void BOOST_PP_CAT(init_module_,name)(); \
extern "C" _BOOST_PYTHON_MODULE_INIT(name)
# endif
# define BOOST_PYTHON_MODULE_INIT(name) \
void BOOST_PP_CAT(init_module_,name)(); \
extern "C" BOOST_SYMBOL_EXPORT _BOOST_PYTHON_MODULE_INIT(name)
# endif

View File

@@ -62,11 +62,9 @@
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if PY_MAJOR_VERSION == 2
# define BOOST_LIB_NAME boost_numpy
#elif PY_MAJOR_VERSION == 3
# define BOOST_LIB_NAME boost_numpy3
#endif
#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:
//
@@ -79,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

@@ -86,11 +86,11 @@ public:
/// @brief Copy the scalar (deep for all non-object fields).
ndarray copy() const;
/// @brief Return the size of the nth dimension.
Py_intptr_t shape(int n) const { return get_shape()[n]; }
/// @brief Return the size of the nth dimension. raises IndexError if k not in [-get_nd() : get_nd()-1 ]
Py_intptr_t shape(int n) const;
/// @brief Return the stride of the nth dimension.
Py_intptr_t strides(int n) const { return get_strides()[n]; }
/// @brief Return the stride of the nth dimension. raises IndexError if k not in [-get_nd() : get_nd()-1]
Py_intptr_t strides(int n) const;
/**
* @brief Return the array's raw data pointer.

View File

@@ -106,7 +106,7 @@ struct unary_ufunc
dtype in_dtype = dtype::get_builtin<TArgument>();
dtype out_dtype = dtype::get_builtin<TResult>();
ndarray in_array = from_object(input, in_dtype, ndarray::ALIGNED);
ndarray out_array = (output != object()) ?
ndarray out_array = ! output.is_none() ?
from_object(output, out_dtype, ndarray::ALIGNED | ndarray::WRITEABLE)
: zeros(in_array.get_nd(), in_array.get_shape(), out_dtype);
multi_iter iter = make_multi_iter(in_array, out_array);
@@ -171,7 +171,7 @@ struct binary_ufunc
ndarray in1_array = from_object(input1, in1_dtype, ndarray::ALIGNED);
ndarray in2_array = from_object(input2, in2_dtype, ndarray::ALIGNED);
multi_iter iter = make_multi_iter(in1_array, in2_array);
ndarray out_array = (output != object())
ndarray out_array = !output.is_none()
? from_object(output, out_dtype, ndarray::ALIGNED | ndarray::WRITEABLE)
: zeros(iter.get_nd(), iter.get_shape(), out_dtype);
iter = make_multi_iter(in1_array, in2_array, out_array);

0
include/boost/python/object.hpp Executable file → Normal file
View File

View File

@@ -83,7 +83,7 @@ inline void register_shared_ptr_from_python_and_casts(T*, Bases)
{
// Constructor performs registration
python::detail::force_instantiate(converter::shared_ptr_from_python<T, boost::shared_ptr>());
#if __cplusplus >= 201103L
#if !defined(BOOST_NO_CXX11_SMART_PTR)
python::detail::force_instantiate(converter::shared_ptr_from_python<T, std::shared_ptr>());
#endif

0
include/boost/python/object/function_doc_signature.hpp Executable file → Normal file
View File

0
include/boost/python/object/inheritance_query.hpp Executable file → Normal file
View File

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

@@ -21,7 +21,7 @@ struct make_ptr_instance
template <class Arg>
static inline Holder* construct(void* storage, PyObject*, Arg& x)
{
#if __cplusplus < 201103L
#if defined(BOOST_NO_CXX11_SMART_PTR)
return new (storage) Holder(x);
#else
return new (storage) Holder(std::move(x));
@@ -58,7 +58,7 @@ struct make_ptr_instance
static inline PyTypeObject* get_derived_class_object(boost::python::detail::true_, U const volatile* x)
{
converter::registration const* r = converter::registry::query(
type_info(typeid(*get_pointer(x)))
type_info(typeid(*x))
);
return r ? r->m_class_object : 0;
}

View File

@@ -106,7 +106,7 @@ struct pointer_holder_back_reference : instance_holder
template <class Pointer, class Value>
inline pointer_holder<Pointer,Value>::pointer_holder(Pointer p)
#if __cplusplus < 201103L
#if defined(BOOST_NO_CXX11_SMART_PTR)
: m_p(p)
#else
: m_p(std::move(p))
@@ -116,7 +116,7 @@ inline pointer_holder<Pointer,Value>::pointer_holder(Pointer p)
template <class Pointer, class Value>
inline pointer_holder_back_reference<Pointer,Value>::pointer_holder_back_reference(Pointer p)
#if __cplusplus < 201103L
#if defined(BOOST_NO_CXX11_SMART_PTR)
: m_p(p)
#else
: m_p(std::move(p))

View File

@@ -135,7 +135,7 @@ struct py_function
{}
py_function(py_function const& rhs)
#if __cplusplus < 201103L
#if defined(BOOST_NO_CXX11_SMART_PTR)
: m_impl(rhs.m_impl)
#else
: m_impl(std::move(rhs.m_impl))
@@ -168,7 +168,7 @@ struct py_function
}
private:
#if __cplusplus < 201103L
#if defined(BOOST_NO_CXX11_SMART_PTR)
mutable std::auto_ptr<py_function_impl_base> m_impl;
#else
mutable std::unique_ptr<py_function_impl_base> m_impl;

0
include/boost/python/object/stl_iterator_core.hpp Executable file → Normal file
View File

0
include/boost/python/object_protocol_core.hpp Executable file → Normal file
View File

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)

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