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

Compare commits

...

255 Commits

Author SHA1 Message Date
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
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
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
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
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
77ff0d6bbc Fix CI OSX build failure. 2018-04-17 20:41:17 -04:00
Stefan Seefeld
24313709a7 Fix auto-linking logic (Windows only). 2018-04-12 23:39:22 -04:00
Stefan Seefeld
ac9fa536c8 Add OSX to CI test matrix. 2018-04-08 21:34:48 -04:00
Gaurav
7352c9c0f7 Remove not reachable condition.
Line no 138-139 suggest if condition satisfy if n_actual <=max_arity :
        if (n_actual + f->m_nkeyword_values >= min_arity
            && n_actual <= max_arity)
So condition at Line no 161 is not reachable.
2018-04-08 21:18:57 -04:00
Stefan Seefeld
26ac881b9d Fix CI links. 2018-04-08 20:41:51 -04:00
Stefan Seefeld
19f6c782aa Improve CI test coverage. 2018-04-08 18:21:22 -04:00
Stefan Seefeld
f3df1bf912 Remove redundant pragma once directives. 2018-04-07 17:05:18 -04:00
Stefan Seefeld
d515eb82c8 Fix build warning. 2018-03-15 15:29:06 -04:00
Stefan Seefeld
0021720a46 Conditionalize targets on Python configuration. 2018-03-11 10:31:21 -04:00
Stefan Seefeld
61591f7ad2 Enable more MSVC versions. 2018-03-09 13:17:24 -05:00
Stefan Seefeld
6b8ab7a5a3 Conditionalize tests. 2018-03-09 13:08:07 -05:00
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
b9d0d97499 Fix MSVC compilation failure. 2017-11-16 10:26:30 -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
Stefan Seefeld
2d1f66fd19 Remove module as obsoleted by Boost.NumPy. 2017-07-20 11:39:58 -04:00
Stefan Seefeld
69e38d2186 Fix documentation. 2017-07-20 10:11:19 -04:00
Stefan Seefeld
8536e97c67 Use utf-8 encoding 2017-06-25 14:33:42 -04:00
shreyans800755
142661dac8 Use std type_traits instead of boost type_traits
Fixes https://github.com/boostorg/python/issues/106
2017-06-25 14:17:41 -04:00
John Kirkham
d6554d6c65 Handle BOOST_LIB_NAME for NumPy on Python 2/3
This was reusing the Python 2 name on Python 3, which is incorrect since
the Python 3 library for Boost.NumPy has a `3` in it. Hence this checks
against the Python version and defines this correctly.
2017-06-12 09:32:31 -04:00
John Kirkham
90829714cc Fix BOOST_LIB_NAME for Python 3
This was reusing the Python 2 name on Python 3, which is incorrect since
the Python 3 library for Boost.Python now has a `3` in it. Hence this
checks against the Python version and defines this correctly.
2017-06-12 09:32:31 -04:00
Stefan Seefeld
664d443df3 Fix Python3 compatibility bug. 2017-06-03 18:26:14 -04:00
Stefan Seefeld
c4fe369d69 Require NumPy 1.7 API. 2017-06-02 19:31:54 -04:00
Stefan Seefeld
7cfc47008e Rename test source 2017-06-02 19:31:54 -04:00
Raphael Isemann
1452dfe713 Reencoded a few headers that used Windows-1252 with UTF-8.
Nearly every header in the boost codebase is UTF-8, but here there
are a few headers which are using Windows-1252, which makes it impossible
for some tools to parse those files. This patch just reencodes them
with UTF-8 like the rest of the codebase. I checked that the name of the
author is still correct after this change.

No functional change intended.
2017-06-02 17:44:46 -04:00
Saliya
3613142839 Fixing compiling error 'error: ‘NPY_FLOAT16’ was not declared in this scope'
Signed-off-by: Saliya <hamparawa@gmail.com>
2017-06-02 15:35:04 -04:00
John Zwinck
b2f53e1acf exec/eval(): add overloads for char const*
Many times the caller may have a string created in C++,
so there is no need to wrap it in a Python object when
the only thing done with the object is extract<char*>.
2017-05-04 19:29:56 -04:00
Stefan Seefeld
3844c4fc5f Fix more missing symbols. 2017-04-14 13:14:05 -04:00
Stefan Seefeld
df16e3e55e Fix typo. 2017-03-28 12:54:05 -04:00
Stefan Seefeld
3066c73c09 Fix Windows builds. 2017-03-24 15:39:13 -04:00
Stefan Seefeld
edd890bd2b More dllexport fixes 2017-03-24 15:39:13 -04:00
Stefan Seefeld
352792c90a Add more export symbols. 2017-03-16 20:14:39 -04:00
Stefan Seefeld
47faef65ee Fix documentation links. 2017-03-16 11:35:26 -04:00
Rene Rivera
5121fc11f9 Don't build numpy if there's no python version to target. 2017-03-06 10:30:41 -06:00
Rene Rivera
471e6181b2 BPL builds targets need to always be defined. 2017-03-05 15:16:36 -06:00
Rene Rivera
398e7f02b8 Fix no pynumpy target when no numpy configured. 2017-03-05 08:56:57 -06:00
Rene Rivera
1e315242ce Fix libs from referencing BPL when there is no python configured. 2017-03-03 22:28:22 -06:00
al3xst
77ee91d5c5 Updated python library reference url
Due to changes on the python website, the url to the pickle library reference page was invalid.
2017-03-03 18:29:05 -05:00
Rene Rivera
e670de2795 Fix empty numpy lib name caused by missing parens for lib name map. 2017-03-02 21:55:49 -06:00
Rene Rivera
367b793ac9 Merge branch 'develop' of https://github.com/boostorg/python.git into develop 2017-03-01 10:15:47 -06:00
Rene Rivera
8c170d9193 Fix building of multiple BPL libs even when the configured python does
not match.
2017-03-01 10:15:37 -06:00
SPKorhonen
bd7b8ecba5 Fix for missing export symbols, issue #98 (#110)
Fix for missing export symbols in shared library of boost::python::numpy
2017-02-15 11:53:28 -05:00
Jürgen Hunold
0224f54ae0 Switch^Cisibility support to BOOST_SYMBOL_EXPORT. Refs #2114 2017-02-13 10:43:23 -05:00
Stefan Seefeld
d14b8cf411 Fix library dependency with Python 3. 2017-01-03 21:17:51 -05:00
Tadeu Manoel
4e0b96faa8 Fix conversion of PyUnicodeObject to wstring (#93) 2016-12-14 07:58:07 -05:00
Tadeu Manoel
7178a70176 Fix a problem where test_builtin_converters.py is not being run (#94)
This was happening because the module docstring was not the first statement.
2016-12-14 07:54:37 -05:00
Vladimir Prus
36bbdde2fe Use Boost-global python tagging. 2016-10-28 11:56:15 +03:00
Stefan Seefeld
1df6d84b80 Fix Python 3 incompatibility. 2016-10-27 08:37:25 -04:00
Stefan Seefeld
e968329174 Clean up examples. 2016-10-23 21:34:16 -04:00
Stefan Seefeld
07c8cbe652 Adjust to Boost.Build changes. 2016-10-23 21:27:31 -04:00
Stefan Seefeld
163e469bc4 Minor fixes. 2016-10-19 11:25:48 -04:00
Stefan Seefeld
ac39d2ed69 Fix doc build. 2016-10-19 07:34:34 -04:00
Stefan Seefeld
264f6ae4b9 Work around a sphinx bug. 2016-10-18 21:14:47 -04:00
Stefan Seefeld
84c96447e2 Add NumPy support to the BB-based build logic. 2016-10-18 16:32:05 -04:00
Stefan Seefeld
dc8d68d3fc Fix id clash in hierarchical tocs. 2016-10-16 20:30:15 -04:00
Stefan Seefeld
91512a971d More doc fine-tuning. 2016-10-10 14:22:57 -04:00
Stefan Seefeld
080eb55be6 Fine-tune documentation formatting. 2016-10-10 12:02:28 -04:00
Rene Rivera
a3d8223b5d Fix syntax error caused by merging. 2016-10-09 11:04:38 -05:00
Stefan Seefeld
b9431cd326 Remove obsolete tests from build logic. 2016-10-09 09:19:20 -04:00
Stefan Seefeld
2ccf54f091 Minor doc touch-ups. 2016-10-09 00:02:39 -04:00
Stefan Seefeld
4ce4821111 Remove obsolete tests. 2016-10-08 15:29:56 -04:00
Rene Rivera
69ddfcae17 Add, and update, documentation build targets. 2016-10-08 15:16:38 -04:00
Stefan Seefeld
3ace4a0015 Adjust NumPy code to work with new directory / namespace structure. 2016-10-08 13:34:17 -04:00
Stefan Seefeld
cbb3851488 Merge NumPy extension from https://github.com/ndarray/Boost.NumPy/. 2016-10-07 20:03:12 -04:00
Stefan Seefeld
127cc20a1d Install documentation for development branch separately. 2016-10-07 18:17:43 -04:00
Stefan Seefeld
482219f20a Remove a bunch of obsolete files. 2016-09-29 23:18:00 -04:00
Wei-Ming Yang
061050c006 Fix a mistake in str::count() 2016-09-29 08:09:30 -04:00
Wei-Ming Yang
03adaee6d2 Implement str::endswith() 2016-09-29 08:08:46 -04:00
WKarel
bc2f77a3db Assert refcount before decrement (#64)
Assert reference count before decrementing it.
2016-09-29 07:48:46 -04:00
vmurashev
aaf0d220ae tests for python3 - get rid of 'from past.builtins import long' 2016-09-28 22:44:46 -04:00
vmurashev
bb6f52dc35 test/exec.cpp - register builtin module before call 'Py_Initialize' 2016-09-28 22:44:46 -04:00
Stefan Seefeld
d422058fb4 Adjust BB logic to shared_ptr test changes. 2016-09-28 16:59:44 -04:00
Stefan Seefeld
a60ab14b91 Fix doc upload. 2016-09-28 13:37:15 -04:00
Stefan Seefeld
e0ee734161 Update credentials to upload generated docs. 2016-09-28 08:31:12 -04:00
Stefan Seefeld
444c948abe Fix doc upload. 2016-09-27 20:13:38 -04:00
Stefan Seefeld
97e4b34a15 Add support for std::shared_ptr. 2016-09-27 13:53:37 -04:00
Stefan Seefeld
5029273ca8 Use std::unique_ptr instead of std::auto_ptr 2016-09-22 20:30:33 -04:00
Jim Bosch
26aaa5b62e Merge pull request #51 from willyd/vscompat
Visual Studio compatibility fixes
2015-11-21 18:36:38 -05:00
Guillaume Dumont
f753f4bc30 Visual Studio compatibility fixes
Static linking fix
2015-09-16 10:18:23 -04:00
Jim Bosch
9e53eb2c23 Fix some confusing magic numbers in docs for stride (#50).
Documentation here needs a bigger cleanup than I can give it
right now, but this at least removes the ambiguity as to whether
"4" means the shape or sizeof(int).
2015-09-09 23:55:28 -04:00
Jim Bosch
6c2e3fb487 Update README and convert it to Markdown. 2015-09-09 23:48:55 -04:00
Jim Bosch
fcbba59630 Enable tests in CMake build and fix relative path problems.
As reported in #46, tests were not being built with CMake due
to a typo.  But they were also broken, because the relative path
to the dynamic library used in the link commands for the test
Python modules wasn't appropriate for running the tests from
the source directory.  Instead, we now copy the Python test
scripts to the build directory and run them there.
2015-09-09 23:27:40 -04:00
Jim Bosch
61a399e80a Remove const from rvalue returns (#42).
I'd originally thought this was a useful way to prevent no-op
assignments to rvalues, but compilers now check for that
without using const, and it was probably only non-standard
compiler behavior that ever made it useful.
2015-09-09 22:38:50 -04:00
Jim Bosch
a0e849ed91 Switch from int to Py_intptr_t for shape/stride returns. 2015-01-18 10:00:42 -05:00
Christoph Lassner
4dbb2784ee Removed unnecessary defaults. 2015-01-17 14:06:22 -05:00
Christoph Lassner
4d9ab505b0 Updated build system behaviour and comments for the --with-boost option. 2015-01-17 14:06:00 -05:00
Jim Bosch
3494381c01 Resolve dtype equivalence issue in MSVC 2014-11-23 12:39:57 -05:00
Christoph Lassner
bc13c4c600 Fixed unsigned long test error. 2014-11-23 12:39:57 -05:00
Christoph Lassner
73b8350e53 Switch SCons to use SConsChecks submodule for Windows support 2014-11-23 12:39:52 -05:00
Jim Bosch
c509a3ab01 Merge pull request #39 from termoshtt/cmake_python3
(with minor modification from Jim Bosch)
2014-11-23 12:05:52 -05:00
Toshiki Teramura
4c2070f39f Revise example/wrap.cpp for python3 2014-11-23 12:03:58 -05:00
Toshiki Teramura
e2c23fd5f9 Append python version detector
Slight modifications from Jim Bosch for more standard language in
build system language.
2014-11-23 12:03:15 -05:00
Jim Bosch
7ff5465e7d Merge pull request #36 from ChrislS/master
SCons change to build a static lib for Windows
2014-09-25 20:19:38 -04:00
Christoph Lassner
e747cc9422 * SCons change to build a static lib for Windows. 2014-09-25 18:25:05 +02:00
Jim Bosch
b46ccc4f51 Merge pull request #35 from karlssonper/master
Examples and tests optional to build in CMake
2014-08-26 14:12:02 -04:00
per
be72aab254 Examples and tests are now optional to build. The default behavior is the same as before where both are built. 2014-08-18 11:28:53 +02:00
Jim Bosch
5035f6e801 Merge pull request #34 from karlssonper/master
added the NPY_FLOAT16 dtype
2014-08-04 15:10:44 -06:00
Per
0b549aee88 added the NPY_FLOAT16 dtype 2014-08-04 16:38:02 +02:00
Jim Bosch
bf73da1bce Merge pull request #31 from nbecker/master
SCons build system updates to support Python 3
2014-06-02 21:52:21 -04:00
Neal D. Becker
ca8ce585b7 Use equivalent, but doesn't seem to help 2014-06-02 09:40:28 -04:00
Neal D. Becker
81551cf6b6 port to py3 2014-06-02 09:40:00 -04:00
Jim Bosch
e3bf3c6f51 Merge pull request #29 from coroa/master
cmake: switch from using deprecated linklibraries to target_linklibraries
2013-10-10 15:46:08 -07:00
Jonas Hoersch
c8798676f6 cmake: switch from using deprecated linklibraries to target_linklibraries
the total information duplication actually decreases and it
facilitates reusing CMake instructions from outer projects.
2013-10-06 20:03:51 +02:00
Jim Bosch
c9974daec2 Avoid Python 3 compile warnings in NumPy initialization 2013-08-24 18:08:01 -04:00
Jim Bosch
b46dfd9064 Qualify calls to template member functions in invoke_matching.
This is necessary to avoid a bug in which a template struct from another
namespace can be confused with the member function by the parser
(see gcc bug 55576; it's apparently a defect in the C++98 standard).
2013-03-19 11:38:08 -04:00
Jim Bosch
956606ef0c Update README to mention CMake build system. 2013-03-15 23:08:40 -04:00
Philip Miller
0b59058fa2 Add cmake build system, fix examples for Windows compatibility. 2013-03-15 23:08:16 -04:00
Jim Bosch
2a41c80c58 Fix embedding issues with statically-compiled Python, at least on Linux. Use LINKFLAGS instead of LDFLAGS (see also #23; patch from Luc Bourhis) 2013-03-07 09:41:10 -05:00
Jim Bosch
42a57978ee Merge pull request #17 from awishnick/master
Added astype to ndarray
2013-01-18 13:46:42 -08:00
Aaron Wishnick
4b99e6b83f Add astype to ndarray. 2013-01-11 15:16:29 -05:00
Jim Bosch
49b536fbd3 replace non-constant array sizes with scoped_array 2012-12-10 23:32:08 -05:00
Jim Bosch
2e47285fb5 Add license file and license header to source files. 2012-09-26 00:33:10 -04:00
Jim Bosch
45b588b85a Merge pull request #12 from barnabyrobson/patch-1
Update SConscript to print the correct message when Boost.Python config test cannot be run.
2012-09-25 20:14:19 -07:00
barnabyrobson
cce7dfcf17 Update SConscript
Fixing copy and pasted comment to say correct thing when program built against Boost.Python can not run.
2012-09-22 20:13:20 -07:00
Jim Bosch
2f7742ffec add more permissive equivalence test for dtypes, start using it in tests 2012-09-18 23:13:29 -04:00
Ilya Kolpakov
46b959cceb ufunc tests now ensure that return value is the same object as the 'output' (if it is provided) argument being the same object as the ufunc return value 2012-09-04 12:10:55 +02:00
Ilya Kolpakov
ca3526c76a ufunc test now uses assert_array_almost_equal instead of bitwise(?) comparison 2012-09-04 11:30:58 +02:00
Jim Bosch
4ec94c676b Add example (wrap.py) to demonstrate how to wrap simple functions that operate on C arrays into functions that operate on NumPy arrays (#6). 2012-05-13 17:51:48 -04:00
Jim Bosch
a35cbd1af1 Switch to use RPATH in test and example builds (#5). 2012-05-13 17:50:15 -04:00
Jim Bosch
28a9fab278 Overhauled how builtin dtype objects are accessed for better consistency, added converters for array scalars. 2012-05-13 13:03:10 -04:00
Jim Bosch
ab2225bcbd Remove unused special handling for bool dtype. 2012-05-12 12:15:32 -04:00
Jim Bosch
dbe4903887 fix LoadableModule suffix on darwin 2012-04-29 12:55:57 -04:00
Jim Bosch
405f99cd3c Fix bug in boost/numpy.hpp install location 2012-04-28 15:47:48 -04:00
Jim Bosch
313dcbb628 added as_matrix call policy 2012-04-21 16:46:28 -04:00
Jim Bosch
dca44829a6 untabify python test files 2012-04-21 16:34:01 -04:00
Jim Bosch
46f6382fe4 Change how external environment variables are propagated to SCons to allow it to find executables in $PATH. 2012-04-21 15:14:29 -04:00
Jim Bosch
99e6194620 more SCons refactoring 2012-04-21 00:50:53 -04:00
Jim Bosch
4c2850cbfd Make CheckLibs available to ndarray SConstruct file. 2012-04-19 23:28:41 -04:00
Jim Bosch
029eb385ed Prepend Boost paths rather than append them; puts explicit paths at a higher priority than paths pulled from distutils (patch from Neal Becker). 2012-04-17 23:03:58 -04:00
Jim Bosch
77b89341d0 Added support for specifying installation directories for headers and libraries separately (modified patch from Neal Becker).
Signed-off-by: Jim Bosch <jbosch@astro.princeton.edu>
2012-04-17 22:53:06 -04:00
Jim Bosch
588027252b Remove unnecessary shared_ptr in class_ for ufuncs (from Neal Becker).
Signed-off-by: Jim Bosch <jbosch@astro.princeton.edu>
2012-04-17 22:01:39 -04:00
Jim Bosch
d61d41a786 allow CCFLAGS to be passed on command line or through construction variable; default is now '-O2 -g' 2012-04-17 10:00:36 -04:00
Jim Bosch
1d3a535e53 switch to using LoadableModule instead of SharedLibrary for test Python modules 2012-04-16 23:58:34 -04:00
Jim Bosch
65dc91f3da add bang lines to Python unit test scripts 2012-04-16 23:50:46 -04:00
Jim Bosch
782ca7bf20 add custom rpath option to SCons builds 2012-04-16 23:43:57 -04:00
Jim Bosch
1a5a3e1701 modifications to SCons build system to be friendlier to ndarray 2012-04-16 00:53:38 -04:00
Jim Bosch
00c61f4767 fix GitHub URL in readme 2012-04-11 20:18:38 -04:00
Jim Bosch
c20af50ae3 added README file 2012-04-11 20:17:18 -04:00
Jim Bosch
38e68fa2ae overhauled scons scripts 2012-03-18 18:57:14 -04:00
Jim Bosch
35a62fea52 added .gitignore 2012-03-18 17:09:13 -04:00
Jim Bosch
b219376e24 fixed header order in gaussian example; Python.h should always come before system headers 2012-03-18 17:05:22 -04:00
Jim Bosch
1e66e33201 removed ublas dependency from gaussian example 2011-11-08 03:45:31 +00:00
Stefan Seefeld
8f909d55ac Refine style. 2011-10-31 22:56:38 +00:00
Stefan Seefeld
05c21bcae1 Refine style. 2011-10-31 22:55:22 +00:00
Stefan Seefeld
0cb3bd7aa5 Add navigation bar. 2011-10-30 22:25:34 +00:00
Stefan Seefeld
7a84a00673 build new 'gaussian.cpp' extension. 2011-10-30 20:54:20 +00:00
Jim Bosch
9d7dfd8449 added gaussian example, updated scons build 2011-10-30 14:43:53 +00:00
Stefan Seefeld
2a8823f745 Fix formatting issues in the Reference Manual. 2011-10-29 20:39:37 +00:00
Stefan Seefeld
beaa4b0e4d Remove implementation details from documentation. 2011-10-29 18:20:25 +00:00
Stefan Seefeld
55c3b0569e Restructure documentation sources to build with sphinx. 2011-10-27 14:12:14 +00:00
Ankit Daftery
2aca81bca9 Added temporary directory for Reference documentation 2011-08-31 12:35:56 +00:00
Jim Bosch
32d2135462 boost/numpy - enabled new unit tests in old SCons build system 2011-08-25 23:32:43 +00:00
Ankit Daftery
7064cf3186 Added tutorial for ufunc 2011-08-17 18:26:20 +00:00
Ankit Daftery
777e16e1d0 Added example for ufunc 2011-08-17 18:25:44 +00:00
Ankit Daftery
715e5cbc31 Added non-unit strides example 2011-08-14 06:49:08 +00:00
Ankit Daftery
67b5b07976 Added non-unit strides example 2011-08-14 06:48:46 +00:00
Ankit Daftery
7b088c9df2 Removed todo 2011-08-13 13:55:03 +00:00
Ankit Daftery
3dda62f8b8 Added tutorial for fromdata, i.e. copy free data access 2011-08-12 09:26:55 +00:00
Ankit Daftery
c33460c265 Made a few modifications 2011-08-12 09:26:22 +00:00
Ankit Daftery
4c12b004ec Added example for data access using pointers 2011-08-12 05:16:20 +00:00
Ankit Daftery
5bed132ff8 Added a line for zeros 2011-08-08 17:05:09 +00:00
Ankit Daftery
3ffcf3335a Added working custom dtype example 2011-08-06 21:13:13 +00:00
Ankit Daftery
c314274a56 Added working custom dtype exampel 2011-08-06 21:12:42 +00:00
Ankit Daftery
437373456f Added example for custom dtype 2011-08-05 17:04:29 +00:00
Ankit Daftery
7add755ae0 Added tutorial for dtype 2011-08-05 09:06:19 +00:00
Ankit Daftery
79182d7189 Added ndarray.rst 2011-08-04 17:47:09 +00:00
Ankit Daftery
36e9e38373 Tutorial for ndarrays 2011-08-04 17:45:00 +00:00
Ankit Daftery
45e52301e9 Added from_data implementation, zeros(..) examples 2011-08-04 17:39:04 +00:00
Ankit Daftery
37a73f344b Modified Jamfile 2011-08-03 20:07:40 +00:00
Ankit Daftery
bbd9aad6e9 New examples 2011-08-03 20:07:20 +00:00
Stefan Seefeld
8fa1f9db9e Add support for ReST docs. 2011-07-19 04:32:25 +00:00
Stefan Seefeld
9c56469358 Add example(s) 2011-07-05 14:20:57 +00:00
Stefan Seefeld
196c9e653f Fix indexing tests. 2011-07-03 20:36:55 +00:00
Stefan Seefeld
c572b4db73 Rename (and move) boost.python.numpy to boost.numpy. 2011-07-03 16:42:15 +00:00
Stefan Seefeld
b2519a25a9 Rename (and move) boost.python.numpy to boost.numpy. 2011-07-03 16:40:30 +00:00
Ankit Daftery
2979e4b062 Added index array and boolean tests 2011-06-30 02:50:40 +00:00
Stefan Seefeld
88dd5330d0 Tidy indexing tests. 2011-06-27 14:07:54 +00:00
Ankit Daftery
fa51b58cd6 Added test for slices with steps. Auto-detection of step not implemented yet 2011-06-27 04:09:12 +00:00
Ankit Daftery
419b6ec973 Added tests for indexing 2011-06-24 12:58:57 +00:00
Ankit Daftery
085f574d6e Added more tests for ndarray 2011-06-20 17:18:43 +00:00
Stefan Seefeld
69d9f34f3e Fix ndarray tests. 2011-06-19 20:16:06 +00:00
Stefan Seefeld
36ee7d23f9 Fix ndarray tests. 2011-06-19 20:08:48 +00:00
Ankit Daftery
b269b4b124 Adding test for ndarray.Fails as of now. 2011-06-19 19:38:51 +00:00
Ankit Daftery
20b68f2a2f Added build rule for shapes 2011-06-14 03:36:59 +00:00
Ankit Daftery
2794a9bd15 Test to check the shape of the ndarray 2011-06-14 03:32:10 +00:00
Stefan Seefeld
0a76801936 Move build system improvements 2011-05-30 20:39:43 +00:00
Stefan Seefeld
daf466a697 Work on numpy configuration 2011-05-30 01:18:16 +00:00
Ankit Daftery
718cfd468e First build of numpy.jam module to check for the location of the numpy build directory 2011-05-29 18:39:06 +00:00
Ankit Daftery
3796825523 Updated to include the numpy.jam module 2011-05-29 18:34:21 +00:00
Ankit Daftery
6904a166f7 Updated to include the numpy.jam module 2011-05-29 18:33:56 +00:00
Ankit Daftery
39b9047190 New addition to support boost.build 2011-05-28 12:53:03 +00:00
Ankit Daftery
930167e961 New addition to support boost.build 2011-05-28 12:52:29 +00:00
Ankit Daftery
64b2c1697b Patch to fix scons issue 2011-05-28 12:47:37 +00:00
Ankit Daftery
f0345b2521 New addition to support boost.build 2011-05-28 12:45:52 +00:00
Jim Bosch
77ec571511 Boost.Python.Numpy - moved convenience header one directory lower 2011-02-16 00:24:22 +00:00
Jim Bosch
70c7fbd1d8 Boost.Python.Numpy - removing malfunctioning variant build directories 2011-01-17 20:01:48 +00:00
Jim Bosch
91a1119070 Boost.Python.Numpy - cleaning up build system 2011-01-15 23:00:43 +00:00
Jim Bosch
a300f7cdd0 boost.python.numpy - updates to build system, added some svn:ignores 2011-01-07 23:39:45 +00:00
Jim Bosch
65db10061f numpy - (build system) fixed setting lib output path in tests 2011-01-06 19:37:28 +00:00
Jim Bosch
3d7f523384 numpy - added missing doxygen builder 2011-01-06 19:30:58 +00:00
Jim Bosch
252c3aa695 numpy - updates to site_scons, header documentation 2011-01-04 19:19:20 +00:00
Jim Bosch
584df88fb2 boost.python.numpy - switched to simpler syntax for invoke_matching_array 2010-10-06 22:40:41 +00:00
Jim Bosch
ba1416fff0 boost.python.numpy - moved dtype::invoke_matching_template into separate header, added similar code for invocation based on dimensionality 2010-10-06 19:05:20 +00:00
Jim Bosch
42ca807c82 boost.python.numpy - fixed missing bool instantiation for dtype::get_builtin 2010-10-06 00:31:09 +00:00
Jim Bosch
b988e8c45f boost.python.numpy - adding missing symbols, fixed constness in dtype 2010-07-25 00:18:18 +00:00
Jim Bosch
c7db44f617 boost.python.numpy - added ndarray::reshape 2010-06-29 07:55:33 +00:00
Jim Bosch
f3aecdf2f4 boost.python.numpy - added dtype template invoker 2010-06-24 22:20:55 +00:00
Jim Bosch
40bd0326f3 boost.python numpy - build system separates debug and standard builds 2010-06-08 01:44:59 +00:00
Jim Bosch
99d3a54ad5 boost.python numpy support - improvements to build system 2010-05-18 06:59:41 +00:00
Jim Bosch
c3d186e0bf boost python numpy extensions - updated source files to reflect previous header move 2010-05-15 03:44:45 +00:00
Jim Bosch
e0fa8ec619 numpy python extensions - moved main header file inside subdirectory 2010-05-14 23:43:38 +00:00
Jim Bosch
e2b2ebe862 numpy python extension - added basic SCons build system, started on unit tests 2010-05-14 22:47:14 +00:00
Jim Bosch
eef2eef7dd initial sandbox import for numpy utilities in boost.python 2010-03-08 21:50:13 +00:00
Jim Bosch
189915bc8b folder for new numpy project: improved boost.python bindings for numpy 2010-03-08 20:12:06 +00:00
424 changed files with 8112 additions and 12851 deletions

View File

@@ -4,7 +4,7 @@ environment:
# /E:ON and /V:ON options are not enabled in the batch script intepreter
# See: http://stackoverflow.com/a/13751649/163740
CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\ci\\run_with_env.cmd"
BOOST_PREFIX: C:\Libraries\boost_1_60_0
BOOST_PREFIX: C:\Libraries\boost_1_66_0
matrix:
@@ -15,20 +15,21 @@ environment:
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x" # currently 2.7.9
PYTHON_ARCH: "32"
ARCH: "x86"
MSVC: "14.0"
ARCH: x86
#- PYTHON: "C:\\Python27-x64"
# PYTHON_VERSION: "2.7.x" # currently 2.7.9
# PYTHON_ARCH: "64"
# ARCH: "x86_64"
- PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.x"
PYTHON_ARCH: "64"
MSVC: "12.0"
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"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.x"
PYTHON_ARCH: "64"
MSVC: "14.13.26128"
ARCH: x86_64
install:
# If there is a newer build queued for the same PR, cancel this one.
@@ -44,8 +45,9 @@ install:
- ps: "ls \"C:/\""
- ECHO "Installed libraries:"
- ps: "ls \"C:/Libraries/\""
- ECHO "Installed SDKs:"
- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
## This path doesn't exist with the VS 2017 worker images
#- 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.
@@ -68,19 +70,22 @@ install:
# 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
#- "%CMD_IN_ENV% pip install -r dev-requirements.txt"
- |
curl -LfsS -o faber.tar.gz https://github.com/stefanseefeld/faber/archive/snapshot/2018-04-08.tar.gz
tar xf faber.tar.gz
CD faber-snapshot-2018-04-08
python setup.py install
CD ..
# report the available MSVC compilers
- faber --info=tools cxx
- easy_install sphinx
- pip install numpy
build_script:
# Build the compiled extension
#- "%CMD_IN_ENV% python setup.py build"
- scons config arch=%ARCH% --boost-include=%BOOST_PREFIX%
- scons arch=%ARCH%
- faber --with-boost-include=%BOOST_PREFIX% target.arch=%ARCH% msvc.version=%MSVC%
test_script:
# Run the project tests
#- "%CMD_IN_ENV% python setup.py nosetests"
- scons test arch=%ARCH% --verbose
- faber --with-boost-include=%BOOST_PREFIX% test.report target.arch=%ARCH% msvc.version=%MSVC%
after_test:
# If tests are successful, create binary packages for the project.
@@ -95,4 +100,4 @@ after_test:
#on_success:
# - TODO: upload the content of dist/*.whl to a public wheelhouse
#
#

3
.ci/faber Normal file
View File

@@ -0,0 +1,3 @@
from faber.tools.python import python
p = python(command='$PYTHON')

View File

@@ -5,34 +5,53 @@ 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 ]; then
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
# build happens to contain the "doc/html" tree that we want to push
# into the gh-pages branch. So we step into that directory, create a new repo,
# set the remote appropriately, then commit and push.
cd bin.SCons
cd build
git init
git config user.name "Travis CI"
git config user.email "$COMMIT_AUTHOR_EMAIL"
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.
cp ../index.html .
cp ../doc/index.html doc/
git add index.html
git add doc/index.html
git add -A doc/html
git commit -m "Deploy to GitHub Pages: ${SHA}"
# Now that we're all set up, we can push.

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
bin.SCons
*.pyc
*~
\#*\#

View File

@@ -11,55 +11,108 @@ dist: trusty
language: cpp
env:
global:
- secure: BRNUkxN3p8f+uYKWC3Hr0VPqZA0PxbWr1DJlcI4hbiZtzKhMCWjDmd9UW9CzzexqeOxpd+9s0G87qvOur+wMSVxugDxtTesZrh1czXHeSVxgQrYD783XJtQJ9aYypbChkiboRD6Xpmbq7itwMuHBJMFtCuDxMynpU1jWwkyTf2Y=
matrix:
include:
- compiler: gcc
env: CXX=g++ PYTHON=python CXXFLAGS=-std=c++98
- compiler: gcc
env: CXX=g++ PYTHON=python CXXFLAGS=-std=c++11
- compiler: gcc
env: CXX=g++ PYTHON=python3 CXXFLAGS=-std=c++98
- compiler: gcc
env: CXX=g++ PYTHON=python3 CXXFLAGS=-std=c++11
- compiler: clang
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++98
- compiler: clang
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++11
- env: PYTHON=python DOC=1
global:
- secure: mqoxglbUN/At/r8O7nLVccGldnB1jvhLHNyYjfCXrdOD0GNX+TY2TS1+kIEv9Deg/P6X/QvrBa/ZzbDNryn3mDXBfOSy400ebSIUHHP3HtGHJShOGDyXedY3hZ/dqmxdV3p9hIxv4lcx1HPyC96s4wpiR0S9F1JBzD6scIabezM=
- os: linux
env: CXX=g++ PYTHON=python CXXFLAGS=-std=c++98
- os: linux
env: CXX=g++ PYTHON=python CXXFLAGS=-std=c++11
- os: linux
env: CXX=g++ PYTHON=python3 CXXFLAGS=-std=c++98
- os: linux
env: CXX=g++ PYTHON=python3 CXXFLAGS=-std=c++11
- os: linux
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++98
- os: linux
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++11
- os: osx
env: CXX=clang++ PYTHON=python CXXFLAGS=-std=c++11
- env: PYTHON=python DOC=1
allow_failures:
- os: osx
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- scons
- gcc-4.8
- g++-4.8
- clang
- python-dev python-pip
- 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")
- sudo pip install future
# 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).
- |
if [ ! -d $HOME/Boost/tools/boostbook ]; then
echo "rebuilding Boost prerequisites."
wget https://sourceforge.net/projects/boost/files/boost/1.66.0/boost_1_66_0.tar.gz/download
tar xf download
pushd boost_1_66_0
./bootstrap.sh
./b2 tools/bcp
mkdir -p $HOME/Boost
# Install Boost.Python prerequisites, but not Boost.Python itself.
dist/bin/bcp python tools/boostbook tools/quickbook $HOME/Boost &> /dev/null
rm -rf $HOME/Boost/boost/python*
popd
else
echo "using cached Boost prerequisites."
fi
# Install Faber, the build tool.
date=2018-04-08
wget https://github.com/stefanseefeld/faber/archive/snapshot/$date.tar.gz
tar xf $date.tar.gz
pushd faber-snapshot-$date
#wget https://github.com/stefanseefeld/faber/archive/release/0.2.tar.gz
#tar xf 0.2.tar.gz
#pushd faber-release-0.2
sudo python setup.py install
popd
before_script:
- scons --version
- sed -e "s/\$PYTHON/$PYTHON/g" .ci/faber > ~/.faber
- $PYTHON --version
- faber -h
- ls -l $HOME/Boost
script:
- scons config --python=$PYTHON
- if [ "$DOC" ]; then scons doc; else scons && scons test; fi
- |
if [ "$DOC" ]; then
BOOST_ROOT=$HOME/Boost faber --builddir=build doc.html
else
faber --with-boost-include=$HOME/Boost --builddir=build test.report cxx.name=$CXX cxxflags=$CXXFLAGS
fi
after_success:
# Upload docs only when building upstream.
- if [ "$DOC" -a "$TRAVIS_REPO_SLUG" = "boostorg/python" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then .ci/upload_docs.sh; fi
- |
if [ "$DOC" -a \
"$TRAVIS_REPO_SLUG" = "boostorg/python" -a \
"$TRAVIS_PULL_REQUEST" = "false" ]; then
export GH_TOKEN
.ci/upload_docs.sh
fi

68
Jamfile Normal file
View File

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

23
LICENSE_1_0.txt Normal file
View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

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
@@ -17,7 +19,10 @@ Welcome to Boost.Python, a C++ library which enables seamless interoperability b
See the [Boost.Python](http://boostorg.github.io/python) documentation for details.
# Building ![Build Status](https://travis-ci.org/boostorg/python.svg?branch=develop)
**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)](https://travis-ci.org/boostorg/python) [![Build status](https://ci.appveyor.com/api/projects/status/cgx9xma6v3gjav92/branch/develop?svg=true)](https://ci.appveyor.com/project/stefanseefeld/python/branch/develop)
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.
@@ -25,27 +30,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.
@@ -54,7 +46,7 @@ to build the library.
Run
```
scons test
faber test.report
```
to run the tests.
@@ -63,6 +55,6 @@ to run the tests.
Run
```
scons doc
faber doc.html
```
to build the documentation.
to build the documentation.

View File

@@ -1,34 +0,0 @@
# -*- python -*-
Import("env")
env.Append(CPPPATH = "#/include",CPPDEFINES = ["BOOST_ALL_NO_LIB=1"])
env.AppendUnique(CPPDEFINES = ["${LINK_DYNAMIC and 'BOOST_PYTHON_DYN_LINK=1' or []}"])
for variant in env["variant"]:
env["current_variant"] = variant
env.SetProperty(profile = False)
if variant == "release":
env.SetProperty(optimize = "speed", debug = False)
elif variant == "debug":
env.SetProperty(optimize = "no", debug = True)
elif variant == "profile":
env.SetProperty(optimize = "speed", profile = True, debug = True)
for linking in env["link"]:
env["linking"] = linking
if linking == "dynamic":
env["LINK_DYNAMIC"] = True
else:
env["LINK_DYNAMIC"] = False
for threading in env["threading"]:
env["current_threading"] = threading
env.SetProperty(threading = threading)
variant_dir=env.subst("$BOOST_CURRENT_VARIANT_DIR")
env.SConscript("src/SConscript", variant_dir=variant_dir + '/src',
exports = { "env" : env.Clone(BOOST_LIB = 'python') })
if GetOption("test"):
test_env = env.Clone(BOOST_LIB = 'python', BOOST_TEST = True)
test_env.BoostUseLib('python')
env.SConscript("test/SConscript", variant_dir=variant_dir + '/test',
exports = { "env" : test_env })

View File

@@ -1,100 +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 = Environment(toolpath=['config/tools'],
tools=['default', 'libs', 'tests', 'doc'],
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()
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.62'
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') })

167
build/Jamfile Normal file
View File

@@ -0,0 +1,167 @@
# Copyright David Abrahams 2001-2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import os ;
import indirect ;
import modules ;
import feature ;
import property ;
import python ;
if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
{
# Attempt default configuration of python
import toolset : using ;
using python ;
}
if [ python.configured ] || ( --without-python in [ modules.peek : ARGV ] )
{
alias config-warning ;
}
else
{
message config-warning
: "warning: No python installation configured and autoconfiguration"
: "note: failed. See http://www.boost.org/libs/python/doc/building.html"
: "note: for configuration instructions or pass --without-python to"
: "note: suppress this message and silently skip all Boost.Python targets"
;
}
project boost/python
: source-location ../src
;
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
local rule eq ( a : b ) { if $(a) = $(b) { return 1 ; } }
lib boost_python
: # 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
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(__name__).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 ]
<include>$(numpy-include)
<library>boost_python
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(__name__).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 ]
{
if [ python.numpy ]
{
boost-install boost_python boost_numpy ;
}
else
{
boost-install boost_python ;
}
}
else
{
# 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,151 +0,0 @@
# Copyright David Abrahams 2001-2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import os ;
import indirect ;
import modules ;
import feature ;
import python ;
if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
{
# Attempt default configuration of python
import toolset : using ;
using python ;
}
if [ python.configured ] || ( --without-python in [ modules.peek : ARGV ] )
{
alias config-warning ;
}
else
{
message config-warning
: "warning: No python installation configured and autoconfiguration"
: "note: failed. See http://www.boost.org/libs/python/doc/building.html"
: "note: for configuration instructions or pass --without-python to"
: "note: suppress this message and silently skip all Boost.Python targets"
;
}
rule find-py3-version
{
local versions = [ feature.values python ] ;
local py3ver ;
for local v in $(versions)
{
if $(v) >= 3.0
{
py3ver = $(v) ;
}
}
return $(py3ver) ;
}
py3-version = [ find-py3-version ] ;
project boost/python
: source-location ../src
: requirements
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(__name__).tag
;
rule tag ( name : type ? : property-set )
{
local result = $(name) ;
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
{
if $(name) = boost_python && $(PYTHON_ID)
{
result = $(result)-$(PYTHON_ID) ;
}
}
# forward to the boost tagging rule
return [ indirect.call $(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
$(result) : $(type) : $(property-set) ] ;
}
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
rule lib_boost_python ( is-py3 ? )
{
lib [ cond $(is-py3) : boost_python3 : boost_python ]
: # sources
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
object/enum.cpp
object/class.cpp
object/function.cpp
object/inheritance.cpp
object/life_support.cpp
object/pickle_support.cpp
errors.cpp
module.cpp
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object/stl_iterator.cpp
object_protocol.cpp
object_operators.cpp
wrapper.cpp
import.cpp
exec.cpp
object/function_doc_signature.cpp
: # 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
[ cond $(is-py3) : <python>$(py3-version) ]
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
}
lib_boost_python ;
boost-install boost_python ;
if $(py3-version)
{
lib_boost_python yes ;
boost-install boost_python3 ;
}

Binary file not shown.

View File

@@ -1,131 +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 boost
def add_options(vars):
ui.add_option('-V', '--verbose', dest='verbose', action='store_true', help='verbose mode: print full commands.')
python.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'))
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():
checks = OrderedDict()
checks['cxx'] = cxx.check
checks['python'] = python.check
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,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,70 +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 exists(env):
return True
def generate(env):
env.AddMethod(QuickBook)
env.AddMethod(BoostBook)
env.AddMethod(BoostHTML)
env.AddMethod(BoostRST)

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,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

@@ -4,10 +4,14 @@
# 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 boostbook ;
import quickbook ;
import docutils ;
import os ;
path-constant here : . ;
path-constant images : html/images ;
project python/doc
: requirements
-<xsl:param>boost.defaults=Boost
@@ -17,9 +21,16 @@ project python/doc
<format>html:<xsl:param>chunk.section.depth=1
;
import boostbook ;
import quickbook ;
import docutils ;
make numpy : numpy/index.rst : @sphinx-build ;
if [ os.name ] = NT
{
actions sphinx-build { chdir "$(>:D)" && make clean && make html}
}
else
{
actions sphinx-build { make -C "$(>:D)" clean html}
}
boostbook python : python.qbk
: <format>html:<name>$(here)/html
@@ -47,3 +58,9 @@ html article : article.rst
: <location>html
<docutils-html>"--link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript --stylesheet=rst.css"
;
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease : python tutorial reference numpy article ;
explicit boostrelease ;

View File

@@ -1,49 +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'])

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

BIN
doc/images/jam.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

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

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

133
doc/numpy/Makefile Normal file
View File

@@ -0,0 +1,133 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
HTMLDIR = ../html/numpy
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
all: html
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(HTMLDIR)
@echo
@echo "Build finished. The HTML pages are in $(HTMLDIR)."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/BoostNumPy.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/BoostNumPy.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/BoostNumPy"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/BoostNumPy"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
make -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

716
doc/numpy/_static/boost.css Normal file
View File

@@ -0,0 +1,716 @@
/*=============================================================================
Copyright (c) 2004 Joel de Guzman
http://spirit.sourceforge.net/
Copyright 2013 Niall Douglas additions for colors and alignment.
Copyright 2013 Paul A. Bristow additions for more colors and alignments.
Distributed under the Boost Software License, Version 1.0. (See accompany-
ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
/*=============================================================================
Body defaults
=============================================================================*/
body
{
margin: 1em;
font-family: sans-serif;
}
/*=============================================================================
Paragraphs
=============================================================================*/
p
{
text-align: left;
font-size: 10pt;
line-height: 1.15;
}
/*=============================================================================
Program listings
=============================================================================*/
/* Code on paragraphs */
p tt.computeroutput
{
font-size: 9pt;
}
pre.synopsis
{
font-size: 9pt;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
.programlisting,
.screen
{
font-size: 9pt;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
/* Program listings in tables don't get borders */
td .programlisting,
td .screen
{
margin: 0pc 0pc 0pc 0pc;
padding: 0pc 0pc 0pc 0pc;
}
/*=============================================================================
Headings
=============================================================================*/
h1, h2, h3, h4, h5, h6
{
text-align: left;
margin: 1em 0em 0.5em 0em;
font-weight: bold;
}
h1 { font-size: 140%; }
h2 { font-weight: bold; font-size: 140%; }
h3 { font-weight: bold; font-size: 130%; }
h4 { font-weight: bold; font-size: 120%; }
h5 { font-weight: normal; font-style: italic; font-size: 110%; }
h6 { font-weight: normal; font-style: italic; font-size: 100%; }
/* Top page titles */
title,
h1.title,
h2.title
h3.title,
h4.title,
h5.title,
h6.title,
.refentrytitle
{
font-weight: bold;
margin-bottom: 1pc;
}
h1.title { font-size: 140% }
h2.title { font-size: 140% }
h3.title { font-size: 130% }
h4.title { font-size: 120% }
h5.title { font-size: 110% }
h6.title { font-size: 100% }
.section h1
{
margin: 0em 0em 0.5em 0em;
font-size: 140%;
}
.section h2 { font-size: 140% }
.section h3 { font-size: 130% }
.section h4 { font-size: 120% }
.section h5 { font-size: 110% }
.section h6 { font-size: 100% }
/* Code on titles */
h1 tt.computeroutput { font-size: 140% }
h2 tt.computeroutput { font-size: 140% }
h3 tt.computeroutput { font-size: 130% }
h4 tt.computeroutput { font-size: 130% }
h5 tt.computeroutput { font-size: 130% }
h6 tt.computeroutput { font-size: 130% }
/*=============================================================================
Author
=============================================================================*/
h3.author
{
font-size: 100%
}
/*=============================================================================
Lists
=============================================================================*/
li
{
font-size: 10pt;
line-height: 1.3;
}
/* Unordered lists */
ul
{
text-align: left;
}
/* Ordered lists */
ol
{
text-align: left;
}
/*=============================================================================
Links
=============================================================================*/
a
{
text-decoration: none; /* no underline */
}
a:hover
{
text-decoration: underline;
}
/*=============================================================================
Spirit style navigation
=============================================================================*/
.spirit-nav
{
text-align: right;
}
.spirit-nav a
{
color: white;
padding-left: 0.5em;
}
.spirit-nav img
{
border-width: 0px;
}
/*=============================================================================
Copyright footer
=============================================================================*/
.copyright-footer
{
text-align: right;
font-size: 70%;
}
.copyright-footer p
{
text-align: right;
font-size: 80%;
}
/*=============================================================================
Table of contents
=============================================================================*/
div.toc
{
margin: 1pc 4% 0pc 4%;
padding: 0.1pc 1pc 0.1pc 1pc;
font-size: 80%;
line-height: 1.15;
}
.boost-toc
{
float: right;
padding: 0.5pc;
}
/* Code on toc */
.toc .computeroutput { font-size: 120% }
/* No margin on nested menus */
.toc dl dl { margin: 0; }
/*=============================================================================
Tables
=============================================================================*/
.table-title,
div.table p.title
{
margin-left: 4%;
padding-right: 0.5em;
padding-left: 0.5em;
}
.informaltable table,
.table table
{
width: 92%;
margin-left: 4%;
margin-right: 4%;
}
div.informaltable table,
div.table table
{
padding: 4px;
}
/* Table Cells */
div.informaltable table tr td,
div.table table tr td
{
padding: 0.5em;
text-align: left;
font-size: 9pt;
}
div.informaltable table tr th,
div.table table tr th
{
padding: 0.5em 0.5em 0.5em 0.5em;
border: 1pt solid white;
font-size: 80%;
}
table.simplelist
{
width: auto !important;
margin: 0em !important;
padding: 0em !important;
border: none !important;
}
table.simplelist td
{
margin: 0em !important;
padding: 0em !important;
text-align: left !important;
font-size: 9pt !important;
border: none !important;
}
/*=============================================================================
Suppress margins in tables
=============================================================================*/
table th > *:first-child,
table td > *:first-child
{
margin-top: 0;
}
table th > *:last-child,
table td > *:last-child
{
margin-bottom: 0;
}
/*=============================================================================
Blurbs
=============================================================================*/
div.note,
div.tip,
div.important,
div.caution,
div.warning,
p.blurb
{
font-size: 9pt; /* A little bit smaller than the main text */
line-height: 1.2;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
p.blurb img
{
padding: 1pt;
}
/*=============================================================================
Variable Lists
=============================================================================*/
div.variablelist
{
margin: 1em 0;
}
/* Make the terms in definition lists bold */
div.variablelist dl dt,
span.term
{
font-weight: bold;
font-size: 10pt;
}
div.variablelist table tbody tr td
{
text-align: left;
vertical-align: top;
padding: 0em 2em 0em 0em;
font-size: 10pt;
margin: 0em 0em 0.5em 0em;
line-height: 1;
}
div.variablelist dl dt
{
margin-bottom: 0.2em;
}
div.variablelist dl dd
{
margin: 0em 0em 0.5em 2em;
font-size: 10pt;
}
div.variablelist table tbody tr td p,
div.variablelist dl dd p
{
margin: 0em 0em 0.5em 0em;
line-height: 1;
}
/*=============================================================================
Misc
=============================================================================*/
/* Title of books and articles in bibliographies */
span.title
{
font-style: italic;
}
span.underline
{
text-decoration: underline;
}
span.strikethrough
{
text-decoration: line-through;
}
/* Copyright, Legal Notice */
div div.legalnotice p
{
text-align: left
}
/*=============================================================================
Colors
=============================================================================*/
@media screen
{
body {
background-color: #FFFFFF;
color: #000000;
}
/* Syntax Highlighting */
.keyword { color: #0000AA; }
.identifier { color: #000000; }
.special { color: #707070; }
.preprocessor { color: #402080; }
.char { color: teal; }
.comment { color: #800000; }
.string { color: teal; }
.number { color: teal; }
.white_bkd { background-color: #FFFFFF; }
.dk_grey_bkd { background-color: #999999; }
/* Links */
a, a .keyword, a .identifier, a .special, a .preprocessor
a .char, a .comment, a .string, a .number
{
color: #005a9c;
}
a:visited, a:visited .keyword, a:visited .identifier,
a:visited .special, a:visited .preprocessor a:visited .char,
a:visited .comment, a:visited .string, a:visited .number
{
color: #9c5a9c;
}
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
{
text-decoration: none; /* no underline */
color: #000000;
}
/* Copyright, Legal Notice */
.copyright
{
color: #666666;
font-size: small;
}
div div.legalnotice p
{
color: #666666;
}
/* Program listing */
pre.synopsis
{
border: 1px solid #DCDCDC;
}
.programlisting,
.screen
{
border: 1px solid #DCDCDC;
}
td .programlisting,
td .screen
{
border: 0px solid #DCDCDC;
}
/* Blurbs */
div.note,
div.tip,
div.important,
div.caution,
div.warning,
p.blurb
{
border: 1px solid #DCDCDC;
}
/* Table of contents */
div.toc
{
border: 1px solid #DCDCDC;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid #DCDCDC;
}
div.informaltable table tr th,
div.table table tr th
{
background-color: #F0F0F0;
border: 1px solid #DCDCDC;
}
.copyright-footer
{
color: #8F8F8F;
}
/* Misc */
span.highlight
{
color: #00A000;
}
}
@media print
{
/* Links */
a
{
color: black;
}
a:visited
{
color: black;
}
.spirit-nav
{
display: none;
}
/* Program listing */
pre.synopsis
{
border: 1px solid gray;
}
.programlisting,
.screen
{
border: 1px solid gray;
}
td .programlisting,
td .screen
{
border: 0px solid #DCDCDC;
}
/* Table of contents */
div.toc
{
border: 1px solid gray;
}
.informaltable table,
.table table
{
border: 1px solid gray;
border-collapse: collapse;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid gray;
}
div.informaltable table tr th,
div.table table tr th
{
border: 1px solid gray;
}
table.simplelist tr td
{
border: none !important;
}
/* Misc */
span.highlight
{
font-weight: bold;
}
}
/*=============================================================================
Images
=============================================================================*/
span.inlinemediaobject img
{
vertical-align: middle;
}
/*==============================================================================
Super and Subscript: style so that line spacing isn't effected, see
http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=1&postId=5341
==============================================================================*/
sup,
sub {
height: 0;
line-height: 1;
vertical-align: baseline;
position: relative;
}
/* For internet explorer: */
* html sup,
* html sub {
vertical-align: bottom;
}
sup {
bottom: 1ex;
}
sub {
top: .5ex;
}
/*==============================================================================
Indexes: pretty much the same as the TOC.
==============================================================================*/
.index
{
font-size: 80%;
padding-top: 0px;
padding-bottom: 0px;
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
}
.index ul
{
padding-left: 3em;
}
.index p
{
padding: 2px;
margin: 2px;
}
.index-entry-level-0
{
font-weight: bold;
}
.index em
{
font-weight: bold;
}
/*==============================================================================
Alignment and coloring use 'role' feature, available from Quickbook 1.6 up.
Added from Niall Douglas for role color and alignment.
http://article.gmane.org/gmane.comp.lib.boost.devel/243318
*/
/* Add text alignment (see http://www.w3schools.com/cssref/pr_text_text-align.asp) */
span.aligncenter
{
display: inline-block; width: 100%; text-align: center;
}
span.alignright
{
display: inline-block; width: 100%; text-align: right;
}
/* alignleft is the default. */
span.alignleft
{
display: inline-block; width: 100%; text-align: left;
}
/* alignjustify stretches the word spacing so that each line has equal width
within a chosen fraction of page width (here arbitrarily 20%).
*Not* useful inside table items as the column width remains the total string width.
Nor very useful, except to temporarily restrict the width.
*/
span.alignjustify
{
display: inline-block; width: 20%; text-align: justify;
}
/* Text colors.
Names at http://www.w3.org/TR/2002/WD-css3-color-20020219/ 4.3. X11 color keywords.
Quickbook Usage: [role red Some red text]
*/
span.red { inline-block; color: red; }
span.green { color: green; }
span.lime { color: #00FF00; }
span.blue { color: blue; }
span.navy { color: navy; }
span.yellow { color: yellow; }
span.magenta { color: magenta; }
span.indigo { color: #4B0082; }
span.cyan { color: cyan; }
span.purple { color: purple; }
span.gold { color: gold; }
span.silver { color: silver; } /* lighter gray */
span.gray { color: #808080; } /* light gray */

BIN
doc/numpy/_static/boost.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
doc/numpy/_static/bpl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
doc/numpy/_static/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

BIN
doc/numpy/_static/next.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

BIN
doc/numpy/_static/prev.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

View File

@@ -0,0 +1,38 @@
@import url(boost.css);
.header h1 a
{
color: #00507f;
font-size: 200%;
font-style: italic;
}
.header h3 { margin: 1px;}
#contents
{
/* border-bottom: solid thin black;*/
}
.highlight
{
border: 1px solid #dcdcdc;
background-color: inherit;
padding: 0 1em;
margin: 0 5em;
}
#searchbox
{
float: right;
width: auto;
margin: 0 2em;
}
.admonition-title { font-weight: bold;}
.toctree-wrapper
{
border: 1px solid #dcdcdc;
padding: 1em;
margin: 0 2em;
}
.toctree-wrapper .caption,
.toctree-wrapper .topic-title { font-weight: bold;}

BIN
doc/numpy/_static/up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

View File

@@ -0,0 +1,120 @@
{%- macro navbar() %}
<div class="navbar" style="text-align:right;">
{#%- if parents|count > 0 %#}
{#{ parents[1].title }#}
{%- if prev %}
<a class="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}"><img src="{{ pathto('_static/prev.png', 1) }}" alt="prev"/></a>
{%- endif %}
{%- if parents %}
<a class="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}"><img src="{{ pathto('_static/up.png', 1) }}" alt="up"/></a>
{%- endif %}
{%- if next %}
<a class="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}"><img src="{{ pathto('_static/next.png', 1) }}" alt="next"/></a>
{%- endif %}
{#%- endif %#}
</div>
{%- endmacro %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
{{ metatags }}
{%- if builder != 'htmlhelp' %}
{%- set titlesuffix = docstitle|e %}
{%- set titlesuffix = " - " + titlesuffix %}
{%- endif %}
<title>{{ title|striptags }}{{ titlesuffix }}</title>
{%- if builder == 'web' %}
<link rel="stylesheet" href="{{ pathto('index') }}?do=stylesheet{%
if in_admin_panel %}&admin=yes{% endif %}" type="text/css" />
{%- for link, type, title in page_links %}
<link rel="alternate" type="{{ type|e(true) }}" title="{{ title|e(true) }}" href="{{ link|e(true) }}" />
{%- endfor %}
{%- else %}
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
<link rel="stylesheet" href="{{ pathto('_static/style.css', 1) }}" type="text/css" />
{%- endif %}
{%- if builder != 'htmlhelp' %}
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '{{ pathto("", 1) }}',
VERSION: '{{ release|e }}',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '{{ file_suffix }}'
};
</script>
{%- for scriptfile in script_files %}
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
{%- endfor %}
{%- if use_opensearch %}
<link rel="search" type="application/opensearchdescription+xml"
title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
href="{{ pathto('_static/opensearch.xml', 1) }}"/>
{%- endif %}
{%- if favicon %}
<link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
{%- endif %}
{%- endif %}
{%- block linktags %}
{%- if hasdoc('about') %}
<link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
{%- endif %}
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
{%- if hasdoc('copyright') %}
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
{%- endif %}
<link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}" />
{%- if parents %}
<link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}" />
{%- endif %}
{%- if next %}
<link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}" />
{%- endif %}
{%- if prev %}
<link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}" />
{%- endif %}
{%- endblock %}
{%- block extrahead %} {% endblock %}
</head>
<body>
<div class="header">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="{{ pathto('index') }}"><img
alt="C++ Boost" src="{{ pathto('_static/' + logo, 1) }}" border="0"></a></h3>
</td>
<td >
<h1 align="center"><a href="{{ pathto('index') }}">(NumPy)</a></h1>
<!-- <h2 align="center">CallPolicies Concept</h2>-->
</td>
<td>
{%- if pagename != "search" %}
<div id="searchbox" style="display: none">
<form class="search" action="{{ pathto('search') }}" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="{{ _('Search') }}" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
{%- endif %}
</td>
</tr>
</table>
</div>
<hr/>
<div class="content">
{%- block top_navbar %}{{ navbar() }}{% endblock %}
{% block body %} {% endblock %}
{%- block bottom_navbar %}{{ navbar() }}{% endblock %}
</div>
</body>
</html>

219
doc/numpy/conf.py Normal file
View File

@@ -0,0 +1,219 @@
# -*- coding: utf-8 -*-
#
# Boost.Python NumPy documentation build configuration file, created by
# sphinx-quickstart on Thu Oct 27 09:04:58 2011.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Boost.Python NumPy extension'
copyright = u'2011, Stefan Seefeld'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '1.0'
# The full version, including alpha/beta/rc tags.
release = '1.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'default'
highlight_language = 'c++'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = '_static/bpl.png'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'BoostPythonNumPydoc'
html_add_permalinks = False
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'BoostPythonNumPy.tex', u'Boost.Python NumPy Documentation',
u'Stefan Seefeld', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'boostnumpy', u'Boost.Python NumPy Documentation',
[u'Stefan Seefeld'], 1)
]

14
doc/numpy/index.rst Normal file
View File

@@ -0,0 +1,14 @@
.. Boost.Python NumPy extension documentation master file, created by
sphinx-quickstart on Thu Oct 27 09:04:58 2011.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to the documentation of the Boost.Python NumPy extension!
=================================================================
.. toctree::
:maxdepth: 2
Tutorial <tutorial/index>
Reference <reference/index>

171
doc/numpy/make.bat Normal file
View File

@@ -0,0 +1,171 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set HTMLDIR=../html/numpy
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %HTMLDIR%
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %HTMLDIR%.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\BoostNumPy.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\BoostNumPy.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end

View File

@@ -0,0 +1,110 @@
binary_ufunc
============
.. contents :: Table of Contents
A ``binary_ufunc`` is a struct used as an intermediate step to broadcast two arguments so that a C++ function can be converted to a ufunc like function
``<boost/python/numpy/ufunc.hpp>`` contains the ``binary_ufunc`` structure definitions
synopsis
--------
::
namespace boost
{
namespace python
{
namespace numpy
{
template <typename TBinaryFunctor,
typename TArgument1=typename TBinaryFunctor::first_argument_type,
typename TArgument2=typename TBinaryFunctor::second_argument_type,
typename TResult=typename TBinaryFunctor::result_type>
struct binary_ufunc
{
static object call(TBinaryFunctor & self,
object const & input1,
object const & input2,
object const & output);
static object make();
};
}
}
}
constructors
------------
::
struct example_binary_ufunc
{
typedef any_valid first_argument_type;
typedef any_valid second_argument_type;
typedef any_valid result_type;
};
:Requirements: The ``any_valid`` type must be defined using typedef as a valid C++ type in order to use the struct methods correctly
:Note: The struct must be exposed as a Python class, and an instance of the class must be created to use the ``call`` method corresponding to the ``__call__`` attribute of the Python object
accessors
---------
::
template <typename TBinaryFunctor,
typename TArgument1=typename TBinaryFunctor::first_argument_type,
typename TArgument2=typename TBinaryFunctor::second_argument_type,
typename TResult=typename TBinaryFunctor::result_type>
static object call(TBinaryFunctor & self,
object const & input,
object const & output);
:Requires: Typenames ``TBinaryFunctor`` and optionally ``TArgument1`` and ``TArgument2`` for argument type and ``TResult`` for result type
:Effects: Passes a Python object to the underlying C++ functor after broadcasting its arguments
::
template <typename TBinaryFunctor,
typename TArgument1=typename TBinaryFunctor::first_argument_type,
typename TArgument2=typename TBinaryFunctor::second_argument_type,
typename TResult=typename TBinaryFunctor::result_type>
static object make();
:Requires: Typenames ``TBinaryFunctor`` and optionally ``TArgument1`` and ``TArgument2`` for argument type and ``TResult`` for result type
:Returns: A Python function object to call the overloaded () operator in the struct (in typical usage)
Example(s)
----------
::
namespace p = boost::python;
namespace np = boost::python::numpy;
struct BinarySquare
{
typedef double first_argument_type;
typedef double second_argument_type;
typedef double result_type;
double operator()(double a,double b) const { return (a*a + b*b) ; }
};
p::object ud = p::class_<BinarySquare, boost::shared_ptr<BinarySquare> >("BinarySquare").def("__call__", np::binary_ufunc<BinarySquare>::make());
p::object inst = ud();
result_array = inst.attr("__call__")(demo_array,demo_array) ;
std::cout << "Square of list with binary ufunc is " << p::extract <char const * > (p::str(result_array)) << std::endl ;

View File

@@ -0,0 +1,92 @@
dtype
=====
.. contents :: Table of Contents
A `dtype`_ is an object describing the type of the elements of an ndarray
.. _dtype: http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#data-type-objects-dtype
``<boost/python/numpy/dtype.hpp>`` contains the method calls necessary to generate a python object equivalent to a numpy.dtype from builtin C++ objects, as well as to create custom dtypes from user defined types
synopsis
--------
::
namespace boost
{
namespace python
{
namespace numpy
{
class dtype : public object
{
static python::detail::new_reference convert(object::object_cref arg, bool align);
public:
// Convert an arbitrary Python object to a data-type descriptor object.
template <typename T>
explicit dtype(T arg, bool align=false);
// Get the built-in numpy dtype associated with the given scalar template type.
template <typename T> static dtype get_builtin();
// Return the size of the data type in bytes.
int get_itemsize() const;
};
}
}
}
constructors
------------
::
template <typename T>
explicit dtype(T arg, bool align=false)
:Requirements: ``T`` must be either :
* a built-in C++ typename convertible to object
* a valid python object or convertible to object
:Effects: Constructs an object from the supplied python object / convertible
to object / builtin C++ data type
:Throws: Nothing
::
template <typename T> static dtype get_builtin();
:Requirements: The typename supplied, ``T`` must be a builtin C++ type also supported by numpy
:Returns: Numpy dtype corresponding to builtin C++ type
accessors
---------
::
int get_itemsize() const;
:Returns: the size of the data type in bytes.
Example(s)
----------
::
namespace p = boost::python;
namespace np = boost::python::numpy;
np::dtype dtype = np::dtype::get_builtin<double>();
p::tuple for_custom_dtype = p::make_tuple("ha",dtype);
np::dtype custom_dtype = np::dtype(list_for_dtype);

View File

@@ -0,0 +1,12 @@
Boost.Python NumPy extension Reference
======================================
.. toctree::
:maxdepth: 2
dtype
ndarray
unary_ufunc
binary_ufunc
multi_iter

View File

@@ -0,0 +1,94 @@
multi_iter
==========
.. contents :: Table of Contents
A ``multi_iter`` is a Python object, intended to be used as an iterator It should generally only be used in loops.
``<boost/python/numpy/ufunc.hpp>`` contains the class definitions for ``multi_iter``
synopsis
--------
::
namespace boost
{
namespace python
{
namespace numpy
{
class multi_iter : public object
{
public:
void next();
bool not_done() const;
char * get_data(int n) const;
int const get_nd() const;
Py_intptr_t const * get_shape() const;
Py_intptr_t const shape(int n) const;
};
multi_iter make_multi_iter(object const & a1);
multi_iter make_multi_iter(object const & a1, object const & a2);
multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3);
}
}
}
constructors
------------
::
multi_iter make_multi_iter(object const & a1);
multi_iter make_multi_iter(object const & a1, object const & a2);
multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3);
:Returns: A Python iterator object broadcasting over one, two or three sequences as supplied
accessors
---------
::
void next();
:Effects: Increments the iterator
::
bool not_done() const;
:Returns: boolean value indicating whether the iterator is at its end
::
char * get_data(int n) const;
:Returns: a pointer to the element of the nth broadcasted array.
::
int const get_nd() const;
:Returns: the number of dimensions of the broadcasted array expression
::
Py_intptr_t const * get_shape() const;
:Returns: the shape of the broadcasted array expression as an array of integers.
::
Py_intptr_t const shape(int n) const;
:Returns: the shape of the broadcasted array expression in the nth dimension.

View File

@@ -0,0 +1,382 @@
ndarray
=======
.. contents :: Table of Contents
A `ndarray`_ is an N-dimensional array which contains items of the same type and size, where N is the number of dimensions and is specified in the form of a ``shape`` tuple. Optionally, the numpy ``dtype`` for the objects contained may also be specified.
.. _ndarray: http://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html
.. _dtype: http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#data-type-objects-dtype
``<boost/python/numpy/ndarray.hpp>`` contains the structures and methods necessary to move raw data between C++ and Python and create ndarrays from the data
synopsis
--------
::
namespace boost
{
namespace python
{
namespace numpy
{
class ndarray : public object
{
public:
enum bitflag
{
NONE=0x0, C_CONTIGUOUS=0x1, F_CONTIGUOUS=0x2, V_CONTIGUOUS=0x1|0x2,
ALIGNED=0x4, WRITEABLE=0x8, BEHAVED=0x4|0x8,
CARRAY_RO=0x1|0x4, CARRAY=0x1|0x4|0x8, CARRAY_MIS=0x1|0x8,
FARRAY_RO=0x2|0x4, FARRAY=0x2|0x4|0x8, FARRAY_MIS=0x2|0x8,
UPDATE_ALL=0x1|0x2|0x4, VARRAY=0x1|0x2|0x8, ALL=0x1|0x2|0x4|0x8
};
ndarray view(dtype const & dt) const;
ndarray astype(dtype const & dt) const;
ndarray copy() const;
int const shape(int n) const;
int const strides(int n) const;
char * get_data() const;
dtype get_dtype() const;
python::object get_base() const;
void set_base(object const & base);
Py_intptr_t const * get_shape() const;
Py_intptr_t const * get_strides() const;
int const get_nd() const;
bitflag const get_flags() const;
ndarray transpose() const;
ndarray squeeze() const;
ndarray reshape(tuple const & shape) const;
object scalarize() const;
};
ndarray zeros(tuple const & shape, dtype const & dt);
ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt);
ndarray empty(tuple const & shape, dtype const & dt);
ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt);
ndarray array(object const & obj);
ndarray array(object const & obj, dtype const & dt);
template <typename Container>
ndarray from_data(void * data,dtype const & dt,Container shape,Container strides,python::object const & owner);
template <typename Container>
ndarray from_data(void const * data, dtype const & dt, Container shape, Container strides, object const & owner);
ndarray from_object(object const & obj, dtype const & dt,int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE);
ndarray from_object(object const & obj, dtype const & dt,int nd, ndarray::bitflag flags=ndarray::NONE);
ndarray from_object(object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE);
ndarray from_object(object const & obj, int nd_min, int nd_max,ndarray::bitflag flags=ndarray::NONE);
ndarray from_object(object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE);
ndarray from_object(object const & obj, ndarray::bitflag flags=ndarray::NONE)
ndarray::bitflag operator|(ndarray::bitflag a, ndarray::bitflag b) ;
ndarray::bitflag operator&(ndarray::bitflag a, ndarray::bitflag b);
}
constructors
------------
::
ndarray view(dtype const & dt) const;
:Returns: new ndarray with old ndarray data cast as supplied dtype
::
ndarray astype(dtype const & dt) const;
:Returns: new ndarray with old ndarray data converted to supplied dtype
::
ndarray copy() const;
:Returns: Copy of calling ndarray object
::
ndarray transpose() const;
:Returns: An ndarray with the rows and columns interchanged
::
ndarray squeeze() const;
:Returns: An ndarray with all unit-shaped dimensions removed
::
ndarray reshape(tuple const & shape) const;
:Requirements: The new ``shape`` of the ndarray must be supplied as a tuple
:Returns: An ndarray with the same data but reshaped to the ``shape`` supplied
::
object scalarize() const;
:Returns: A scalar if the ndarray has only one element, otherwise it returns the entire array
::
ndarray zeros(tuple const & shape, dtype const & dt);
ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt);
:Requirements: The following parameters must be supplied as required :
* the ``shape`` or the size of all dimensions, as a tuple
* the ``dtype`` of the data
* the ``nd`` size for a square shaped ndarray
* the ``shape`` Py_intptr_t
:Returns: A new ndarray with the given shape and data type, with data initialized to zero.
::
ndarray empty(tuple const & shape, dtype const & dt);
ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt);
:Requirements: The following parameters must be supplied :
* the ``shape`` or the size of all dimensions, as a tuple
* the ``dtype`` of the data
* the ``shape`` Py_intptr_t
:Returns: A new ndarray with the given shape and data type, with data left uninitialized.
::
ndarray array(object const & obj);
ndarray array(object const & obj, dtype const & dt);
:Returns: A new ndarray from an arbitrary Python sequence, with dtype of each element specified optionally
::
template <typename Container>
inline ndarray from_data(void * data,dtype const & dt,Container shape,Container strides,python::object const & owner)
:Requirements: The following parameters must be supplied :
* the ``data`` which is a generic C++ data container
* the dtype ``dt`` of the data
* the ``shape`` of the ndarray as Python object
* the ``strides`` of each dimension of the array as a Python object
* the ``owner`` of the data, in case it is not the ndarray itself
:Returns: ndarray with attributes and data supplied
:Note: The ``Container`` typename must be one that is convertible to a std::vector or python object type
::
ndarray from_object(object const & obj, dtype const & dt,int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE);
:Requirements: The following parameters must be supplied :
* the ``obj`` Python object to convert to ndarray
* the dtype ``dt`` of the data
* minimum number of dimensions ``nd_min`` of the ndarray as Python object
* maximum number of dimensions ``nd_max`` of the ndarray as Python object
* optional ``flags`` bitflags
:Returns: ndarray constructed with dimensions and data supplied as parameters
::
inline ndarray from_object(object const & obj, dtype const & dt, int nd, ndarray::bitflag flags=ndarray::NONE);
:Requirements: The following parameters must be supplied :
* the ``obj`` Python object to convert to ndarray
* the dtype ``dt`` of the data
* number of dimensions ``nd`` of the ndarray as Python object
* optional ``flags`` bitflags
:Returns: ndarray with dimensions ``nd`` x ``nd`` and suplied parameters
::
inline ndarray from_object(object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE)
:Requirements: The following parameters must be supplied :
* the ``obj`` Python object to convert to ndarray
* the dtype ``dt`` of the data
* optional ``flags`` bitflags
:Returns: Supplied Python object as ndarray
::
ndarray from_object(object const & obj, int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE);
:Requirements: The following parameters must be supplied :
* the ``obj`` Python object to convert to ndarray
* minimum number of dimensions ``nd_min`` of the ndarray as Python object
* maximum number of dimensions ``nd_max`` of the ndarray as Python object
* optional ``flags`` bitflags
:Returns: ndarray with supplied dimension limits and parameters
:Note: dtype need not be supplied here
::
inline ndarray from_object(object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE);
:Requirements: The following parameters must be supplied :
* the ``obj`` Python object to convert to ndarray
* the dtype ``dt`` of the data
* number of dimensions ``nd`` of the ndarray as Python object
* optional ``flags`` bitflags
:Returns: ndarray of ``nd`` x ``nd`` dimensions constructed from the supplied object
::
inline ndarray from_object(object const & obj, ndarray::bitflag flags=ndarray::NONE)
:Requirements: The following parameters must be supplied :
* the ``obj`` Python object to convert to ndarray
* optional ``flags`` bitflags
:Returns: ndarray of same dimensions and dtype as supplied Python object
accessors
---------
::
int const shape(int n) const;
:Returns: The size of the n-th dimension of the ndarray
::
int const strides(int n) const;
:Returns: The stride of the nth dimension.
::
char * get_data() const;
:Returns: Array's raw data pointer as a char
:Note: This returns char so stride math works properly on it.User will have to reinterpret_cast it.
::
dtype get_dtype() const;
:Returns: Array's data-type descriptor object (dtype)
::
object get_base() const;
:Returns: Object that owns the array's data, or None if the array owns its own data.
::
void set_base(object const & base);
:Returns: Set the object that owns the array's data. Exercise caution while using this
::
Py_intptr_t const * get_shape() const;
:Returns: Shape of the array as an array of integers
::
Py_intptr_t const * get_strides() const;
:Returns: Stride of the array as an array of integers
::
int const get_nd() const;
:Returns: Number of array dimensions
::
bitflag const get_flags() const;
:Returns: Array flags
::
inline ndarray::bitflag operator|(ndarray::bitflag a, ndarray::bitflag b)
:Returns: bitflag logically OR-ed as (a | b)
::
inline ndarray::bitflag operator&(ndarray::bitflag a, ndarray::bitflag b)
:Returns: bitflag logically AND-ed as (a & b)
Example(s)
----------
::
namespace p = boost::python;
namespace np = boost::python::numpy;
p::object tu = p::make_tuple('a','b','c') ;
np::ndarray example_tuple = np::array (tu) ;
p::list l ;
np::ndarray example_list = np::array (l) ;
np::dtype dt = np::dtype::get_builtin<int>();
np::ndarray example_list1 = np::array (l,dt);
int data[] = {1,2,3,4} ;
p::tuple shape = p::make_tuple(4) ;
p::tuple stride = p::make_tuple(4) ;
p::object own ;
np::ndarray data_ex = np::from_data(data,dt,shape,stride,own);
uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};
shape = p::make_tuple(3,2) ;
stride = p::make_tuple(4,2) ;
np::dtype dt1 = np::dtype::get_builtin<uint8_t>();
np::ndarray mul_data_ex = np::from_data(mul_data,dt1, p::make_tuple(3,4),p::make_tuple(4,1),p::object());
mul_data_ex = np::from_data(mul_data,dt1, shape,stride,p::object());

View File

@@ -0,0 +1,103 @@
unary_ufunc
===========
.. contents :: Table of Contents
A ``unary_ufunc`` is a struct used as an intermediate step to broadcast a single argument so that a C++ function can be converted to a ufunc like function
``<boost/python/numpy/ufunc.hpp>`` contains the ``unary_ufunc`` structure definitions
synopsis
--------
::
namespace boost
{
namespace python
{
namespace numpy
{
template <typename TUnaryFunctor,
typename TArgument=typename TUnaryFunctor::argument_type,
typename TResult=typename TUnaryFunctor::result_type>
struct unary_ufunc
{
static object call(TUnaryFunctor & self,
object const & input,
object const & output) ;
static object make();
};
}
}
}
constructors
------------
::
struct example_unary_ufunc
{
typedef any_valid_type argument_type;
typedef any_valid_type result_type;
};
:Requirements: The ``any_valid`` type must be defined using typedef as a valid C++ type in order to use the struct methods correctly
:Note: The struct must be exposed as a Python class, and an instance of the class must be created to use the ``call`` method corresponding to the ``__call__`` attribute of the Python object
accessors
---------
::
template <typename TUnaryFunctor,
typename TArgument=typename TUnaryFunctor::argument_type,
typename TResult=typename TUnaryFunctor::result_type>
static object call(TUnaryFunctor & self,
object const & input,
object const & output);
:Requires: Typenames ``TUnaryFunctor`` and optionally ``TArgument`` for argument type and ``TResult`` for result type
:Effects: Passes a Python object to the underlying C++ functor after broadcasting its arguments
::
template <typename TUnaryFunctor,
typename TArgument=typename TUnaryFunctor::argument_type,
typename TResult=typename TUnaryFunctor::result_type>
static object make();
:Requires: Typenames ``TUnaryFunctor`` and optionally ``TArgument`` for argument type and ``TResult`` for result type
:Returns: A Python function object to call the overloaded () operator in the struct (in typical usage)
Example(s)
----------
::
namespace p = boost::python;
namespace np = boost::python::numpy;
struct UnarySquare
{
typedef double argument_type;
typedef double result_type;
double operator()(double r) const { return r * r;}
};
p::object ud = p::class_<UnarySquare, boost::shared_ptr<UnarySquare> >("UnarySquare").def("__call__", np::unary_ufunc<UnarySquare>::make());
p::object inst = ud();
std::cout << "Square of unary scalar 1.0 is " << p::extract <char const * > (p::str(inst.attr("__call__")(1.0))) << std::endl ;

149
doc/numpy/rst.css Normal file
View File

@@ -0,0 +1,149 @@
@import url("doc/src/boostbook.css");
@import url("doc/src/docutils.css");
/* Copyright David Abrahams 2006. Distributed under the Boost
Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
dl.docutils dt {
font-weight: bold }
img.boost-logo {
border: none;
vertical-align: middle
}
pre.literal-block span.concept {
font-style: italic;
}
.nav {
display: inline;
list-style-type: none;
}
.prevpage {
padding-top: -5px;
text-align: left;
float: left;
}
.nextpage {
padding-top: -20px;
text-align: right;
float: right;
}
div.small {
font-size: smaller }
h2 a {
font-size: 90%;
}
h3 a {
font-size: 80%;
}
h4 a {
font-size: 70%;
}
h5 a {
font-size: 60%;
}
dl,table
{
text-align: left;
font-size: 10pt;
line-height: 1.15;
}
/*=============================================================================
Tables
=============================================================================*/
/* The only clue docutils gives us that tables are logically tables,
and not, e.g., footnotes, is that they have border="1". Therefore
we're keying off of that. We used to manually patch docutils to
add a "table" class to all logical tables, but that proved much too
fragile.
*/
table[border="1"]
{
width: 92%;
margin-left: 4%;
margin-right: 4%;
}
table[border="1"]
{
padding: 4px;
}
/* Table Cells */
table[border="1"] tr td
{
padding: 0.5em;
text-align: left;
font-size: 9pt;
}
table[border="1"] tr th
{
padding: 0.5em 0.5em 0.5em 0.5em;
border: 1pt solid white;
font-size: 80%;
}
@media screen
{
/* Tables */
table[border="1"] tr td
{
border: 1px solid #DCDCDC;
}
table[border="1"] tr th
{
background-color: #F0F0F0;
border: 1px solid #DCDCDC;
}
pre,
.screen
{
border: 1px solid #DCDCDC;
}
td pre
td .screen
{
border: 0px
}
.sidebar pre
{
border: 0px
}
}
pre,
.screen
{
font-size: 9pt;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
/* Program listings in tables don't get borders */
td pre,
td .screen
{
margin: 0pc 0pc 0pc 0pc;
padding: 0pc 0pc 0pc 0pc;
}

View File

@@ -0,0 +1,54 @@
How to use dtypes
=================
Here is a brief tutorial to show how to create ndarrays with built-in python data types, and extract the types and values of member variables
Like before, first get the necessary headers, setup the namespaces and initialize the Python runtime and numpy module::
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
int main(int argc, char **argv)
{
Py_Initialize();
np::initialize();
Next, we create the shape and dtype. We use the get_builtin method to get the numpy dtype corresponding to the builtin C++ dtype
Here, we will create a 3x3 array passing a tuple with (3,3) for the size, and double as the data type ::
p::tuple shape = p::make_tuple(3, 3);
np::dtype dtype = np::dtype::get_builtin<double>();
np::ndarray a = np::zeros(shape, dtype);
Finally, we can print the array using the extract method in the python namespace.
Here, we first convert the variable into a string, and then extract it as a C++ character array from the python string using the <char const \* > template ::
std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
We can also print the dtypes of the data members of the ndarray by using the get_dtype method for the ndarray ::
std::cout << "Datatype is:\n" << p::extract<char const *>(p::str(a.get_dtype())) << std::endl ;
We can also create custom dtypes and build ndarrays with the custom dtypes
We use the dtype constructor to create a custom dtype. This constructor takes a list as an argument.
The list should contain one or more tuples of the format (variable name, variable type)
So first create a tuple with a variable name and its dtype, double, to create a custom dtype ::
p::tuple for_custom_dtype = p::make_tuple("ha",dtype) ;
Next, create a list, and add this tuple to the list. Then use the list to create the custom dtype ::
p::list list_for_dtype ;
list_for_dtype.append(for_custom_dtype) ;
np::dtype custom_dtype = np::dtype(list_for_dtype) ;
We are now ready to create an ndarray with dimensions specified by \*shape\* and of custom dtpye ::
np::ndarray new_array = np::zeros(shape,custom_dtype);
}

View File

@@ -0,0 +1,56 @@
How to access data using raw pointers
=====================================
One of the advantages of the ndarray wrapper is that the same data can be used in both Python and C++ and changes can be made to reflect at both ends.
The from_data method makes this possible.
Like before, first get the necessary headers, setup the namespaces and initialize the Python runtime and numpy module::
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
int main(int argc, char **argv)
{
Py_Initialize();
np::initialize();
Create an array in C++ , and pass the pointer to it to the from_data method to create an ndarray::
int arr[] = {1,2,3,4,5};
np::ndarray py_array = np::from_data(arr, np::dtype::get_builtin<int>(),
p::make_tuple(5),
p::make_tuple(sizeof(int)),
p::object());
Print the source C++ array, as well as the ndarray, to check if they are the same::
std::cout << "C++ array :" << std::endl;
for (int j=0;j<4;j++)
{
std::cout << arr[j] << ' ';
}
std::cout << std::endl
<< "Python ndarray :" << p::extract<char const *>(p::str(py_array)) << std::endl;
Now, change an element in the Python ndarray, and check if the value changed correspondingly in the source C++ array::
py_array[1] = 5 ;
std::cout << "Is the change reflected in the C++ array used to create the ndarray ? " << std::endl;
for (int j = 0; j < 5; j++)
{
std::cout << arr[j] << ' ';
}
Next, change an element of the source C++ array and see if it is reflected in the Python ndarray::
arr[2] = 8;
std::cout << std::endl
<< "Is the change reflected in the Python ndarray ?" << std::endl
<< p::extract<char const *>(p::str(py_array)) << std::endl;
}
As we can see, the changes are reflected across the ends. This happens because the from_data method passes the C++ array by reference to create the ndarray, and thus uses the same locations for storing data.

View File

@@ -0,0 +1,12 @@
Boost.Python NumPy extension Tutorial
=====================================
.. toctree::
:maxdepth: 2
simple
dtype
ndarray
ufunc
fromdata

View File

@@ -0,0 +1,99 @@
Creating ndarrays
=================
The Boost.Numpy library exposes quite a few methods to create ndarrays. ndarrays can be created in a variety of ways, include empty arrays and zero filled arrays.
ndarrays can also be created from arbitrary python sequences as well as from data and dtypes.
This tutorial will introduce you to some of the ways in which you can create ndarrays. The methods covered here include creating ndarrays from arbitrary Python sequences, as well as from C++ containers, using both unit and non-unit strides
First, as before, initialise the necessary namepaces and runtimes ::
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
int main(int argc, char **argv)
{
Py_Initialize();
np::initialize();
Let's now create an ndarray from a simple tuple. We first create a tuple object, and then pass it to the array method, to generate the necessary tuple ::
p::object tu = p::make_tuple('a','b','c');
np::ndarray example_tuple = np::array(tu);
Let's now try the same with a list. We create an empty list, add an element using the append method, and as before, call the array method ::
p::list l;
l.append('a');
np::ndarray example_list = np::array (l);
Optionally, we can also specify a dtype for the array ::
np::dtype dt = np::dtype::get_builtin<int>();
np::ndarray example_list1 = np::array (l,dt);
We can also create an array by supplying data arrays and a few other parameters.
First,create an integer array ::
int data[] = {1,2,3,4,5};
Create a shape, and strides, needed by the function ::
p::tuple shape = p::make_tuple(5);
p::tuple stride = p::make_tuple(sizeof(int));
Here, shape is (4,) , and the stride is `sizeof(int)``.
A stride is the number of bytes that must be traveled to get to the next desired element while constructing the ndarray.
The function also needs an owner, to keep track of the data array passed. Passing none is dangerous ::
p::object own;
The from_data function takes the data array, datatype,shape,stride and owner as arguments and returns an ndarray ::
np::ndarray data_ex1 = np::from_data(data,dt, shape,stride,own);
Now let's print the ndarray we created ::
std::cout << "Single dimensional array ::" << std::endl
<< p::extract<char const *>(p::str(data_ex)) << std::endl;
Let's make it a little more interesting. Lets make an 3x2 ndarray from a multi-dimensional array using non-unit strides
First lets create a 3x4 array of 8-bit integers ::
uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};
Now let's create an array of 3x2 elements, picking the first and third elements from each row . For that, the shape will be 3x2.
The strides will be 4x2 i.e. 4 bytes to go to the next desired row, and 2 bytes to go to the next desired column ::
shape = p::make_tuple(3,2);
stride = p::make_tuple(sizeof(uint8_t)*2,sizeof(uint8_t));
Get the numpy dtype for the built-in 8-bit integer data type ::
np::dtype dt1 = np::dtype::get_builtin<uint8_t>();
Now lets first create and print out the ndarray as is.
Notice how we can pass the shape and strides in the function directly, as well as the owner. The last part can be done because we don't have any use to
manipulate the "owner" object ::
np::ndarray mul_data_ex = np::from_data(mul_data, dt1,
p::make_tuple(3,4),
p::make_tuple(4,1),
p::object());
std::cout << "Original multi dimensional array :: " << std::endl
<< p::extract<char const *>(p::str(mul_data_ex)) << std::endl;
Now create the new ndarray using the shape and strides and print out the array we created using non-unit strides ::
mul_data_ex = np::from_data(mul_data, dt1, shape, stride, p::object());
std::cout << "Selective multidimensional array :: "<<std::endl
<< p::extract<char const *>(p::str(mul_data_ex)) << std::endl ;
}
.. note:: The from_data method will throw ``error_already_set`` if the number of elements dictated by the shape and the corresponding strides don't match.

View File

@@ -0,0 +1,41 @@
A simple tutorial on Arrays
===========================
Let's start with a simple tutorial to create and modify arrays.
Get the necessary headers for numpy components and set up necessary namespaces::
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
Initialise the Python runtime, and the numpy module. Failure to call these results in segmentation errors::
int main(int argc, char **argv)
{
Py_Initialize();
np::initialize();
Zero filled n-dimensional arrays can be created using the shape and data-type of the array as a parameter. Here, the shape is 3x3 and the datatype is the built-in float type::
p::tuple shape = p::make_tuple(3, 3);
np::dtype dtype = np::dtype::get_builtin<float>();
np::ndarray a = np::zeros(shape, dtype);
You can also create an empty array like this ::
np::ndarray b = np::empty(shape,dtype);
Print the original and reshaped array. The array a which is a list is first converted to a string, and each value in the list is extracted using extract< >::
std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
// Reshape the array into a 1D array
a = a.reshape(p::make_tuple(9));
// Print it again.
std::cout << "Reshaped array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
}

View File

@@ -0,0 +1,120 @@
Ufuncs
======
Ufuncs or universal functions operate on ndarrays element by element, and support array broadcasting, type casting, and other features.
Lets try and see how we can use the binary and unary ufunc methods
After the neccessary includes ::
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
Now we create the structs necessary to implement the ufuncs. The typedefs *must* be made as the ufunc generators take these typedefs as inputs and return an error otherwise ::
struct UnarySquare
{
typedef double argument_type;
typedef double result_type;
double operator()(double r) const { return r * r;}
};
struct BinarySquare
{
typedef double first_argument_type;
typedef double second_argument_type;
typedef double result_type;
double operator()(double a,double b) const { return (a*a + b*b) ; }
};
Initialise the Python runtime and the numpy module ::
int main(int argc, char **argv)
{
Py_Initialize();
np::initialize();
Now expose the struct UnarySquare to Python as a class, and let ud be the class object. ::
p::object ud = p::class_<UnarySquare, boost::shared_ptr<UnarySquare> >("UnarySquare");
ud.def("__call__", np::unary_ufunc<UnarySquare>::make());
Let inst be an instance of the class ud ::
p::object inst = ud();
Use the "__call__" method to call the overloaded () operator and print the value ::
std::cout << "Square of unary scalar 1.0 is " << p::extract<char const *>(p::str(inst.attr("__call__")(1.0))) << std::endl;
Create an array in C++ ::
int arr[] = {1,2,3,4} ;
..and use it to create the ndarray in Python ::
np::ndarray demo_array = np::from_data(arr, np::dtype::get_builtin<int>(),
p::make_tuple(4),
p::make_tuple(4),
p::object());
Print out the demo array ::
std::cout << "Demo array is " << p::extract<char const *>(p::str(demo_array)) << std::endl;
Call the "__call__" method to perform the operation and assign the value to result_array ::
p::object result_array = inst.attr("__call__")(demo_array);
Print the resultant array ::
std::cout << "Square of demo array is " << p::extract<char const *>(p::str(result_array)) << std::endl;
Lets try the same with a list ::
p::list li;
li.append(3);
li.append(7);
Print out the demo list ::
std::cout << "Demo list is " << p::extract<char const *>(p::str(li)) << std::endl;
Call the ufunc for the list ::
result_array = inst.attr("__call__")(li);
And print the list out ::
std::cout << "Square of demo list is " << p::extract<char const *>(p::str(result_array)) << std::endl;
Now lets try Binary ufuncs. Again, expose the struct BinarySquare to Python as a class, and let ud be the class object ::
ud = p::class_<BinarySquare, boost::shared_ptr<BinarySquare> >("BinarySquare");
ud.def("__call__", np::binary_ufunc<BinarySquare>::make());
And initialise ud ::
inst = ud();
Print the two input lists ::
std::cout << "The two input list for binary ufunc are " << std::endl
<< p::extract<char const *>(p::str(demo_array)) << std::endl
<< p::extract<char const *>(p::str(demo_array)) << std::endl;
Call the binary ufunc taking demo_array as both inputs ::
result_array = inst.attr("__call__")(demo_array,demo_array);
And print the output ::
std::cout << "Square of list with binary ufunc is " << p::extract<char const *>(p::str(result_array)) << std::endl;
}

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_
@@ -50,6 +51,7 @@ The development of these features was funded in part by grants to `Boost Consult
* [link glossary Glossary]
* [link support Support Resources]
* [link faq Frequently Asked Questions (FAQs)]
* [@numpy/index.html NumPy Extension Documentation]
[endsect]
@@ -57,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

@@ -38,7 +38,7 @@ The `indexing_suite` class is the base class for the management of C++ container
[[__iter__(self)]
[This method is called when an iterator is required for a container. This method should return a new iterator object that can iterate over all the objects in the container. For mappings, it should iterate over the keys of the container, and should also be made available as the method iterkeys().
Iterator objects also need to implement this method; they are required to return themselves. For more information on iterator objects, see [@http://www.python.org/doc/current/lib/typeiter.html Iterator Types] in the [@http://www.python.org/doc/current/lib/lib.html Python Library Reference].]]
Iterator objects also need to implement this method; they are required to return themselves. For more information on iterator objects, see [@https://docs.python.org/3/library/stdtypes.html#iterator-types Iterator Types] in the [@https://docs.python.org/3/library/index.html Python Library Reference].]]
[[__contains__(self, item)]
[Called to implement membership test operators. Should return true if item is in self, false otherwise. For mapping objects, this should consider the keys of the mapping rather than the values or the key-item pairs.]]

View File

@@ -1,153 +0,0 @@
[section boost/python/numeric.hpp]
[section Introduction]
Exposes a [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] for the Python [@http://www.python.org/dev/doc/devel/lib/typesmapping.html array] type.
[endsect]
[section Class `array`]
Provides access to the array types of [@http://www.pfdubois.com/numpy/ Numerical Python]\ 's [@http://www.pfdubois.com/numpy/#Numeric Numeric] and [@http://stsdas.stsci.edu/numarray/index.html NumArray] modules. With the exception of the functions documented below, the semantics of the constructors and member functions defined below can be fully understood by reading the [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] concept definition. Since array is publicly derived from object, the public object interface applies to array instances as well.
The default behavior is to use numarray.NDArray as the associated Python type if the numarray module is installed in the default location. Otherwise it falls back to use Numeric.ArrayType. If neither extension module is installed, overloads of wrapped C++ functions with numeric::array parameters will never be matched, and other attempted uses of numeric::array will raise an appropriate Python exception. The associated Python type can be set manually using the set_module_and_type(...) static function.
``
namespace boost { namespace python { namespace numeric
{
class array : public object
{
public:
object astype();
template <class Type>
object astype(Type const& type_);
template <class Type>
array new_(Type const& type_) const;
template <class Sequence>
void resize(Sequence const& x);
void resize(long x1);
void resize(long x1, long x2);
...
void resize(long x1, long x2,...long xn);
template <class Sequence>
void setshape(Sequence const& x);
void setshape(long x1);
void setshape(long x1, long x2);
...
void setshape(long x1, long x2,...long xn);
template <class Indices, class Values>
void put(Indices const& indices, Values const& values);
template <class Sequence>
object take(Sequence const& sequence, long axis = 0);
template <class File>
void tofile(File const& f) const;
object factory();
template <class Sequence>
object factory(Sequence const&);
template <class Sequence, class Typecode>
object factory(Sequence const&, Typecode const&, bool copy = true, bool savespace = false);
template <class Sequence, class Typecode, class Type>
object factory(Sequence const&, Typecode const&, bool copy, bool savespace, Type const&);
template <class Sequence, class Typecode, class Type, class Shape>
object factory(Sequence const&, Typecode const&, bool copy, bool savespace, Type const&, Shape const&);
template <class T1>
explicit array(T1 const& x1);
template <class T1, class T2>
explicit array(T1 const& x1, T2 const& x2);
...
template <class T1, class T2,...class Tn>
explicit array(T1 const& x1, T2 const& x2,...Tn const& xn);
static void set_module_and_type();
static void set_module_and_type(char const* package_path = 0, char const* type_name = 0);
static void get_module_name();
object argmax(long axis=-1);
object argmin(long axis=-1);
object argsort(long axis=-1);
void byteswap();
object copy() const;
object diagonal(long offset = 0, long axis1 = 0, long axis2 = 1) const;
void info() const;
bool is_c_array() const;
bool isbyteswapped() const;
void sort();
object trace(long offset = 0, long axis1 = 0, long axis2 = 1) const;
object type() const;
char typecode() const;
object getflat() const;
long getrank() const;
object getshape() const;
bool isaligned() const;
bool iscontiguous() const;
long itemsize() const;
long nelements() const;
object nonzero() const;
void ravel();
object repeat(object const& repeats, long axis=0);
void setflat(object const& flat);
void swapaxes(long axis1, long axis2);
str tostring() const;
void transpose(object const& axes = object());
object view() const;
};
}}}
``
[endsect]
[section Class `array` observer functions]
``
object factory();
template <class Sequence>
object factory(Sequence const&);
template <class Sequence, class Typecode>
object factory(Sequence const&, Typecode const&, bool copy = true, bool savespace = false);
template <class Sequence, class Typecode, class Type>
object factory(Sequence const&, Typecode const&, bool copy, bool savespace, Type const&);
template <class Sequence, class Typecode, class Type, class Shape>
object factory(Sequence const&, Typecode const&, bool copy, bool savespace, Type const&, Shape const&);
``
These functions map to the underlying array type's array() function family. They are not called "array" because of the C++ limitation that you can't define a member function with the same name as its enclosing class.
``
template <class Type>
array new_(Type const&) const;
``
This function maps to the underlying array type's new() function. It is not called "new" because that is a keyword in C++.
[endsect]
[section Class `array` static functions]
``
static void set_module_and_type(char const* package_path, char const* type_name);
static void set_module_and_type();
``
[variablelist
[[Requires][package_path and type_name, if supplied, is an [link ntbs].]]
[[Effects][The first form sets the package path of the module that supplies the type named by type_name to package_path. The second form restores the default search behavior. The associated Python type will be searched for only the first time it is needed, and thereafter the first time it is needed after an invocation of set_module_and_type.]]
]
``static std::string get_module_name()``
[variablelist
[[Effects][Returns the name of the module containing the class that will be held by new `numeric::array` instances.]]
]
[endsect]
[section Example]
``
#include <boost/python/numeric.hpp>
#include <boost/python/tuple.hpp>
// sets the first element in a 2d numeric array
void set_first_element(numeric::array& y, double value)
{
y[make_tuple(0,0)] = value;
}
``
[endsect]
[endsect]

View File

@@ -5,7 +5,6 @@
[include dict.qbk]
[include list.qbk]
[include long.qbk]
[include numeric.qbk]
[include object.qbk]
[include str.qbk]
[include slice.qbk]

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`]]

View File

@@ -4,7 +4,7 @@ Pickle is a Python module for object serialization, also known as persistence, m
It is often necessary to save and restore the contents of an object to a file. One approach to this problem is to write a pair of functions that read and write data from a file in a special format. A powerful alternative approach is to use Python's pickle module. Exploiting Python's ability for introspection, the pickle module recursively converts nearly arbitrary Python objects into a stream of bytes that can be written to a file.
The Boost Python Library supports the pickle module through the interface as described in detail in the [@http://www.python.org/doc/current/lib/module-pickle.html Python Library Reference for pickle]. This interface involves the special methods `__getinitargs__`, `__getstate__` and `__setstate__` as described in the following. Note that `Boost.Python` is also fully compatible with Python's cPickle module.
The Boost Python Library supports the pickle module through the interface as described in detail in the [@https://docs.python.org/2/library/pickle.html Python Library Reference for pickle]. This interface involves the special methods `__getinitargs__`, `__getstate__` and `__setstate__` as described in the following. Note that `Boost.Python` is also fully compatible with Python's cPickle module.
[endsect]
[section The Pickle Interface]
At the user level, the Boost.Python pickle interface involves three special methods:

View File

@@ -105,14 +105,6 @@ list odd_elements(list l)
return l[slice(_,_,2)];
}
// Perform a multidimensional extended slice of a Numeric.array
numeric::array even_columns(numeric::array arr)
{
// select every other column, starting with the second, of a 2-D array.
// Equivalent to "return arr[:, 1::2]" in Python.
return arr[make_tuple( slice(), slice(1,_,2))];
}
// Perform a summation over a slice of a std::vector.
double partial_sum(std::vector<double> const& Foo, const slice index)
{

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

@@ -92,7 +92,7 @@ who had to use a different tool.
We will skip over the details. Our objective will be to simply create
the hello world module and run it in Python. For a complete reference to
building Boost.Python, check out: [@../../../building.html
building Boost.Python, check out: [@../building.html
building.html]. After this brief ['bjam] tutorial, we should have built
the DLLs and run a python program using the extension.
@@ -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]
@@ -1417,6 +1417,8 @@ eval evaluates the given expression and returns the resulting value.
exec executes the given code (typically a set of statements) returning the result,
and exec_file executes the code contained in the given file.
There are also overloads taking `char const*` instead of str as the first argument.
The [^globals] and [^locals] parameters are Python dictionaries
containing the globals and locals of the context in which to run the code.
For most intents and purposes you can use the namespace dictionary of the
@@ -1869,36 +1871,6 @@ This technique has several advantages:
* Minimize the need to recompile
* Rapid prototyping (you can move the code to C++ if required without changing the interface)
You can even add a little syntactic sugar with the use of metaclasses. Let's
create a special metaclass that "injects" methods in other classes.
# The one Boost.Python uses for all wrapped classes.
# You can use here any class exported by Boost instead of "point"
BoostPythonMetaclass = point.__class__
class injector(object):
class __metaclass__(BoostPythonMetaclass):
def __init__(self, name, bases, dict):
for b in bases:
if type(b) not in (self, type):
for k,v in dict.items():
setattr(b,k,v)
return type.__init__(self, name, bases, dict)
# inject some methods in the point foo
class more_point(injector, point):
def __repr__(self):
return 'Point(x=%s, y=%s)' % (self.x, self.y)
def foo(self):
print 'foo!'
Now let's see how it got:
>>> print point()
Point(x=10, y=10)
>>> point().foo()
foo!
Another useful idea is to replace constructors with factory functions:
_point = point

View File

@@ -1,43 +1,35 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Copyright Stefan Seefeld 2016.
# 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)
# Specify the path to the Boost project. If you move this project,
# adjust this path to refer to the Boost root directory.
use-project boost
: ../../.. ;
import python ;
# Set up the project-wide requirements that everything uses the
# boost_python library from the project whose global ID is
# /boost/python.
project
: requirements <library>/boost/python//boost_python
<implicit-dependency>/boost//headers
: usage-requirements <implicit-dependency>/boost//headers
;
# Declare the three extension modules. You can specify multiple
# source files after the colon separated by spaces.
python-extension getting_started1 : getting_started1.cpp ;
python-extension getting_started2 : getting_started2.cpp ;
python-extension std_pair_ext : std_pair.cpp ;
# A little "rule" (function) to clean up the syntax of declaring tests
# of these extension modules.
local rule run-test ( test-name : sources + )
if ! [ python.configured ]
{
import testing ;
testing.make-test run-pyd : $(sources) : : $(test-name) ;
ECHO "warning: no Python configured in user-config.jam" ;
ECHO "warning: will use default configuration" ;
using python ;
}
# Declare test targets
run-test test1 : getting_started1 test_getting_started1.py ;
run-test test2 : getting_started2 test_getting_started2.py ;
run-test test3 : std_pair_ext test_std_pair.py ;
# Adjust the following if Boost.Python isn't installed in a default location
lib boost_python ;
# A target that runs all the tests
alias test : test1 test2 test3 ;
project
: requirements
# <include>/path/to/boost/python
<library>boost_python
;
# Only run tests when explicitly requested
explicit test test1 test2 test3 ;
rule run-test ( test-name : sources + )
{
import testing ;
testing.make-test run-pyd : $(sources) : : $(test-name) ;
}
build-project quickstart ;
build-project tutorial ;
if [ python.numpy ]
{
build-project numpy ;
}

View File

@@ -1,16 +0,0 @@
.. Copyright David Abrahams 2006. Distributed under the Boost
.. Software License, Version 1.0. (See accompanying
.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
To get started with the Boost Python Library, use the examples
getting_started1.cpp and getting_started2.cpp. Invoking
bjam --toolset=your-toolset test
in this directory will build and run the examples. See
http://www.boost.org/more/getting_started.html for details about the
--toolset= option.
If you move this example from its place in the Boost development tree
you'll need to edit the two lines indicated in Jamroot and
boost-build.jam.

11
example/README.md Normal file
View File

@@ -0,0 +1,11 @@
![logo](https://raw.githubusercontent.com/boostorg/python/develop/doc/images/bpl.png)
# Examples
This directory contains various examples using Boost.Python.
You may compile these using the `bjam` command either in this directory
or in any of the subdirectories.
You may need to adjust the paths in the Jamroot file if Boost.Python
is not installed in a default location.
See http://boostorg.github.io/python/doc/html/building/no_install_quickstart.html
for details.

View File

@@ -1,7 +0,0 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Edit this path to point at the tools/build/src subdirectory of your
# Boost installation. Absolute paths work, too.
boost-build ../../../tools/build/src ;

View File

@@ -1,25 +0,0 @@
// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <string>
namespace { // Avoid cluttering the global namespace.
// A couple of simple C++ functions that we want to expose to Python.
std::string greet() { return "hello, world"; }
int square(int number) { return number * number; }
}
namespace python = boost::python;
// Python requires an exported function called init<module-name> in every
// extension module. This is where we build the module contents.
BOOST_PYTHON_MODULE(getting_started1)
{
// Add regular functions to the module.
python::def("greet", greet);
python::def("square", square);
}

View File

@@ -1,41 +0,0 @@
// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <iostream>
#include <string>
namespace { // Avoid cluttering the global namespace.
// A friendly class.
class hello
{
public:
hello(const std::string& country) { this->country = country; }
std::string greet() const { return "Hello from " + country; }
private:
std::string country;
};
// A function taking a hello object as an argument.
std::string invite(const hello& w) {
return w.greet() + "! Please come soon!";
}
}
BOOST_PYTHON_MODULE(getting_started2)
{
using namespace boost::python;
class_<hello>("hello", init<std::string>())
// Add a regular member function.
.def("greet", &hello::greet)
// Add invite() as a member of hello!
.def("invite", invite)
;
// Also add invite() as a regular function to the module.
def("invite", invite);
}

29
example/numpy/Jamfile Normal file
View File

@@ -0,0 +1,29 @@
# Copyright Stefan Seefeld 2016.
# 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 python ;
# Adjust the following if Boost.Python isn't installed in a default location
lib boost_numpy
:
: <search>/usr/local/Boost/lib
<include>/usr/local/Boost/include
;
project numpy
: requirements
<include>/usr/local/Boost/include
<library>boost_numpy
<location>.
;
exe simple : simple.cpp boost_numpy /python//python ;
exe dtype : dtype.cpp boost_numpy /python//python ;
exe ndarray : ndarray.cpp /python//python ;
exe fromdata : fromdata.cpp /python//python ;
exe ufunc : ufunc.cpp /python//python ;
exe wrap : wrap.cpp /python//python ;
python-extension gaussian : gaussian.cpp ;

View File

@@ -0,0 +1,37 @@
# Copyright Jim Bosch 2010-2012.
# 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 numpy
import gaussian
mu = numpy.zeros(2, dtype=float)
sigma = numpy.identity(2, dtype=float)
sigma[0, 1] = 0.15
sigma[1, 0] = 0.15
g = gaussian.bivariate_gaussian(mu, sigma)
r = numpy.linspace(-40, 40, 1001)
x, y = numpy.meshgrid(r, r)
z = g(x, y)
s = z.sum() * (r[1] - r[0])**2
print "sum (should be ~ 1):", s
xc = (z * x).sum() / z.sum()
print "x centroid (should be ~ %f): %f" % (mu[0], xc)
yc = (z * y).sum() / z.sum()
print "y centroid (should be ~ %f): %f" % (mu[1], yc)
xx = (z * (x - xc)**2).sum() / z.sum()
print "xx moment (should be ~ %f): %f" % (sigma[0,0], xx)
yy = (z * (y - yc)**2).sum() / z.sum()
print "yy moment (should be ~ %f): %f" % (sigma[1,1], yy)
xy = 0.5 * (z * (x - xc) * (y - yc)).sum() / z.sum()
print "xy moment (should be ~ %f): %f" % (sigma[0,1], xy)

49
example/numpy/dtype.cpp Normal file
View File

@@ -0,0 +1,49 @@
// Copyright Ankit Daftery 2011-2012.
// 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)
/**
* @brief An example to show how to create ndarrays with built-in python data types, and extract
* the types and values of member variables
*
* @todo Add an example to show type conversion.
* Add an example to show use of user-defined types
*
*/
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
int main(int argc, char **argv)
{
// Initialize the Python runtime.
Py_Initialize();
// Initialize NumPy
np::initialize();
// Create a 3x3 shape...
p::tuple shape = p::make_tuple(3, 3);
// ...as well as a type for C++ double
np::dtype dtype = np::dtype::get_builtin<double>();
// Construct an array with the above shape and type
np::ndarray a = np::zeros(shape, dtype);
// Print the array
std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
// Print the datatype of the elements
std::cout << "Datatype is:\n" << p::extract<char const *>(p::str(a.get_dtype())) << std::endl ;
// Using user defined dtypes to create dtype and an array of the custom dtype
// First create a tuple with a variable name and its dtype, double, to create a custom dtype
p::tuple for_custom_dtype = p::make_tuple("ha",dtype) ;
// The list needs to be created, because the constructor to create the custom dtype
// takes a list of (variable,variable_type) as an argument
p::list list_for_dtype ;
list_for_dtype.append(for_custom_dtype) ;
// Create the custom dtype
np::dtype custom_dtype = np::dtype(list_for_dtype) ;
// Create an ndarray with the custom dtype
np::ndarray new_array = np::zeros(shape,custom_dtype);
}

View File

@@ -0,0 +1,48 @@
// Copyright Ankit Daftery 2011-2012.
// 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)
/**
* @brief An example to show how to access data using raw pointers. This shows that you can use and
* manipulate data in either Python or C++ and have the changes reflected in both.
*/
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
int main(int argc, char **argv)
{
// Initialize the Python runtime.
Py_Initialize();
// Initialize NumPy
np::initialize();
// Create an array in C++
int arr[] = {1,2,3,4} ;
// Create the ndarray in Python
np::ndarray py_array = np::from_data(arr, np::dtype::get_builtin<int>() , p::make_tuple(4), p::make_tuple(4), p::object());
// Print the ndarray that we just created, and the source C++ array
std::cout << "C++ array :" << std::endl ;
for (int j=0;j<4;j++)
{
std::cout << arr[j] << ' ' ;
}
std::cout << std::endl << "Python ndarray :" << p::extract<char const *>(p::str(py_array)) << std::endl;
// Change an element in the python ndarray
py_array[1] = 5 ;
// And see if the C++ container is changed or not
std::cout << "Is the change reflected in the C++ array used to create the ndarray ? " << std::endl ;
for (int j = 0;j<4 ; j++)
{
std::cout << arr[j] << ' ' ;
}
// Conversely, change it in C++
arr[2] = 8 ;
// And see if the changes are reflected in the Python ndarray
std::cout << std::endl << "Is the change reflected in the Python ndarray ?" << std::endl << p::extract<char const *>(p::str(py_array)) << std::endl;
}

315
example/numpy/gaussian.cpp Normal file
View File

@@ -0,0 +1,315 @@
// Copyright Jim Bosch 2010-2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/numpy.hpp>
#include <cmath>
#include <memory>
#ifndef M_PI
#include <boost/math/constants/constants.hpp>
const double M_PI = boost::math::constants::pi<double>();
#endif
namespace bp = boost::python;
namespace bn = boost::python::numpy;
/**
* A 2x2 matrix class, purely for demonstration purposes.
*
* Instead of wrapping this class with Boost.Python, we'll convert it to/from numpy.ndarray.
*/
class matrix2 {
public:
double & operator()(int i, int j) {
return _data[i*2 + j];
}
double const & operator()(int i, int j) const {
return _data[i*2 + j];
}
double const * data() const { return _data; }
private:
double _data[4];
};
/**
* A 2-element vector class, purely for demonstration purposes.
*
* Instead of wrapping this class with Boost.Python, we'll convert it to/from numpy.ndarray.
*/
class vector2 {
public:
double & operator[](int i) {
return _data[i];
}
double const & operator[](int i) const {
return _data[i];
}
double const * data() const { return _data; }
vector2 operator+(vector2 const & other) const {
vector2 r;
r[0] = _data[0] + other[0];
r[1] = _data[1] + other[1];
return r;
}
vector2 operator-(vector2 const & other) const {
vector2 r;
r[0] = _data[0] - other[0];
r[1] = _data[1] - other[1];
return r;
}
private:
double _data[2];
};
/**
* Matrix-vector multiplication.
*/
vector2 operator*(matrix2 const & m, vector2 const & v) {
vector2 r;
r[0] = m(0, 0) * v[0] + m(0, 1) * v[1];
r[1] = m(1, 0) * v[0] + m(1, 1) * v[1];
return r;
}
/**
* Vector inner product.
*/
double dot(vector2 const & v1, vector2 const & v2) {
return v1[0] * v2[0] + v1[1] * v2[1];
}
/**
* This class represents a simple 2-d Gaussian (Normal) distribution, defined by a
* mean vector 'mu' and a covariance matrix 'sigma'.
*/
class bivariate_gaussian {
public:
vector2 const & get_mu() const { return _mu; }
matrix2 const & get_sigma() const { return _sigma; }
/**
* Evaluate the density of the distribution at a point defined by a two-element vector.
*/
double operator()(vector2 const & p) const {
vector2 u = _cholesky * (p - _mu);
return 0.5 * _cholesky(0, 0) * _cholesky(1, 1) * std::exp(-0.5 * dot(u, u)) / M_PI;
}
/**
* Evaluate the density of the distribution at an (x, y) point.
*/
double operator()(double x, double y) const {
vector2 p;
p[0] = x;
p[1] = y;
return operator()(p);
}
/**
* Construct from a mean vector and covariance matrix.
*/
bivariate_gaussian(vector2 const & mu, matrix2 const & sigma)
: _mu(mu), _sigma(sigma), _cholesky(compute_inverse_cholesky(sigma))
{}
private:
/**
* This evaluates the inverse of the Cholesky factorization of a 2x2 matrix;
* it's just a shortcut in evaluating the density.
*/
static matrix2 compute_inverse_cholesky(matrix2 const & m) {
matrix2 l;
// First do cholesky factorization: l l^t = m
l(0, 0) = std::sqrt(m(0, 0));
l(0, 1) = m(0, 1) / l(0, 0);
l(1, 1) = std::sqrt(m(1, 1) - l(0,1) * l(0,1));
// Now do forward-substitution (in-place) to invert:
l(0, 0) = 1.0 / l(0, 0);
l(1, 0) = l(0, 1) = -l(0, 1) / l(1, 1);
l(1, 1) = 1.0 / l(1, 1);
return l;
}
vector2 _mu;
matrix2 _sigma;
matrix2 _cholesky;
};
/*
* We have a two options for wrapping get_mu and get_sigma into NumPy-returning Python methods:
* - we could deep-copy the data, making totally new NumPy arrays;
* - we could make NumPy arrays that point into the existing memory.
* The latter is often preferable, especially if the arrays are large, but it's dangerous unless
* the reference counting is correct: the returned NumPy array needs to hold a reference that
* keeps the memory it points to from being deallocated as long as it is alive. This is what the
* "owner" argument to from_data does - the NumPy array holds a reference to the owner, keeping it
* from being destroyed.
*
* Note that this mechanism isn't completely safe for data members that can have their internal
* storage reallocated. A std::vector, for instance, can be invalidated when it is resized,
* so holding a Python reference to a C++ class that holds a std::vector may not be a guarantee
* that the memory in the std::vector will remain valid.
*/
/**
* These two functions are custom wrappers for get_mu and get_sigma, providing the shallow-copy
* conversion with reference counting described above.
*
* It's also worth noting that these return NumPy arrays that cannot be modified in Python;
* the const overloads of vector::data() and matrix::data() return const references,
* and passing a const pointer to from_data causes NumPy's 'writeable' flag to be set to false.
*/
static bn::ndarray py_get_mu(bp::object const & self) {
vector2 const & mu = bp::extract<bivariate_gaussian const &>(self)().get_mu();
return bn::from_data(
mu.data(),
bn::dtype::get_builtin<double>(),
bp::make_tuple(2),
bp::make_tuple(sizeof(double)),
self
);
}
static bn::ndarray py_get_sigma(bp::object const & self) {
matrix2 const & sigma = bp::extract<bivariate_gaussian const &>(self)().get_sigma();
return bn::from_data(
sigma.data(),
bn::dtype::get_builtin<double>(),
bp::make_tuple(2, 2),
bp::make_tuple(2 * sizeof(double), sizeof(double)),
self
);
}
/**
* To allow the constructor to work, we need to define some from-Python converters from NumPy arrays
* to the matrix/vector types. The rvalue-from-python functionality is not well-documented in Boost.Python
* itself; you can learn more from boost/python/converter/rvalue_from_python_data.hpp.
*/
/**
* We start with two functions that just copy a NumPy array into matrix/vector objects. These will be used
* in the templated converted below. The first just uses the operator[] overloads provided by
* bp::object.
*/
static void copy_ndarray_to_mv2(bn::ndarray const & array, vector2 & vec) {
vec[0] = bp::extract<double>(array[0]);
vec[1] = bp::extract<double>(array[1]);
}
/**
* Here, we'll take the alternate approach of using the strides to access the array's memory directly.
* This can be much faster for large arrays.
*/
static void copy_ndarray_to_mv2(bn::ndarray const & array, matrix2 & mat) {
// Unfortunately, get_strides() can't be inlined, so it's best to call it once up-front.
Py_intptr_t const * strides = array.get_strides();
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
mat(i, j) = *reinterpret_cast<double const *>(array.get_data() + i * strides[0] + j * strides[1]);
}
}
}
/**
* Here's the actual converter. Because we've separated the differences into the above functions,
* we can write a single template class that works for both matrix2 and vector2.
*/
template <typename T, int N>
struct mv2_from_python {
/**
* Register the converter.
*/
mv2_from_python() {
bp::converter::registry::push_back(
&convertible,
&construct,
bp::type_id< T >()
);
}
/**
* Test to see if we can convert this to the desired type; if not return zero.
* If we can convert, returned pointer can be used by construct().
*/
static void * convertible(PyObject * p) {
try {
bp::object obj(bp::handle<>(bp::borrowed(p)));
std::auto_ptr<bn::ndarray> array(
new bn::ndarray(
bn::from_object(obj, bn::dtype::get_builtin<double>(), N, N, bn::ndarray::V_CONTIGUOUS)
)
);
if (array->shape(0) != 2) return 0;
if (N == 2 && array->shape(1) != 2) return 0;
return array.release();
} catch (bp::error_already_set & err) {
bp::handle_exception();
return 0;
}
}
/**
* Finish the conversion by initializing the C++ object into memory prepared by Boost.Python.
*/
static void construct(PyObject * obj, bp::converter::rvalue_from_python_stage1_data * data) {
// Extract the array we passed out of the convertible() member function.
std::auto_ptr<bn::ndarray> array(reinterpret_cast<bn::ndarray*>(data->convertible));
// Find the memory block Boost.Python has prepared for the result.
typedef bp::converter::rvalue_from_python_storage<T> storage_t;
storage_t * storage = reinterpret_cast<storage_t*>(data);
// Use placement new to initialize the result.
T * m_or_v = new (storage->storage.bytes) T();
// Fill the result with the values from the NumPy array.
copy_ndarray_to_mv2(*array, *m_or_v);
// Finish up.
data->convertible = storage->storage.bytes;
}
};
BOOST_PYTHON_MODULE(gaussian) {
bn::initialize();
// Register the from-python converters
mv2_from_python< vector2, 1 >();
mv2_from_python< matrix2, 2 >();
typedef double (bivariate_gaussian::*call_vector)(vector2 const &) const;
bp::class_<bivariate_gaussian>("bivariate_gaussian", bp::init<bivariate_gaussian const &>())
// Declare the constructor (wouldn't work without the from-python converters).
.def(bp::init< vector2 const &, matrix2 const & >())
// Use our custom reference-counting getters
.add_property("mu", &py_get_mu)
.add_property("sigma", &py_get_sigma)
// First overload accepts a two-element array argument
.def("__call__", (call_vector)&bivariate_gaussian::operator())
// This overload works like a binary NumPy universal function: you can pass
// in scalars or arrays, and the C++ function will automatically be called
// on each element of an array argument.
.def("__call__", bn::binary_ufunc<bivariate_gaussian,double,double,double>::make())
;
}

71
example/numpy/ndarray.cpp Normal file
View File

@@ -0,0 +1,71 @@
// Copyright Ankit Daftery 2011-2012.
// 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)
/**
* @brief An example to show how to create ndarrays using arbitrary Python sequences.
*
* The Python sequence could be any object whose __array__ method returns an array, or any
* (nested) sequence. This example also shows how to create arrays using both unit and
* non-unit strides.
*/
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
#if _MSC_VER
using boost::uint8_t;
#endif
int main(int argc, char **argv)
{
// Initialize the Python runtime.
Py_Initialize();
// Initialize NumPy
np::initialize();
// Create an ndarray from a simple tuple
p::object tu = p::make_tuple('a','b','c') ;
np::ndarray example_tuple = np::array (tu) ;
// and from a list
p::list l ;
np::ndarray example_list = np::array (l) ;
// Optionally, you can also specify a dtype
np::dtype dt = np::dtype::get_builtin<int>();
np::ndarray example_list1 = np::array (l,dt);
// You can also create an array by supplying data.First,create an integer array
int data[] = {1,2,3,4} ;
// Create a shape, and strides, needed by the function
p::tuple shape = p::make_tuple(4) ;
p::tuple stride = p::make_tuple(4) ;
// The function also needs an owner, to keep track of the data array passed. Passing none is dangerous
p::object own ;
// The from_data function takes the data array, datatype,shape,stride and owner as arguments
// and returns an ndarray
np::ndarray data_ex = np::from_data(data,dt,shape,stride,own);
// Print the ndarray we created
std::cout << "Single dimensional array ::" << std::endl << p::extract < char const * > (p::str(data_ex)) << std::endl ;
// Now lets make an 3x2 ndarray from a multi-dimensional array using non-unit strides
// First lets create a 3x4 array of 8-bit integers
uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};
// Now let's create an array of 3x2 elements, picking the first and third elements from each row
// For that, the shape will be 3x2
shape = p::make_tuple(3,2) ;
// The strides will be 4x2 i.e. 4 bytes to go to the next desired row, and 2 bytes to go to the next desired column
stride = p::make_tuple(4,2) ;
// Get the numpy dtype for the built-in 8-bit integer data type
np::dtype dt1 = np::dtype::get_builtin<uint8_t>();
// First lets create and print out the ndarray as is
np::ndarray mul_data_ex = np::from_data(mul_data,dt1, p::make_tuple(3,4),p::make_tuple(4,1),p::object());
std::cout << "Original multi dimensional array :: " << std::endl << p::extract < char const * > (p::str(mul_data_ex)) << std::endl ;
// Now create the new ndarray using the shape and strides
mul_data_ex = np::from_data(mul_data,dt1, shape,stride,p::object());
// Print out the array we created using non-unit strides
std::cout << "Selective multidimensional array :: "<<std::endl << p::extract < char const * > (p::str(mul_data_ex)) << std::endl ;
}

32
example/numpy/simple.cpp Normal file
View File

@@ -0,0 +1,32 @@
// Copyright 2011 Stefan Seefeld.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
int main(int argc, char **argv)
{
// Initialize the Python runtime.
Py_Initialize();
// Initialize NumPy
np::initialize();
// Create a 3x3 shape...
p::tuple shape = p::make_tuple(3, 3);
// ...as well as a type for C++ float
np::dtype dtype = np::dtype::get_builtin<float>();
// Construct an array with the above shape and type
np::ndarray a = np::zeros(shape, dtype);
// Construct an empty array with the above shape and dtype as well
np::ndarray b = np::empty(shape,dtype);
// Print the array
std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
// Reshape the array into a 1D array
a = a.reshape(p::make_tuple(9));
// Print it again.
std::cout << "Reshaped array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
}

86
example/numpy/ufunc.cpp Normal file
View File

@@ -0,0 +1,86 @@
// Copyright Ankit Daftery 2011-2012.
// 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)
/**
* @brief An example to demonstrate use of universal functions or ufuncs
*
*
* @todo Calling the overloaded () operator is in a roundabout manner, find a simpler way
* None of the methods like np::add, np::multiply etc are supported as yet
*/
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
// Create the structs necessary to implement the ufuncs
// The typedefs *must* be made
struct UnarySquare
{
typedef double argument_type;
typedef double result_type;
double operator()(double r) const { return r * r;}
};
struct BinarySquare
{
typedef double first_argument_type;
typedef double second_argument_type;
typedef double result_type;
double operator()(double a,double b) const { return (a*a + b*b) ; }
};
int main(int argc, char **argv)
{
// Initialize the Python runtime.
Py_Initialize();
// Initialize NumPy
np::initialize();
// Expose the struct UnarySquare to Python as a class, and let ud be the class object
p::object ud = p::class_<UnarySquare, boost::shared_ptr<UnarySquare> >("UnarySquare")
.def("__call__", np::unary_ufunc<UnarySquare>::make());
// Let inst be an instance of the class ud
p::object inst = ud();
// Use the "__call__" method to call the overloaded () operator and print the value
std::cout << "Square of unary scalar 1.0 is " << p::extract <char const * > (p::str(inst.attr("__call__")(1.0))) << std::endl ;
// Create an array in C++
int arr[] = {1,2,3,4} ;
// ..and use it to create the ndarray in Python
np::ndarray demo_array = np::from_data(arr, np::dtype::get_builtin<int>() , p::make_tuple(4), p::make_tuple(4), p::object());
// Print out the demo array
std::cout << "Demo array is " << p::extract <char const * > (p::str(demo_array)) << std::endl ;
// Call the "__call__" method to perform the operation and assign the value to result_array
p::object result_array = inst.attr("__call__")(demo_array) ;
// Print the resultant array
std::cout << "Square of demo array is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
// Lets try the same with a list
p::list li ;
li.append(3);
li.append(7);
// Print out the demo list
std::cout << "Demo list is " << p::extract <char const * > (p::str(li)) << std::endl ;
// Call the ufunc for the list
result_array = inst.attr("__call__")(li) ;
// And print the list out
std::cout << "Square of demo list is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
// Now lets try Binary ufuncs
// Expose the struct BinarySquare to Python as a class, and let ud be the class object
ud = p::class_<BinarySquare, boost::shared_ptr<BinarySquare> >("BinarySquare")
.def("__call__", np::binary_ufunc<BinarySquare>::make());
// Again initialise inst as an instance of the class ud
inst = ud();
// Print the two input listsPrint the two input lists
std::cout << "The two input list for binary ufunc are " << std::endl << p::extract <char const * > (p::str(demo_array)) << std::endl << p::extract <char const * > (p::str(demo_array)) << std::endl ;
// Call the binary ufunc taking demo_array as both inputs
result_array = inst.attr("__call__")(demo_array,demo_array) ;
std::cout << "Square of list with binary ufunc is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
}

135
example/numpy/wrap.cpp Normal file
View File

@@ -0,0 +1,135 @@
// Copyright Jim Bosch 2011-2012.
// 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)
/**
* A simple example showing how to wrap a couple of C++ functions that
* operate on 2-d arrays into Python functions that take NumPy arrays
* as arguments.
*
* If you find have a lot of such functions to wrap, you may want to
* create a C++ array type (or use one of the many existing C++ array
* libraries) that maps well to NumPy arrays and create Boost.Python
* converters. There's more work up front than the approach here,
* but much less boilerplate per function. See the "Gaussian" example
* included with Boost.NumPy for an example of custom converters, or
* take a look at the "ndarray" project on GitHub for a more complete,
* high-level solution.
*
* Note that we're using embedded Python here only to make a convenient
* self-contained example; you could just as easily put the wrappers
* in a regular C++-compiled module and imported them in regular
* Python. Again, see the Gaussian demo for an example.
*/
#include <boost/python/numpy.hpp>
#include <boost/scoped_array.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
// This is roughly the most efficient way to write a C/C++ function that operates
// on a 2-d NumPy array - operate directly on the array by incrementing a pointer
// with the strides.
void fill1(double * array, int rows, int cols, int row_stride, int col_stride) {
double * row_iter = array;
double n = 0.0; // just a counter we'll fill the array with.
for (int i = 0; i < rows; ++i, row_iter += row_stride) {
double * col_iter = row_iter;
for (int j = 0; j < cols; ++j, col_iter += col_stride) {
*col_iter = ++n;
}
}
}
// Here's a simple wrapper function for fill1. It requires that the passed
// NumPy array be exactly what we're looking for - no conversion from nested
// sequences or arrays with other data types, because we want to modify it
// in-place.
void wrap_fill1(np::ndarray const & array) {
if (array.get_dtype() != np::dtype::get_builtin<double>()) {
PyErr_SetString(PyExc_TypeError, "Incorrect array data type");
p::throw_error_already_set();
}
if (array.get_nd() != 2) {
PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions");
p::throw_error_already_set();
}
fill1(reinterpret_cast<double*>(array.get_data()),
array.shape(0), array.shape(1),
array.strides(0) / sizeof(double), array.strides(1) / sizeof(double));
}
// Another fill function that takes a double**. This is less efficient, because
// it's not the native NumPy data layout, but it's common enough in C/C++ that
// it's worth its own example. This time we don't pass the strides, and instead
// in wrap_fill2 we'll require the C_CONTIGUOUS bitflag, which guarantees that
// the column stride is 1 and the row stride is the number of columns. That
// restricts the arrays that can be passed to fill2 (it won't work on most
// subarray views or transposes, for instance).
void fill2(double ** array, int rows, int cols) {
double n = 0.0; // just a counter we'll fill the array with.
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
array[i][j] = ++n;
}
}
}
// Here's the wrapper for fill2; it's a little more complicated because we need
// to check the flags and create the array of pointers.
void wrap_fill2(np::ndarray const & array) {
if (array.get_dtype() != np::dtype::get_builtin<double>()) {
PyErr_SetString(PyExc_TypeError, "Incorrect array data type");
p::throw_error_already_set();
}
if (array.get_nd() != 2) {
PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions");
p::throw_error_already_set();
}
if (!(array.get_flags() & np::ndarray::C_CONTIGUOUS)) {
PyErr_SetString(PyExc_TypeError, "Array must be row-major contiguous");
p::throw_error_already_set();
}
double * iter = reinterpret_cast<double*>(array.get_data());
int rows = array.shape(0);
int cols = array.shape(1);
boost::scoped_array<double*> ptrs(new double*[rows]);
for (int i = 0; i < rows; ++i, iter += cols) {
ptrs[i] = iter;
}
fill2(ptrs.get(), array.shape(0), array.shape(1));
}
BOOST_PYTHON_MODULE(example) {
np::initialize(); // have to put this in any module that uses Boost.NumPy
p::def("fill1", wrap_fill1);
p::def("fill2", wrap_fill2);
}
int main(int argc, char **argv)
{
// This line makes our module available to the embedded Python intepreter.
# if PY_VERSION_HEX >= 0x03000000
PyImport_AppendInittab("example", &PyInit_example);
# else
PyImport_AppendInittab("example", &initexample);
# endif
// Initialize the Python runtime.
Py_Initialize();
PyRun_SimpleString(
"import example\n"
"import numpy\n"
"z1 = numpy.zeros((5,6), dtype=float)\n"
"z2 = numpy.zeros((4,3), dtype=float)\n"
"example.fill1(z1)\n"
"example.fill2(z2)\n"
"print z1\n"
"print z2\n"
);
Py_Finalize();
}

Binary file not shown.

View File

@@ -1,23 +1,15 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Copyright Stefan Seefeld 2016.
# 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)
# Specify the path to the Boost project. If you move this project,
# adjust the path to refer to the Boost root directory.
use-project boost
: ../../../.. ;
# Set up the project-wide requirements that everything uses the
# boost_python library defined in the project whose global ID is
# /boost/python.
project boost-python-quickstart
: requirements <library>/boost/python//boost_python
<implicit-dependency>/boost//headers
: usage-requirements <implicit-dependency>/boost//headers
;
# Make the definition of the python-extension rule available
import python ;
import testing ;
project quickstart
: requirements
<location>.
;
# Declare a Python extension called hello.
python-extension extending : extending.cpp ;
@@ -25,8 +17,6 @@ python-extension extending : extending.cpp ;
# Declare an executable called embedding that embeds Python
exe embedding : embedding.cpp /python//python ;
import testing ;
# Declare a test of the extension module
testing.make-test run-pyd : extending test_extending.py : : test_ext ;

View File

@@ -1,7 +0,0 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Edit this path to point at the tools/build/src subdirectory of your
# Boost installation. Absolute paths work, too.
boost-build ../../../../tools/build/src ;

View File

@@ -1,6 +1,7 @@
#! /usr/bin/env python
# Copyright Stefan Seefeld 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
print 'Hello World !'
print('Hello World !')
number = 42

View File

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

View File

@@ -1,49 +0,0 @@
// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/to_python_converter.hpp>
namespace { // Avoid cluttering the global namespace.
// Converts a std::pair instance to a Python tuple.
template <typename T1, typename T2>
struct std_pair_to_tuple
{
static PyObject* convert(std::pair<T1, T2> const& p)
{
return boost::python::incref(
boost::python::make_tuple(p.first, p.second).ptr());
}
static PyTypeObject const *get_pytype () {return &PyTuple_Type; }
};
// Helper for convenience.
template <typename T1, typename T2>
struct std_pair_to_python_converter
{
std_pair_to_python_converter()
{
boost::python::to_python_converter<
std::pair<T1, T2>,
std_pair_to_tuple<T1, T2>,
true //std_pair_to_tuple has get_pytype
>();
}
};
// Example function returning a std::pair.
std::pair<int, int>
foo() { return std::pair<int, int>(3, 5); }
} // namespace anonymous
BOOST_PYTHON_MODULE(std_pair_ext)
{
using namespace boost::python;
std_pair_to_python_converter<int, int>();
def("foo", foo);
}

View File

@@ -1,21 +0,0 @@
# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
r'''>>> import getting_started1
>>> print getting_started1.greet()
hello, world
>>> number = 11
>>> print number, '*', number, '=', getting_started1.square(number)
11 * 11 = 121
'''
def run(args = None):
if args is not None:
import sys
sys.argv = args
import doctest, test_getting_started1
return doctest.testmod(test_getting_started1)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

View File

@@ -1,34 +0,0 @@
# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
r'''>>> from getting_started2 import *
>>> hi = hello('California')
>>> hi.greet()
'Hello from California'
>>> invite(hi)
'Hello from California! Please come soon!'
>>> hi.invite()
'Hello from California! Please come soon!'
>>> class wordy(hello):
... def greet(self):
... return hello.greet(self) + ', where the weather is fine'
...
>>> hi2 = wordy('Florida')
>>> hi2.greet()
'Hello from Florida, where the weather is fine'
>>> invite(hi2)
'Hello from Florida! Please come soon!'
'''
def run(args = None):
if args is not None:
import sys
sys.argv = args
import doctest, test_getting_started2
return doctest.testmod(test_getting_started2)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

View File

@@ -1,6 +0,0 @@
# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import std_pair_ext
assert std_pair_ext.foo() == (3, 5)
print "OK"

19
example/tutorial/Jamfile Normal file
View File

@@ -0,0 +1,19 @@
# Copyright Stefan Seefeld 2016.
# 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 python ;
project tutorial
: requirements
<location>.
;
python-extension hello_ext : hello.cpp ;
run-test hello : hello_ext hello.py ;
alias test : hello ;
explicit test ;

View File

@@ -1,51 +0,0 @@
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import python ;
if ! [ python.configured ]
{
ECHO "notice: no Python configured in user-config.jam" ;
ECHO "notice: will use default configuration" ;
using python ;
}
# Specify the path to the Boost project. If you move this project,
# adjust this path to refer to the Boost root directory.
use-project boost
: ../../../.. ;
# Set up the project-wide requirements that everything uses the
# boost_python library from the project whose global ID is
# /boost/python.
project
: requirements <library>/boost/python//boost_python
<implicit-dependency>/boost//headers
: usage-requirements <implicit-dependency>/boost//headers
;
# Declare the three extension modules. You can specify multiple
# source files after the colon separated by spaces.
python-extension hello_ext : hello.cpp ;
# Put the extension and Boost.Python DLL in the current directory, so
# that running script by hand works.
install convenient_copy
: hello_ext
: <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION
<location>.
;
# A little "rule" (function) to clean up the syntax of declaring tests
# of these extension modules.
local rule run-test ( test-name : sources + )
{
import testing ;
testing.make-test run-pyd : $(sources) : : $(test-name) ;
}
# Declare test targets
run-test hello : hello_ext hello.py ;

View File

@@ -1,7 +1,8 @@
#! /usr/bin/env python
# Copyright Joel de Guzman 2002-2007. Distributed under the Boost
# Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
# or copy at http://www.boost.org/LICENSE_1_0.txt)
# Hello World Example from the tutorial
import hello_ext
print hello_ext.greet()
print(hello_ext.greet())

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

View File

@@ -42,7 +42,6 @@
# include <boost/python/make_function.hpp>
# include <boost/python/manage_new_object.hpp>
# include <boost/python/module.hpp>
# include <boost/python/numeric.hpp>
# include <boost/python/object.hpp>
# include <boost/python/object_protocol.hpp>
# include <boost/python/object_protocol_core.hpp>

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

@@ -9,7 +9,7 @@
# include <boost/python/converter/arg_from_python.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
# include <boost/type_traits/remove_cv.hpp>
# include <boost/python/detail/type_traits.hpp>
#endif
namespace boost { namespace python {
@@ -19,7 +19,7 @@ struct arg_from_python
: converter::select_arg_from_python<
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
typename boost::remove_cv<T>::type
typename detail::remove_cv<T>::type
# else
T
# endif
@@ -28,7 +28,7 @@ struct arg_from_python
typedef typename converter::select_arg_from_python<
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
typename boost::remove_cv<T>::type
typename detail::remove_cv<T>::type
# else
T
# endif

View File

@@ -11,10 +11,7 @@
# include <boost/config.hpp>
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/detail/type_list.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/type_traits/remove_reference.hpp>
# include <boost/type_traits/remove_cv.hpp>
# include <boost/python/detail/type_traits.hpp>
# include <boost/preprocessor/enum_params.hpp>
# include <boost/preprocessor/repeat.hpp>
@@ -116,9 +113,9 @@ namespace detail
template <class T>
struct is_reference_to_keywords
{
BOOST_STATIC_CONSTANT(bool, is_ref = is_reference<T>::value);
typedef typename remove_reference<T>::type deref;
typedef typename remove_cv<deref>::type key_t;
BOOST_STATIC_CONSTANT(bool, is_ref = detail::is_reference<T>::value);
typedef typename detail::remove_reference<T>::type deref;
typedef typename detail::remove_cv<deref>::type key_t;
BOOST_STATIC_CONSTANT(bool, is_key = is_keywords<key_t>::value);
BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key));

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

View File

@@ -6,8 +6,8 @@
# define BASES_DWA2002321_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/type_traits/object_traits.hpp>
# include <boost/python/detail/type_list.hpp>
# include <boost/python/detail/type_traits.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/preprocessor/enum_params_with_a_default.hpp>

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