mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-11 08:03:55 +00:00
commit
faec30c4db
@ -5,7 +5,6 @@ platform:
|
|||||||
- x86
|
- x86
|
||||||
- x64
|
- x64
|
||||||
environment:
|
environment:
|
||||||
CTEST_OUTPUT_ON_FAILURE: 1
|
|
||||||
matrix:
|
matrix:
|
||||||
- CONDA: 27
|
- CONDA: 27
|
||||||
- CONDA: 35
|
- CONDA: 35
|
||||||
@ -16,12 +15,12 @@ install:
|
|||||||
if ($env:PLATFORM -eq "x64") { $env:PYTHON = "$env:PYTHON-x64" }
|
if ($env:PLATFORM -eq "x64") { $env:PYTHON = "$env:PYTHON-x64" }
|
||||||
$env:PATH = "C:\Python$env:PYTHON\;C:\Python$env:PYTHON\Scripts\;$env:PATH"
|
$env:PATH = "C:\Python$env:PYTHON\;C:\Python$env:PYTHON\Scripts\;$env:PATH"
|
||||||
pip install --disable-pip-version-check --user --upgrade pip wheel
|
pip install --disable-pip-version-check --user --upgrade pip wheel
|
||||||
pip install numpy scipy
|
pip install pytest numpy scipy
|
||||||
} elseif ($env:CONDA) {
|
} elseif ($env:CONDA) {
|
||||||
if ($env:CONDA -eq "27") { $env:CONDA = "" }
|
if ($env:CONDA -eq "27") { $env:CONDA = "" }
|
||||||
if ($env:PLATFORM -eq "x64") { $env:CONDA = "$env:CONDA-x64" }
|
if ($env:PLATFORM -eq "x64") { $env:CONDA = "$env:CONDA-x64" }
|
||||||
$env:PATH = "C:\Miniconda$env:CONDA\;C:\Miniconda$env:CONDA\Scripts\;$env:PATH"
|
$env:PATH = "C:\Miniconda$env:CONDA\;C:\Miniconda$env:CONDA\Scripts\;$env:PATH"
|
||||||
conda install -y -q numpy scipy
|
conda install -y -q pytest numpy scipy
|
||||||
}
|
}
|
||||||
- ps: |
|
- ps: |
|
||||||
Start-FileDownload 'http://bitbucket.org/eigen/eigen/get/3.2.9.zip'
|
Start-FileDownload 'http://bitbucket.org/eigen/eigen/get/3.2.9.zip'
|
||||||
@ -30,4 +29,4 @@ install:
|
|||||||
build_script:
|
build_script:
|
||||||
- cmake -A "%CMAKE_ARCH%" -DPYBIND11_WERROR=ON
|
- cmake -A "%CMAKE_ARCH%" -DPYBIND11_WERROR=ON
|
||||||
- set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
- set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||||
- cmake --build . --config Release --target check -- /v:m /logger:%MSBuildLogger%
|
- cmake --build . --config Release --target pytest -- /v:m /logger:%MSBuildLogger%
|
||||||
|
8
.gitignore
vendored
8
.gitignore
vendored
@ -3,10 +3,9 @@ CMakeFiles
|
|||||||
Makefile
|
Makefile
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/example/example*.so
|
*.so
|
||||||
/example/example.cpython*.so
|
*.pyd
|
||||||
/example/example.pyd
|
*.dll
|
||||||
/example/example*.dll
|
|
||||||
*.sln
|
*.sln
|
||||||
*.sdf
|
*.sdf
|
||||||
*.opensdf
|
*.opensdf
|
||||||
@ -32,3 +31,4 @@ MANIFEST
|
|||||||
/dist
|
/dist
|
||||||
/build
|
/build
|
||||||
/cmake/
|
/cmake/
|
||||||
|
.cache/
|
||||||
|
@ -39,7 +39,7 @@ matrix:
|
|||||||
install:
|
install:
|
||||||
- >
|
- >
|
||||||
docker exec --tty "$containerid" apt-get -y --no-install-recommends install
|
docker exec --tty "$containerid" apt-get -y --no-install-recommends install
|
||||||
python2.7-dev python-scipy libeigen3-dev
|
python2.7-dev python-pip python-setuptools python-scipy libeigen3-dev
|
||||||
cmake make g++
|
cmake make g++
|
||||||
- compiler: gcc-6
|
- compiler: gcc-6
|
||||||
services: docker
|
services: docker
|
||||||
@ -48,7 +48,7 @@ matrix:
|
|||||||
install:
|
install:
|
||||||
- >
|
- >
|
||||||
docker exec --tty "$containerid" apt-get -y --no-install-recommends install
|
docker exec --tty "$containerid" apt-get -y --no-install-recommends install
|
||||||
python3.5-dev python3-scipy libeigen3-dev
|
python3.5-dev python3-pip python3-setuptools python3-scipy libeigen3-dev
|
||||||
cmake make g++
|
cmake make g++
|
||||||
# Documentation build:
|
# Documentation build:
|
||||||
- os: linux
|
- os: linux
|
||||||
@ -98,12 +98,12 @@ install:
|
|||||||
|
|
||||||
wget -q -O eigen.tar.gz https://bitbucket.org/eigen/eigen/get/3.2.9.tar.gz
|
wget -q -O eigen.tar.gz https://bitbucket.org/eigen/eigen/get/3.2.9.tar.gz
|
||||||
tar xzf eigen.tar.gz
|
tar xzf eigen.tar.gz
|
||||||
export CMAKE_EXTRA_ARGS="${CMAKE_EXTRA_ARGS} -DCMAKE_INCLUDE_PATH=eigen-eigen-dc6cfdf9bcec"
|
export CMAKE_EXTRA_ARGS="${CMAKE_EXTRA_ARGS} -DCMAKE_INCLUDE_PATH=$PWD/eigen-eigen-dc6cfdf9bcec"
|
||||||
script:
|
script:
|
||||||
- $SCRIPT_RUN_PREFIX cmake ${CMAKE_EXTRA_ARGS}
|
- $SCRIPT_RUN_PREFIX cmake ${CMAKE_EXTRA_ARGS}
|
||||||
-DPYBIND11_PYTHON_VERSION=$PYTHON
|
-DPYBIND11_PYTHON_VERSION=$PYTHON
|
||||||
-DPYBIND11_CPP_STANDARD=-std=c++$CPP
|
-DPYBIND11_CPP_STANDARD=-std=c++$CPP
|
||||||
-DPYBIND11_WERROR=ON
|
-DPYBIND11_WERROR=ON
|
||||||
- $SCRIPT_RUN_PREFIX make CTEST_OUTPUT_ON_FAILURE=TRUE check -j 2
|
- $SCRIPT_RUN_PREFIX make pytest -j 2
|
||||||
after_script:
|
after_script:
|
||||||
- if [ -n "$DOCKER" ]; then docker stop "$containerid"; docker rm "$containerid"; fi
|
- if [ -n "$DOCKER" ]; then docker stop "$containerid"; docker rm "$containerid"; fi
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# CMakeLists.txt -- Build system for the pybind11 examples
|
# CMakeLists.txt -- Build system for the pybind11 modules
|
||||||
#
|
#
|
||||||
# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
|
# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
|
||||||
#
|
#
|
||||||
@ -20,7 +20,7 @@ option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJE
|
|||||||
option(PYBIND11_WERROR "Report all warnings as errors" OFF)
|
option(PYBIND11_WERROR "Report all warnings as errors" OFF)
|
||||||
|
|
||||||
# Add a CMake parameter for choosing a desired Python version
|
# Add a CMake parameter for choosing a desired Python version
|
||||||
set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling the example application")
|
set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling modules")
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/tools")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/tools")
|
||||||
set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
|
set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
|
||||||
@ -146,17 +146,15 @@ function(pybind11_enable_warnings target_name)
|
|||||||
|
|
||||||
if(PYBIND11_WERROR)
|
if(PYBIND11_WERROR)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_compile_options(${target_name} PRIVATE /WX)
|
target_compile_options(${target_name} PRIVATE /WX)
|
||||||
else()
|
else()
|
||||||
target_compile_options(${target_name} PRIVATE -Werror)
|
target_compile_options(${target_name} PRIVATE -Werror)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
if (PYBIND11_TEST)
|
if (PYBIND11_TEST)
|
||||||
enable_testing()
|
add_subdirectory(tests)
|
||||||
add_subdirectory(example)
|
|
||||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> DEPENDS example)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (PYBIND11_INSTALL)
|
if (PYBIND11_INSTALL)
|
||||||
|
@ -102,7 +102,7 @@ C++ side, or to perform other types of customization.
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example-operator-overloading.cpp` contains a
|
The file :file:`tests/test_operator_overloading.cpp` contains a
|
||||||
complete example that demonstrates how to work with overloaded operators in
|
complete example that demonstrates how to work with overloaded operators in
|
||||||
more detail.
|
more detail.
|
||||||
|
|
||||||
@ -203,14 +203,14 @@ The following interactive session shows how to call them from Python.
|
|||||||
is passed as an argument to another C++ function exposed in Python. In this
|
is passed as an argument to another C++ function exposed in Python. In this
|
||||||
case, there is no overhead. Pybind11 will extract the underlying C++
|
case, there is no overhead. Pybind11 will extract the underlying C++
|
||||||
function pointer from the wrapped function to sidestep a potential C++ ->
|
function pointer from the wrapped function to sidestep a potential C++ ->
|
||||||
Python -> C++ roundtrip. This is demonstrated in Example 5.
|
Python -> C++ roundtrip. This is demonstrated in :file:`tests/test_callbacks.cpp`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
This functionality is very useful when generating bindings for callbacks in
|
This functionality is very useful when generating bindings for callbacks in
|
||||||
C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.).
|
C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.).
|
||||||
|
|
||||||
The file :file:`example/example-callbacks.cpp` contains a complete example
|
The file :file:`tests/test_callbacks.cpp` contains a complete example
|
||||||
that demonstrates how to work with callbacks and anonymous functions in
|
that demonstrates how to work with callbacks and anonymous functions in
|
||||||
more detail.
|
more detail.
|
||||||
|
|
||||||
@ -354,7 +354,7 @@ Please take a look at the :ref:`macro_notes` before using this feature.
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example-virtual-functions.cpp` contains a complete
|
The file :file:`tests/test_virtual_functions.cpp` contains a complete
|
||||||
example that demonstrates how to override virtual functions using pybind11
|
example that demonstrates how to override virtual functions using pybind11
|
||||||
in more detail.
|
in more detail.
|
||||||
|
|
||||||
@ -472,7 +472,7 @@ can now create a python class that inherits from ``Dog``:
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
See the file :file:`example-virtual-functions.cpp` for complete examples
|
See the file :file:`tests/test_virtual_functions.cpp` for complete examples
|
||||||
using both the duplication and templated trampoline approaches.
|
using both the duplication and templated trampoline approaches.
|
||||||
|
|
||||||
.. _macro_notes:
|
.. _macro_notes:
|
||||||
@ -556,7 +556,7 @@ out of the box with just the core :file:`pybind11/pybind11.h` header.
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example-python-types.cpp` contains a complete
|
The file :file:`tests/test_python_types.cpp` contains a complete
|
||||||
example that demonstrates how to pass STL data types in more detail.
|
example that demonstrates how to pass STL data types in more detail.
|
||||||
|
|
||||||
Binding sequence data types, iterators, the slicing protocol, etc.
|
Binding sequence data types, iterators, the slicing protocol, etc.
|
||||||
@ -566,7 +566,7 @@ Please refer to the supplemental example for details.
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example-sequences-and-iterators.cpp` contains a
|
The file :file:`tests/test_sequences_and_iterators.cpp` contains a
|
||||||
complete example that shows how to bind a sequence data type, including
|
complete example that shows how to bind a sequence data type, including
|
||||||
length queries (``__len__``), iterators (``__iter__``), the slicing
|
length queries (``__len__``), iterators (``__iter__``), the slicing
|
||||||
protocol and other kinds of useful operations.
|
protocol and other kinds of useful operations.
|
||||||
@ -706,7 +706,7 @@ container:
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example-keep-alive.cpp` contains a complete example
|
The file :file:`tests/test_keep_alive.cpp` contains a complete example
|
||||||
that demonstrates using :class:`keep_alive` in more detail.
|
that demonstrates using :class:`keep_alive` in more detail.
|
||||||
|
|
||||||
Implicit type conversions
|
Implicit type conversions
|
||||||
@ -908,7 +908,7 @@ Please take a look at the :ref:`macro_notes` before using this feature.
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example-smart-ptr.cpp` contains a complete example
|
The file :file:`tests/test_smart_ptr.cpp` contains a complete example
|
||||||
that demonstrates how to work with custom reference-counting holder types
|
that demonstrates how to work with custom reference-counting holder types
|
||||||
in more detail.
|
in more detail.
|
||||||
|
|
||||||
@ -1021,7 +1021,7 @@ a first shot at handling the exception).
|
|||||||
Inside the translator, ``std::rethrow_exception`` should be used within
|
Inside the translator, ``std::rethrow_exception`` should be used within
|
||||||
a try block to re-throw the exception. A catch clause can then use
|
a try block to re-throw the exception. A catch clause can then use
|
||||||
``PyErr_SetString`` to set a Python exception as demonstrated
|
``PyErr_SetString`` to set a Python exception as demonstrated
|
||||||
in :file:`example-custom-exceptions.cpp``.
|
in :file:`tests/test_exceptions.cpp`.
|
||||||
|
|
||||||
This example also demonstrates how to create custom exception types
|
This example also demonstrates how to create custom exception types
|
||||||
with ``py::exception``.
|
with ``py::exception``.
|
||||||
@ -1159,7 +1159,7 @@ Please take a look at the :ref:`macro_notes` before using this feature.
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example-opaque-types.cpp` contains a complete
|
The file :file:`tests/test_opaque_types.cpp` contains a complete
|
||||||
example that demonstrates how to create and expose opaque types using
|
example that demonstrates how to create and expose opaque types using
|
||||||
pybind11 in more detail.
|
pybind11 in more detail.
|
||||||
|
|
||||||
@ -1214,7 +1214,7 @@ with NumPy and SciPy.
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/eigen.cpp` contains a complete example that
|
The file :file:`tests/test_eigen.cpp` contains a complete example that
|
||||||
shows how to pass Eigen sparse and dense data types in more detail.
|
shows how to pass Eigen sparse and dense data types in more detail.
|
||||||
|
|
||||||
Buffer protocol
|
Buffer protocol
|
||||||
@ -1342,7 +1342,7 @@ limitations), refer to the section on :ref:`eigen`.
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example-buffers.cpp` contains a complete example
|
The file :file:`tests/test_buffers.cpp` contains a complete example
|
||||||
that demonstrates using the buffer protocol with pybind11 in more detail.
|
that demonstrates using the buffer protocol with pybind11 in more detail.
|
||||||
|
|
||||||
.. [#f2] http://docs.python.org/3/c-api/buffer.html
|
.. [#f2] http://docs.python.org/3/c-api/buffer.html
|
||||||
@ -1509,7 +1509,7 @@ simply using ``vectorize``).
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example-numpy-vectorize.cpp` contains a complete
|
The file :file:`tests/test_numpy_vectorize.cpp` contains a complete
|
||||||
example that demonstrates using :func:`vectorize` in more detail.
|
example that demonstrates using :func:`vectorize` in more detail.
|
||||||
|
|
||||||
Functions taking Python objects as arguments
|
Functions taking Python objects as arguments
|
||||||
@ -1573,9 +1573,9 @@ with other parameters.
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example-python-types.cpp` contains a complete
|
The file :file:`tests/test_python_types.cpp` contains a complete
|
||||||
example that demonstrates passing native Python types in more detail. The
|
example that demonstrates passing native Python types in more detail. The
|
||||||
file :file:`example/example-arg-keywords-and-defaults.cpp` discusses usage
|
file :file:`tests/test_kwargs_and_defaults.cpp` discusses usage
|
||||||
of ``args`` and ``kwargs``.
|
of ``args`` and ``kwargs``.
|
||||||
|
|
||||||
Default arguments revisited
|
Default arguments revisited
|
||||||
@ -1649,7 +1649,7 @@ Such functions can also be created using pybind11:
|
|||||||
/// Binding code
|
/// Binding code
|
||||||
m.def("generic", &generic);
|
m.def("generic", &generic);
|
||||||
|
|
||||||
(See ``example/example-arg-keywords-and-defaults.cpp``). The class ``py::args``
|
(See ``tests/test_kwargs_and_defaults.cpp``). The class ``py::args``
|
||||||
derives from ``py::list`` and ``py::kwargs`` derives from ``py::dict`` Note
|
derives from ``py::list`` and ``py::kwargs`` derives from ``py::dict`` Note
|
||||||
that the ``kwargs`` argument is invalid if no keyword arguments were actually
|
that the ``kwargs`` argument is invalid if no keyword arguments were actually
|
||||||
provided. Please refer to the other examples for details on how to iterate
|
provided. Please refer to the other examples for details on how to iterate
|
||||||
@ -1799,7 +1799,7 @@ memory corruption and/or segmentation faults.
|
|||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example-pickling.cpp` contains a complete example
|
The file :file:`tests/test_pickling.cpp` contains a complete example
|
||||||
that demonstrates how to pickle and unpickle types using pybind11 in more
|
that demonstrates how to pickle and unpickle types using pybind11 in more
|
||||||
detail.
|
detail.
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ First steps
|
|||||||
|
|
||||||
This sections demonstrates the basic features of pybind11. Before getting
|
This sections demonstrates the basic features of pybind11. Before getting
|
||||||
started, make sure that development environment is set up to compile the
|
started, make sure that development environment is set up to compile the
|
||||||
included set of examples, which also double as test cases.
|
included set of test cases.
|
||||||
|
|
||||||
|
|
||||||
Compiling the test cases
|
Compiling the test cases
|
||||||
@ -22,44 +22,42 @@ After installing the prerequisites, run
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
cmake .
|
mkdir build
|
||||||
make -j 4
|
cd build
|
||||||
|
cmake ..
|
||||||
|
make pytest -j 4
|
||||||
|
|
||||||
followed by
|
The last line will both compile and run the tests.
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
make test
|
|
||||||
|
|
||||||
Windows
|
Windows
|
||||||
-------
|
-------
|
||||||
|
|
||||||
On Windows, use the `CMake GUI`_ to create a Visual Studio project. Note that
|
On Windows, only **Visual Studio 2015** and newer are supported since pybind11 relies
|
||||||
only the 2015 release and newer versions are supported since pybind11 relies on
|
on various C++11 language features that break older versions of Visual Studio.
|
||||||
various C++11 language features that break older versions of Visual Studio.
|
|
||||||
After running CMake, open the created :file:`pybind11.sln` file and perform a
|
|
||||||
release build, which will will produce a file named
|
|
||||||
:file:`Release\\example.pyd`. Copy this file to the :file:`example` directory
|
|
||||||
and run :file:`example\\run_test.py` using the targeted Python version.
|
|
||||||
|
|
||||||
.. _`CMake GUI`: https://cmake.org/runningcmake
|
To compile and run the tests:
|
||||||
|
|
||||||
|
.. code-block:: batch
|
||||||
|
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
cmake --build . --config Release --target pytest
|
||||||
|
|
||||||
|
This will create a Visual Studio project, compile and run the target, all from the
|
||||||
|
command line.
|
||||||
|
|
||||||
.. Note::
|
.. Note::
|
||||||
|
|
||||||
When all tests fail, make sure that
|
If all tests fail, make sure that the Python binary and the testcases are compiled
|
||||||
|
for the same processor type and bitness (i.e. either **i386** or **x86_64**). You
|
||||||
1. The Python binary and the testcases are compiled for the same processor
|
can specify **x86_64** as the target architecture for the generated Visual Studio
|
||||||
type and bitness (i.e. either **i386** or **x86_64**)
|
project using ``cmake -A x64 ..``.
|
||||||
|
|
||||||
2. The Python binary used to run :file:`example\\run_test.py` matches the
|
|
||||||
Python version specified in the CMake GUI. This is controlled via
|
|
||||||
the ``PYTHON_EXECUTABLE`` ``PYTHON_INCLUDE_DIR``, and
|
|
||||||
``PYTHON_LIBRARY`` variables.
|
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
Advanced users who are already familiar with Boost.Python may want to skip
|
Advanced users who are already familiar with Boost.Python may want to skip
|
||||||
the tutorial and look at the test cases in the :file:`example` directory,
|
the tutorial and look at the test cases in the :file:`tests` directory,
|
||||||
which exercise all features of pybind11.
|
which exercise all features of pybind11.
|
||||||
|
|
||||||
Creating bindings for a simple function
|
Creating bindings for a simple function
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
# Set a default build configuration if none is specified. 'MinSizeRel' produces the smallest binaries
|
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
|
||||||
message(STATUS "Setting build type to 'MinSizeRel' as none was specified.")
|
|
||||||
set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE)
|
|
||||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
|
|
||||||
"MinSizeRel" "RelWithDebInfo")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(PYBIND11_EXAMPLES
|
|
||||||
example-methods-and-attributes.cpp
|
|
||||||
example-python-types.cpp
|
|
||||||
example-operator-overloading.cpp
|
|
||||||
example-constants-and-functions.cpp
|
|
||||||
example-callbacks.cpp
|
|
||||||
example-sequences-and-iterators.cpp
|
|
||||||
example-buffers.cpp
|
|
||||||
example-smart-ptr.cpp
|
|
||||||
example-modules.cpp
|
|
||||||
example-numpy-vectorize.cpp
|
|
||||||
example-arg-keywords-and-defaults.cpp
|
|
||||||
example-virtual-functions.cpp
|
|
||||||
example-keep-alive.cpp
|
|
||||||
example-opaque-types.cpp
|
|
||||||
example-pickling.cpp
|
|
||||||
example-inheritance.cpp
|
|
||||||
example-stl-binder-vector.cpp
|
|
||||||
example-eval.cpp
|
|
||||||
example-custom-exceptions.cpp
|
|
||||||
example-numpy-dtypes.cpp
|
|
||||||
issues.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check if Eigen is available
|
|
||||||
find_package(Eigen3 QUIET)
|
|
||||||
|
|
||||||
if(EIGEN3_FOUND)
|
|
||||||
list(APPEND PYBIND11_EXAMPLES eigen.cpp)
|
|
||||||
message(STATUS "Building Eigen v${EIGEN3_VERSION} testcase")
|
|
||||||
else()
|
|
||||||
message(STATUS "NOT Building Eigen testcase")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Create the binding library
|
|
||||||
pybind11_add_module(example example.cpp ${PYBIND11_EXAMPLES})
|
|
||||||
pybind11_enable_warnings(example)
|
|
||||||
|
|
||||||
if(EIGEN3_FOUND)
|
|
||||||
target_include_directories(example PRIVATE ${EIGEN3_INCLUDE_DIR})
|
|
||||||
target_compile_definitions(example PRIVATE -DPYBIND11_TEST_EIGEN)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Always write the output file directly into the 'example' directory (even on MSVC)
|
|
||||||
set(CompilerFlags
|
|
||||||
LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_RELEASE LIBRARY_OUTPUT_DIRECTORY_DEBUG
|
|
||||||
LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO
|
|
||||||
RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_RELEASE RUNTIME_OUTPUT_DIRECTORY_DEBUG
|
|
||||||
RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO)
|
|
||||||
|
|
||||||
foreach(CompilerFlag ${CompilerFlags})
|
|
||||||
set_target_properties(example PROPERTIES ${CompilerFlag} ${PROJECT_SOURCE_DIR}/example)
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
set(RUN_TEST ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/run_test.py)
|
|
||||||
|
|
||||||
foreach(VALUE ${PYBIND11_EXAMPLES})
|
|
||||||
string(REGEX REPLACE "^(.+).cpp$" "\\1" EXAMPLE_NAME "${VALUE}")
|
|
||||||
add_test(NAME ${EXAMPLE_NAME} COMMAND ${RUN_TEST} ${EXAMPLE_NAME})
|
|
||||||
endforeach()
|
|
114
example/eigen.py
114
example/eigen.py
@ -1,114 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import fixed_r, fixed_c
|
|
||||||
from example import fixed_passthrough_r, fixed_passthrough_c
|
|
||||||
from example import dense_r, dense_c
|
|
||||||
from example import dense_passthrough_r, dense_passthrough_c
|
|
||||||
from example import sparse_r, sparse_c
|
|
||||||
from example import sparse_passthrough_r, sparse_passthrough_c
|
|
||||||
from example import double_row, double_col
|
|
||||||
from example import double_mat_cm, double_mat_rm
|
|
||||||
from example import cholesky1, cholesky2, cholesky3, cholesky4, cholesky5, cholesky6
|
|
||||||
from example import diagonal, diagonal_1, diagonal_n
|
|
||||||
from example import block
|
|
||||||
from example import incr_diag, symmetric_upper, symmetric_lower
|
|
||||||
try:
|
|
||||||
import numpy as np
|
|
||||||
import scipy
|
|
||||||
except ImportError:
|
|
||||||
# NumPy missing: skip test
|
|
||||||
exit(99)
|
|
||||||
|
|
||||||
ref = np.array(
|
|
||||||
[[0, 3, 0, 0, 0, 11],
|
|
||||||
[22, 0, 0, 0, 17, 11],
|
|
||||||
[7, 5, 0, 1, 0, 11],
|
|
||||||
[0, 0, 0, 0, 0, 11],
|
|
||||||
[0, 0, 14, 0, 8, 11]])
|
|
||||||
|
|
||||||
|
|
||||||
def check(mat):
|
|
||||||
return 'OK' if np.sum(abs(mat - ref)) == 0 else 'NOT OK'
|
|
||||||
|
|
||||||
print("should_give_NOT_OK = %s" % check(ref[:, ::-1]))
|
|
||||||
|
|
||||||
print("fixed_r = %s" % check(fixed_r()))
|
|
||||||
print("fixed_c = %s" % check(fixed_c()))
|
|
||||||
print("pt_r(fixed_r) = %s" % check(fixed_passthrough_r(fixed_r())))
|
|
||||||
print("pt_c(fixed_c) = %s" % check(fixed_passthrough_c(fixed_c())))
|
|
||||||
print("pt_r(fixed_c) = %s" % check(fixed_passthrough_r(fixed_c())))
|
|
||||||
print("pt_c(fixed_r) = %s" % check(fixed_passthrough_c(fixed_r())))
|
|
||||||
|
|
||||||
print("dense_r = %s" % check(dense_r()))
|
|
||||||
print("dense_c = %s" % check(dense_c()))
|
|
||||||
print("pt_r(dense_r) = %s" % check(dense_passthrough_r(dense_r())))
|
|
||||||
print("pt_c(dense_c) = %s" % check(dense_passthrough_c(dense_c())))
|
|
||||||
print("pt_r(dense_c) = %s" % check(dense_passthrough_r(dense_c())))
|
|
||||||
print("pt_c(dense_r) = %s" % check(dense_passthrough_c(dense_r())))
|
|
||||||
|
|
||||||
print("sparse_r = %s" % check(sparse_r()))
|
|
||||||
print("sparse_c = %s" % check(sparse_c()))
|
|
||||||
print("pt_r(sparse_r) = %s" % check(sparse_passthrough_r(sparse_r())))
|
|
||||||
print("pt_c(sparse_c) = %s" % check(sparse_passthrough_c(sparse_c())))
|
|
||||||
print("pt_r(sparse_c) = %s" % check(sparse_passthrough_r(sparse_c())))
|
|
||||||
print("pt_c(sparse_r) = %s" % check(sparse_passthrough_c(sparse_r())))
|
|
||||||
|
|
||||||
def check_got_vs_ref(got_x, ref_x):
|
|
||||||
return 'OK' if np.array_equal(got_x, ref_x) else 'NOT OK'
|
|
||||||
|
|
||||||
counting_mat = np.arange(9.0, dtype=np.float32).reshape((3, 3))
|
|
||||||
first_row = counting_mat[0, :]
|
|
||||||
first_col = counting_mat[:, 0]
|
|
||||||
|
|
||||||
print("double_row(first_row) = %s" % check_got_vs_ref(double_row(first_row), 2.0 * first_row))
|
|
||||||
print("double_col(first_row) = %s" % check_got_vs_ref(double_col(first_row), 2.0 * first_row))
|
|
||||||
print("double_row(first_col) = %s" % check_got_vs_ref(double_row(first_col), 2.0 * first_col))
|
|
||||||
print("double_col(first_col) = %s" % check_got_vs_ref(double_col(first_col), 2.0 * first_col))
|
|
||||||
|
|
||||||
counting_3d = np.arange(27.0, dtype=np.float32).reshape((3, 3, 3))
|
|
||||||
slices = [counting_3d[0, :, :], counting_3d[:, 0, :], counting_3d[:, :, 0]]
|
|
||||||
|
|
||||||
for slice_idx, ref_mat in enumerate(slices):
|
|
||||||
print("double_mat_cm(%d) = %s" % (slice_idx, check_got_vs_ref(double_mat_cm(ref_mat), 2.0 * ref_mat)))
|
|
||||||
print("double_mat_rm(%d) = %s" % (slice_idx, check_got_vs_ref(double_mat_rm(ref_mat), 2.0 * ref_mat)))
|
|
||||||
|
|
||||||
i = 1
|
|
||||||
for chol in [cholesky1, cholesky2, cholesky3, cholesky4, cholesky5, cholesky6]:
|
|
||||||
mymat = chol(np.array([[1,2,4], [2,13,23], [4,23,77]]))
|
|
||||||
print("cholesky" + str(i) + " " + ("OK" if (mymat == np.array([[1,0,0], [2,3,0], [4,5,6]])).all() else "NOT OKAY"))
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
print("diagonal() %s" % ("OK" if (diagonal(ref) == ref.diagonal()).all() else "FAILED"))
|
|
||||||
print("diagonal_1() %s" % ("OK" if (diagonal_1(ref) == ref.diagonal(1)).all() else "FAILED"))
|
|
||||||
for i in range(-5, 7):
|
|
||||||
print("diagonal_n(%d) %s" % (i, "OK" if (diagonal_n(ref, i) == ref.diagonal(i)).all() else "FAILED"))
|
|
||||||
|
|
||||||
print("block(2,1,3,3) %s" % ("OK" if (block(ref, 2, 1, 3, 3) == ref[2:5, 1:4]).all() else "FAILED"))
|
|
||||||
print("block(1,4,4,2) %s" % ("OK" if (block(ref, 1, 4, 4, 2) == ref[1:, 4:]).all() else "FAILED"))
|
|
||||||
print("block(1,4,3,2) %s" % ("OK" if (block(ref, 1, 4, 3, 2) == ref[1:4, 4:]).all() else "FAILED"))
|
|
||||||
|
|
||||||
print("incr_diag %s" % ("OK" if (incr_diag(7) == np.diag([1,2,3,4,5,6,7])).all() else "FAILED"))
|
|
||||||
|
|
||||||
asymm = np.array([
|
|
||||||
[1, 2, 3, 4],
|
|
||||||
[5, 6, 7, 8],
|
|
||||||
[9, 10,11,12],
|
|
||||||
[13,14,15,16]])
|
|
||||||
symm_lower = np.array(asymm)
|
|
||||||
symm_upper = np.array(asymm)
|
|
||||||
for i in range(4):
|
|
||||||
for j in range(i+1, 4):
|
|
||||||
symm_lower[i,j] = symm_lower[j,i]
|
|
||||||
symm_upper[j,i] = symm_upper[i,j]
|
|
||||||
|
|
||||||
print("symmetric_lower %s" % ("OK" if (symmetric_lower(asymm) == symm_lower).all() else "FAILED"))
|
|
||||||
print("symmetric_upper %s" % ("OK" if (symmetric_upper(asymm) == symm_upper).all() else "FAILED"))
|
|
||||||
|
|
||||||
print(double_col.__doc__)
|
|
||||||
print(double_row.__doc__)
|
|
||||||
print(double_mat_rm.__doc__)
|
|
||||||
print(sparse_passthrough_r.__doc__)
|
|
||||||
print(sparse_passthrough_c.__doc__)
|
|
@ -1,60 +0,0 @@
|
|||||||
should_give_NOT_OK = NOT OK
|
|
||||||
fixed_r = OK
|
|
||||||
fixed_c = OK
|
|
||||||
pt_r(fixed_r) = OK
|
|
||||||
pt_c(fixed_c) = OK
|
|
||||||
pt_r(fixed_c) = OK
|
|
||||||
pt_c(fixed_r) = OK
|
|
||||||
dense_r = OK
|
|
||||||
dense_c = OK
|
|
||||||
pt_r(dense_r) = OK
|
|
||||||
pt_c(dense_c) = OK
|
|
||||||
pt_r(dense_c) = OK
|
|
||||||
pt_c(dense_r) = OK
|
|
||||||
sparse_r = OK
|
|
||||||
sparse_c = OK
|
|
||||||
pt_r(sparse_r) = OK
|
|
||||||
pt_c(sparse_c) = OK
|
|
||||||
pt_r(sparse_c) = OK
|
|
||||||
pt_c(sparse_r) = OK
|
|
||||||
double_row(first_row) = OK
|
|
||||||
double_col(first_row) = OK
|
|
||||||
double_row(first_col) = OK
|
|
||||||
double_col(first_col) = OK
|
|
||||||
double_mat_cm(0) = OK
|
|
||||||
double_mat_rm(0) = OK
|
|
||||||
double_mat_cm(1) = OK
|
|
||||||
double_mat_rm(1) = OK
|
|
||||||
double_mat_cm(2) = OK
|
|
||||||
double_mat_rm(2) = OK
|
|
||||||
cholesky1 OK
|
|
||||||
cholesky2 OK
|
|
||||||
cholesky3 OK
|
|
||||||
cholesky4 OK
|
|
||||||
cholesky5 OK
|
|
||||||
cholesky6 OK
|
|
||||||
diagonal() OK
|
|
||||||
diagonal_1() OK
|
|
||||||
diagonal_n(-5) OK
|
|
||||||
diagonal_n(-4) OK
|
|
||||||
diagonal_n(-3) OK
|
|
||||||
diagonal_n(-2) OK
|
|
||||||
diagonal_n(-1) OK
|
|
||||||
diagonal_n(0) OK
|
|
||||||
diagonal_n(1) OK
|
|
||||||
diagonal_n(2) OK
|
|
||||||
diagonal_n(3) OK
|
|
||||||
diagonal_n(4) OK
|
|
||||||
diagonal_n(5) OK
|
|
||||||
diagonal_n(6) OK
|
|
||||||
block(2,1,3,3) OK
|
|
||||||
block(1,4,4,2) OK
|
|
||||||
block(1,4,3,2) OK
|
|
||||||
incr_diag OK
|
|
||||||
symmetric_lower OK
|
|
||||||
symmetric_upper OK
|
|
||||||
double_col(arg0: numpy.ndarray[float32[m, 1]]) -> numpy.ndarray[float32[m, 1]]
|
|
||||||
double_row(arg0: numpy.ndarray[float32[1, n]]) -> numpy.ndarray[float32[1, n]]
|
|
||||||
double_mat_rm(arg0: numpy.ndarray[float32[m, n]]) -> numpy.ndarray[float32[m, n]]
|
|
||||||
sparse_passthrough_r(arg0: scipy.sparse.csr_matrix[float32]) -> scipy.sparse.csr_matrix[float32]
|
|
||||||
sparse_passthrough_c(arg0: scipy.sparse.csc_matrix[float32]) -> scipy.sparse.csc_matrix[float32]
|
|
@ -1,53 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
import pydoc
|
|
||||||
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import kw_func0, kw_func1, kw_func2, kw_func3, kw_func4, call_kw_func
|
|
||||||
from example import args_function, args_kwargs_function, kw_func_udl, kw_func_udl_z
|
|
||||||
from example import KWClass
|
|
||||||
|
|
||||||
print(pydoc.render_doc(kw_func0, "Help on %s"))
|
|
||||||
print(pydoc.render_doc(kw_func1, "Help on %s"))
|
|
||||||
print(pydoc.render_doc(kw_func2, "Help on %s"))
|
|
||||||
print(pydoc.render_doc(kw_func3, "Help on %s"))
|
|
||||||
print(pydoc.render_doc(kw_func4, "Help on %s"))
|
|
||||||
print(pydoc.render_doc(kw_func_udl, "Help on %s"))
|
|
||||||
print(pydoc.render_doc(kw_func_udl_z, "Help on %s"))
|
|
||||||
print(pydoc.render_doc(args_function, "Help on %s"))
|
|
||||||
print(pydoc.render_doc(args_kwargs_function, "Help on %s"))
|
|
||||||
|
|
||||||
print(KWClass.foo0.__doc__)
|
|
||||||
print(KWClass.foo1.__doc__)
|
|
||||||
|
|
||||||
kw_func1(5, 10)
|
|
||||||
kw_func1(5, y=10)
|
|
||||||
kw_func1(y=10, x=5)
|
|
||||||
|
|
||||||
kw_func2()
|
|
||||||
|
|
||||||
kw_func2(5)
|
|
||||||
kw_func2(x=5)
|
|
||||||
|
|
||||||
kw_func2(y=10)
|
|
||||||
|
|
||||||
kw_func2(5, 10)
|
|
||||||
kw_func2(x=5, y=10)
|
|
||||||
|
|
||||||
try:
|
|
||||||
kw_func2(x=5, y=10, z=12)
|
|
||||||
except Exception as e:
|
|
||||||
print("Caught expected exception: " + str(e))
|
|
||||||
|
|
||||||
kw_func4()
|
|
||||||
kw_func4(myList=[1, 2, 3])
|
|
||||||
|
|
||||||
call_kw_func(kw_func2)
|
|
||||||
|
|
||||||
args_function('arg1_value', 'arg2_value', 3)
|
|
||||||
args_kwargs_function('arg1_value', 'arg2_value', arg3='arg3_value', arg4=4)
|
|
||||||
|
|
||||||
kw_func_udl(x=5, y=10)
|
|
||||||
kw_func_udl_z(x=5)
|
|
@ -1,75 +0,0 @@
|
|||||||
Help on built-in function kw_func0 in module example
|
|
||||||
|
|
||||||
kkww__ffuunncc00(...)
|
|
||||||
kw_func0(arg0: int, arg1: int) -> None
|
|
||||||
|
|
||||||
Help on built-in function kw_func1 in module example
|
|
||||||
|
|
||||||
kkww__ffuunncc11(...)
|
|
||||||
kw_func1(x: int, y: int) -> None
|
|
||||||
|
|
||||||
Help on built-in function kw_func2 in module example
|
|
||||||
|
|
||||||
kkww__ffuunncc22(...)
|
|
||||||
kw_func2(x: int=100L, y: int=200L) -> None
|
|
||||||
|
|
||||||
Help on built-in function kw_func3 in module example
|
|
||||||
|
|
||||||
kkww__ffuunncc33(...)
|
|
||||||
kw_func3(data: unicode=u'Hello world!') -> None
|
|
||||||
|
|
||||||
Help on built-in function kw_func4 in module example
|
|
||||||
|
|
||||||
kkww__ffuunncc44(...)
|
|
||||||
kw_func4(myList: List[int]=[13L, 17L]) -> None
|
|
||||||
|
|
||||||
Help on built-in function kw_func_udl in module example
|
|
||||||
|
|
||||||
kkww__ffuunncc__uuddll(...)
|
|
||||||
kw_func_udl(x: int, y: int=300L) -> None
|
|
||||||
|
|
||||||
Help on built-in function kw_func_udl_z in module example
|
|
||||||
|
|
||||||
kkww__ffuunncc__uuddll__zz(...)
|
|
||||||
kw_func_udl_z(x: int, y: int=0L) -> None
|
|
||||||
|
|
||||||
Help on built-in function args_function in module example
|
|
||||||
|
|
||||||
aarrggss__ffuunnccttiioonn(...)
|
|
||||||
args_function(*args) -> None
|
|
||||||
|
|
||||||
Help on built-in function args_kwargs_function in module example
|
|
||||||
|
|
||||||
aarrggss__kkwwaarrggss__ffuunnccttiioonn(...)
|
|
||||||
args_kwargs_function(*args, **kwargs) -> None
|
|
||||||
|
|
||||||
|
|
||||||
foo0(self: KWClass, arg0: int, arg1: float) -> None
|
|
||||||
foo1(self: KWClass, x: int, y: float) -> None
|
|
||||||
|
|
||||||
|
|
||||||
kw_func(x=5, y=10)
|
|
||||||
kw_func(x=5, y=10)
|
|
||||||
kw_func(x=5, y=10)
|
|
||||||
kw_func(x=100, y=200)
|
|
||||||
kw_func(x=5, y=200)
|
|
||||||
kw_func(x=5, y=200)
|
|
||||||
kw_func(x=100, y=10)
|
|
||||||
kw_func(x=5, y=10)
|
|
||||||
kw_func(x=5, y=10)
|
|
||||||
Caught expected exception: Incompatible function arguments. The following argument types are supported:
|
|
||||||
1. (x: int=100L, y: int=200L) -> None
|
|
||||||
Invoked with:
|
|
||||||
kw_func4: 13 17
|
|
||||||
kw_func4: 1 2 3
|
|
||||||
kw_func(x=1234, y=5678)
|
|
||||||
got argument: arg1_value
|
|
||||||
got argument: arg2_value
|
|
||||||
got argument: 3
|
|
||||||
got argument: arg1_value
|
|
||||||
got argument: arg2_value
|
|
||||||
got keyword argument: arg3 -> arg3_value
|
|
||||||
got keyword argument: arg4 -> 4
|
|
||||||
|
|
||||||
kw_func(x=5, y=10)
|
|
||||||
kw_func(x=5, y=0)
|
|
@ -1,45 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import Matrix
|
|
||||||
|
|
||||||
try:
|
|
||||||
import numpy as np
|
|
||||||
except ImportError:
|
|
||||||
# NumPy missing: skip test
|
|
||||||
exit(99)
|
|
||||||
|
|
||||||
m = Matrix(5, 5)
|
|
||||||
|
|
||||||
print(m[2, 3])
|
|
||||||
m[2, 3] = 4
|
|
||||||
print(m[2, 3])
|
|
||||||
|
|
||||||
m2 = np.array(m, copy=False)
|
|
||||||
print(m2)
|
|
||||||
print(m2[2, 3])
|
|
||||||
m2[2, 3] = 5
|
|
||||||
print(m[2, 3])
|
|
||||||
|
|
||||||
m3 = np.array([[1,2,3],[4,5,6]]).astype(np.float32)
|
|
||||||
print(m3)
|
|
||||||
m4 = Matrix(m3)
|
|
||||||
for i in range(m4.rows()):
|
|
||||||
for j in range(m4.cols()):
|
|
||||||
print(m4[i, j], end = ' ')
|
|
||||||
print()
|
|
||||||
|
|
||||||
from example import ConstructorStats
|
|
||||||
cstats = ConstructorStats.get(Matrix)
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
m = m4 = None
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
m2 = None # m2 holds an m reference
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
print("Constructor values:", cstats.values())
|
|
||||||
print("Copy constructions:", cstats.copy_constructions)
|
|
||||||
#print("Move constructions:", cstats.move_constructions >= 0) # Don't invoke any
|
|
||||||
print("Copy assignments:", cstats.copy_assignments)
|
|
||||||
print("Move assignments:", cstats.move_assignments)
|
|
@ -1,24 +0,0 @@
|
|||||||
### Matrix @ 0x1df1920 created 5x5 matrix
|
|
||||||
0.0
|
|
||||||
4.0
|
|
||||||
[[ 0. 0. 0. 0. 0.]
|
|
||||||
[ 0. 0. 0. 0. 0.]
|
|
||||||
[ 0. 0. 0. 4. 0.]
|
|
||||||
[ 0. 0. 0. 0. 0.]
|
|
||||||
[ 0. 0. 0. 0. 0.]]
|
|
||||||
4.0
|
|
||||||
5.0
|
|
||||||
[[ 1. 2. 3.]
|
|
||||||
[ 4. 5. 6.]]
|
|
||||||
### Matrix @ 0x1fa8cf0 created 2x3 matrix
|
|
||||||
1.0 2.0 3.0
|
|
||||||
4.0 5.0 6.0
|
|
||||||
Instances not destroyed: 2
|
|
||||||
### Matrix @ 0x1fa8cf0 destroyed 2x3 matrix
|
|
||||||
Instances not destroyed: 1
|
|
||||||
### Matrix @ 0x1df1920 destroyed 5x5 matrix
|
|
||||||
Instances not destroyed: 0
|
|
||||||
Constructor values: ['5x5 matrix', '2x3 matrix']
|
|
||||||
Copy constructions: 0
|
|
||||||
Copy assignments: 0
|
|
||||||
Move assignments: 0
|
|
@ -1,95 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
from functools import partial
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import Pet
|
|
||||||
from example import Dog
|
|
||||||
from example import Rabbit
|
|
||||||
from example import dog_bark
|
|
||||||
from example import pet_print
|
|
||||||
|
|
||||||
polly = Pet('Polly', 'parrot')
|
|
||||||
molly = Dog('Molly')
|
|
||||||
roger = Rabbit('Rabbit')
|
|
||||||
print(roger.name() + " is a " + roger.species())
|
|
||||||
pet_print(roger)
|
|
||||||
print(polly.name() + " is a " + polly.species())
|
|
||||||
pet_print(polly)
|
|
||||||
print(molly.name() + " is a " + molly.species())
|
|
||||||
pet_print(molly)
|
|
||||||
dog_bark(molly)
|
|
||||||
try:
|
|
||||||
dog_bark(polly)
|
|
||||||
except Exception as e:
|
|
||||||
print('The following error is expected: ' + str(e))
|
|
||||||
|
|
||||||
from example import test_callback1
|
|
||||||
from example import test_callback2
|
|
||||||
from example import test_callback3
|
|
||||||
from example import test_callback4
|
|
||||||
from example import test_callback5
|
|
||||||
from example import test_cleanup
|
|
||||||
|
|
||||||
def func1():
|
|
||||||
print('Callback function 1 called!')
|
|
||||||
|
|
||||||
def func2(a, b, c, d):
|
|
||||||
print('Callback function 2 called : ' + str(a) + ", " + str(b) + ", " + str(c) + ", "+ str(d))
|
|
||||||
return d
|
|
||||||
|
|
||||||
def func3(a):
|
|
||||||
print('Callback function 3 called : ' + str(a))
|
|
||||||
|
|
||||||
print(test_callback1(func1))
|
|
||||||
print(test_callback2(func2))
|
|
||||||
print(test_callback1(partial(func2, "Hello", "from", "partial", "object")))
|
|
||||||
print(test_callback1(partial(func3, "Partial object with one argument")))
|
|
||||||
|
|
||||||
test_callback3(lambda i: i + 1)
|
|
||||||
f = test_callback4()
|
|
||||||
print("func(43) = %i" % f(43))
|
|
||||||
f = test_callback5()
|
|
||||||
print("func(number=43) = %i" % f(number=43))
|
|
||||||
|
|
||||||
test_cleanup()
|
|
||||||
|
|
||||||
from example import payload_cstats
|
|
||||||
cstats = payload_cstats()
|
|
||||||
print("Payload instances not destroyed:", cstats.alive())
|
|
||||||
print("Copy constructions:", cstats.copy_constructions)
|
|
||||||
print("Move constructions:", cstats.move_constructions >= 1)
|
|
||||||
|
|
||||||
from example import dummy_function
|
|
||||||
from example import dummy_function2
|
|
||||||
from example import test_dummy_function
|
|
||||||
from example import roundtrip
|
|
||||||
|
|
||||||
test_dummy_function(dummy_function)
|
|
||||||
test_dummy_function(roundtrip(dummy_function))
|
|
||||||
if roundtrip(None) is not None:
|
|
||||||
print("Problem!")
|
|
||||||
test_dummy_function(lambda x: x + 2)
|
|
||||||
|
|
||||||
try:
|
|
||||||
test_dummy_function(dummy_function2)
|
|
||||||
print("Problem!")
|
|
||||||
except Exception as e:
|
|
||||||
if 'Incompatible function arguments' in str(e):
|
|
||||||
print("All OK!")
|
|
||||||
else:
|
|
||||||
print("Problem!")
|
|
||||||
|
|
||||||
try:
|
|
||||||
test_dummy_function(lambda x, y: x + y)
|
|
||||||
print("Problem!")
|
|
||||||
except Exception as e:
|
|
||||||
if 'missing 1 required positional argument' in str(e) or \
|
|
||||||
'takes exactly 2 arguments' in str(e):
|
|
||||||
print("All OK!")
|
|
||||||
else:
|
|
||||||
print("Problem!")
|
|
||||||
|
|
||||||
print(test_callback3.__doc__)
|
|
||||||
print(test_callback4.__doc__)
|
|
@ -1,46 +0,0 @@
|
|||||||
Rabbit is a parrot
|
|
||||||
Rabbit is a parrot
|
|
||||||
Polly is a parrot
|
|
||||||
Polly is a parrot
|
|
||||||
Molly is a dog
|
|
||||||
Molly is a dog
|
|
||||||
Woof!
|
|
||||||
The following error is expected: Incompatible function arguments. The following argument types are supported:
|
|
||||||
1. (arg0: example.Dog) -> None
|
|
||||||
Invoked with: <example.Pet object at 0x7ffaf4b00db0>
|
|
||||||
Callback function 1 called!
|
|
||||||
False
|
|
||||||
Callback function 2 called : Hello, x, True, 5
|
|
||||||
5
|
|
||||||
Callback function 2 called : Hello, from, partial, object
|
|
||||||
False
|
|
||||||
Callback function 3 called : Partial object with one argument
|
|
||||||
False
|
|
||||||
func(43) = 44
|
|
||||||
func(43) = 44
|
|
||||||
func(number=43) = 44
|
|
||||||
### Payload @ 0x7ffdcee09c80 created via default constructor
|
|
||||||
### Payload @ 0x7ffdcee09c88 created via copy constructor
|
|
||||||
### Payload @ 0xb54500 created via move constructor
|
|
||||||
### Payload @ 0x7ffdcee09c88 destroyed
|
|
||||||
### Payload @ 0x7ffdcee09c80 destroyed
|
|
||||||
### Payload @ 0xb54500 destroyed
|
|
||||||
Payload instances not destroyed: 0
|
|
||||||
Copy constructions: 1
|
|
||||||
Move constructions: True
|
|
||||||
argument matches dummy_function
|
|
||||||
eval(1) = 2
|
|
||||||
roundtrip (got None)..
|
|
||||||
roundtrip..
|
|
||||||
argument matches dummy_function
|
|
||||||
eval(1) = 2
|
|
||||||
could not convert to a function pointer.
|
|
||||||
eval(1) = 3
|
|
||||||
could not convert to a function pointer.
|
|
||||||
All OK!
|
|
||||||
could not convert to a function pointer.
|
|
||||||
All OK!
|
|
||||||
test_callback3(arg0: Callable[[int], int]) -> None
|
|
||||||
|
|
||||||
test_callback4() -> Callable[[int], int]
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
example/example-constants-and-functions.cpp -- global constants and functions, enumerations, raw byte strings
|
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
|
||||||
|
|
||||||
All rights reserved. Use of this source code is governed by a
|
|
||||||
BSD-style license that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "example.h"
|
|
||||||
|
|
||||||
enum EMyEnumeration {
|
|
||||||
EFirstEntry = 1,
|
|
||||||
ESecondEntry
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ECMyEnum {
|
|
||||||
Two = 2,
|
|
||||||
Three
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExampleWithEnum {
|
|
||||||
public:
|
|
||||||
enum EMode {
|
|
||||||
EFirstMode = 1,
|
|
||||||
ESecondMode
|
|
||||||
};
|
|
||||||
|
|
||||||
static EMode test_function(EMode mode) {
|
|
||||||
std::cout << "ExampleWithEnum::test_function(enum=" << mode << ")" << std::endl;
|
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool test_function1() {
|
|
||||||
std::cout << "test_function()" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_function2(EMyEnumeration k) {
|
|
||||||
std::cout << "test_function(enum=" << k << ")" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
float test_function3(int i) {
|
|
||||||
std::cout << "test_function(" << i << ")" << std::endl;
|
|
||||||
return (float) i / 2.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_ecenum(ECMyEnum z) {
|
|
||||||
std::cout << "test_ecenum(ECMyEnum::" << (z == ECMyEnum::Two ? "Two" : "Three") << ")" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
py::bytes return_bytes() {
|
|
||||||
const char *data = "\x01\x00\x02\x00";
|
|
||||||
return std::string(data, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_bytes(py::bytes bytes) {
|
|
||||||
std::string value = (std::string) bytes;
|
|
||||||
for (size_t i = 0; i < value.length(); ++i)
|
|
||||||
std::cout << "bytes[" << i << "]=" << (int) value[i] << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_ex_constants_and_functions(py::module &m) {
|
|
||||||
m.def("test_function", &test_function1);
|
|
||||||
m.def("test_function", &test_function2);
|
|
||||||
m.def("test_function", &test_function3);
|
|
||||||
m.def("test_ecenum", &test_ecenum);
|
|
||||||
m.attr("some_constant") = py::int_(14);
|
|
||||||
|
|
||||||
py::enum_<EMyEnumeration>(m, "EMyEnumeration")
|
|
||||||
.value("EFirstEntry", EFirstEntry)
|
|
||||||
.value("ESecondEntry", ESecondEntry)
|
|
||||||
.export_values();
|
|
||||||
|
|
||||||
py::enum_<ECMyEnum>(m, "ECMyEnum")
|
|
||||||
.value("Two", ECMyEnum::Two)
|
|
||||||
.value("Three", ECMyEnum::Three)
|
|
||||||
;
|
|
||||||
|
|
||||||
py::class_<ExampleWithEnum> exenum_class(m, "ExampleWithEnum");
|
|
||||||
exenum_class.def_static("test_function", &ExampleWithEnum::test_function);
|
|
||||||
py::enum_<ExampleWithEnum::EMode>(exenum_class, "EMode")
|
|
||||||
.value("EFirstMode", ExampleWithEnum::EFirstMode)
|
|
||||||
.value("ESecondMode", ExampleWithEnum::ESecondMode)
|
|
||||||
.export_values();
|
|
||||||
|
|
||||||
m.def("return_bytes", &return_bytes);
|
|
||||||
m.def("print_bytes", &print_bytes);
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import test_function
|
|
||||||
from example import some_constant
|
|
||||||
from example import EMyEnumeration
|
|
||||||
from example import ECMyEnum, test_ecenum
|
|
||||||
from example import EFirstEntry
|
|
||||||
from example import ExampleWithEnum
|
|
||||||
from example import return_bytes
|
|
||||||
from example import print_bytes
|
|
||||||
|
|
||||||
print(EMyEnumeration)
|
|
||||||
print(EMyEnumeration.EFirstEntry)
|
|
||||||
print(EMyEnumeration.ESecondEntry)
|
|
||||||
print(EFirstEntry)
|
|
||||||
|
|
||||||
print(test_function())
|
|
||||||
print(test_function(7))
|
|
||||||
print(test_function(EMyEnumeration.EFirstEntry))
|
|
||||||
print(test_function(EMyEnumeration.ESecondEntry))
|
|
||||||
test_ecenum(ECMyEnum.Three)
|
|
||||||
z = ECMyEnum.Two
|
|
||||||
test_ecenum(z)
|
|
||||||
try:
|
|
||||||
z == 2
|
|
||||||
print("Bad: expected a TypeError exception")
|
|
||||||
except TypeError:
|
|
||||||
try:
|
|
||||||
z != 3
|
|
||||||
print("Bad: expected a TypeError exception")
|
|
||||||
except TypeError:
|
|
||||||
print("Good: caught expected TypeError exceptions for scoped enum ==/!= int comparisons")
|
|
||||||
|
|
||||||
y = EMyEnumeration.ESecondEntry
|
|
||||||
try:
|
|
||||||
y == 2
|
|
||||||
y != 2
|
|
||||||
print("Good: no TypeError exception for unscoped enum ==/!= int comparisions")
|
|
||||||
except TypeError:
|
|
||||||
print("Bad: caught TypeError exception for unscoped enum ==/!= int comparisons")
|
|
||||||
|
|
||||||
print("enum->integer = %i" % int(EMyEnumeration.ESecondEntry))
|
|
||||||
print("integer->enum = %s" % str(EMyEnumeration(2)))
|
|
||||||
|
|
||||||
print("A constant = " + str(some_constant))
|
|
||||||
|
|
||||||
print(ExampleWithEnum.EMode)
|
|
||||||
print(ExampleWithEnum.EMode.EFirstMode)
|
|
||||||
print(ExampleWithEnum.EFirstMode)
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode)
|
|
||||||
|
|
||||||
print("Equality test 1: " + str(
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode) ==
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode)))
|
|
||||||
|
|
||||||
print("Inequality test 1: " + str(
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode) !=
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode)))
|
|
||||||
|
|
||||||
print("Equality test 2: " + str(
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode) ==
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.ESecondMode)))
|
|
||||||
|
|
||||||
print("Inequality test 2: " + str(
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode) !=
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.ESecondMode)))
|
|
||||||
|
|
||||||
print("Equality test 3: " + str(
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode) ==
|
|
||||||
int(ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode))))
|
|
||||||
|
|
||||||
print("Inequality test 3: " + str(
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode) !=
|
|
||||||
int(ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode))))
|
|
||||||
|
|
||||||
print("Equality test 4: " + str(
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode) ==
|
|
||||||
int(ExampleWithEnum.test_function(ExampleWithEnum.ESecondMode))))
|
|
||||||
|
|
||||||
print("Inequality test 4: " + str(
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode) !=
|
|
||||||
int(ExampleWithEnum.test_function(ExampleWithEnum.ESecondMode))))
|
|
||||||
|
|
||||||
x = {
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode): 1,
|
|
||||||
ExampleWithEnum.test_function(ExampleWithEnum.ESecondMode): 2
|
|
||||||
}
|
|
||||||
|
|
||||||
x[ExampleWithEnum.test_function(ExampleWithEnum.EFirstMode)] = 3
|
|
||||||
x[ExampleWithEnum.test_function(ExampleWithEnum.ESecondMode)] = 4
|
|
||||||
print("Hashing test = " + str(x))
|
|
||||||
|
|
||||||
print_bytes(return_bytes())
|
|
@ -1,56 +0,0 @@
|
|||||||
<class 'example.EMyEnumeration'>
|
|
||||||
EMyEnumeration.EFirstEntry
|
|
||||||
EMyEnumeration.ESecondEntry
|
|
||||||
EMyEnumeration.EFirstEntry
|
|
||||||
test_function()
|
|
||||||
False
|
|
||||||
test_function(7)
|
|
||||||
3.5
|
|
||||||
test_function(enum=1)
|
|
||||||
None
|
|
||||||
test_function(enum=2)
|
|
||||||
None
|
|
||||||
test_ecenum(ECMyEnum::Three)
|
|
||||||
test_ecenum(ECMyEnum::Two)
|
|
||||||
Good: caught expected TypeError exceptions for scoped enum ==/!= int comparisons
|
|
||||||
Good: no TypeError exception for unscoped enum ==/!= int comparisions
|
|
||||||
enum->integer = 2
|
|
||||||
integer->enum = EMyEnumeration.ESecondEntry
|
|
||||||
A constant = 14
|
|
||||||
<class 'example.EMode'>
|
|
||||||
EMode.EFirstMode
|
|
||||||
EMode.EFirstMode
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
Equality test 1: True
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
Inequality test 1: False
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
ExampleWithEnum::test_function(enum=2)
|
|
||||||
Equality test 2: False
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
ExampleWithEnum::test_function(enum=2)
|
|
||||||
Inequality test 2: True
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
Equality test 3: True
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
Inequality test 3: False
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
ExampleWithEnum::test_function(enum=2)
|
|
||||||
Equality test 4: False
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
ExampleWithEnum::test_function(enum=2)
|
|
||||||
Inequality test 4: True
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
ExampleWithEnum::test_function(enum=2)
|
|
||||||
ExampleWithEnum::test_function(enum=1)
|
|
||||||
ExampleWithEnum::test_function(enum=2)
|
|
||||||
Hashing test = {EMode.EFirstMode: 3, EMode.ESecondMode: 4}
|
|
||||||
bytes[0]=1
|
|
||||||
bytes[1]=0
|
|
||||||
bytes[2]=2
|
|
||||||
bytes[3]=0
|
|
@ -1,42 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
import example
|
|
||||||
|
|
||||||
print("Can we catch a MyException?")
|
|
||||||
try:
|
|
||||||
example.throws1()
|
|
||||||
except example.MyException as e:
|
|
||||||
print(e.__class__.__name__, ":", e)
|
|
||||||
print("")
|
|
||||||
|
|
||||||
print("Can we translate to standard Python exceptions?")
|
|
||||||
try:
|
|
||||||
example.throws2()
|
|
||||||
except Exception as e:
|
|
||||||
print(e.__class__.__name__, ":", e)
|
|
||||||
print("")
|
|
||||||
|
|
||||||
print("Can we handle unknown exceptions?")
|
|
||||||
try:
|
|
||||||
example.throws3()
|
|
||||||
except Exception as e:
|
|
||||||
print(e.__class__.__name__, ":", e)
|
|
||||||
print("")
|
|
||||||
|
|
||||||
print("Can we delegate to another handler by rethrowing?")
|
|
||||||
try:
|
|
||||||
example.throws4()
|
|
||||||
except example.MyException as e:
|
|
||||||
print(e.__class__.__name__, ":", e)
|
|
||||||
print("")
|
|
||||||
|
|
||||||
print("Can we fall-through to the default handler?")
|
|
||||||
try:
|
|
||||||
example.throws_logic_error()
|
|
||||||
except Exception as e:
|
|
||||||
print(e.__class__.__name__, ":", e)
|
|
||||||
print("")
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
|||||||
Can we catch a MyException?
|
|
||||||
MyException : this error should go to a custom type
|
|
||||||
|
|
||||||
Can we translate to standard Python exceptions?
|
|
||||||
RuntimeError : this error should go to a standard Python exception
|
|
||||||
|
|
||||||
Can we handle unknown exceptions?
|
|
||||||
RuntimeError : Caught an unknown exception!
|
|
||||||
|
|
||||||
Can we delegate to another handler by rethrowing?
|
|
||||||
MyException : this error is rethrown
|
|
||||||
|
|
||||||
Can we fall-through to the default handler?
|
|
||||||
RuntimeError : this error should fall through to the standard handler
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
|||||||
/*
|
|
||||||
example/example-eval.cpp -- Usage of eval() and eval_file()
|
|
||||||
|
|
||||||
Copyright (c) 2016 Klemens D. Morgenstern
|
|
||||||
|
|
||||||
All rights reserved. Use of this source code is governed by a
|
|
||||||
BSD-style license that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <pybind11/eval.h>
|
|
||||||
#include "example.h"
|
|
||||||
|
|
||||||
void example_eval() {
|
|
||||||
py::module main_module = py::module::import("__main__");
|
|
||||||
py::object main_namespace = main_module.attr("__dict__");
|
|
||||||
|
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
main_module.def("call_test", [&]() -> int {
|
|
||||||
ok = true;
|
|
||||||
return 42;
|
|
||||||
});
|
|
||||||
|
|
||||||
cout << "eval_statements test" << endl;
|
|
||||||
|
|
||||||
auto result = py::eval<py::eval_statements>(
|
|
||||||
"print('Hello World!');\n"
|
|
||||||
"x = call_test();", main_namespace);
|
|
||||||
|
|
||||||
if (ok && result == py::none())
|
|
||||||
cout << "eval_statements passed" << endl;
|
|
||||||
else
|
|
||||||
cout << "eval_statements failed" << endl;
|
|
||||||
|
|
||||||
cout << "eval test" << endl;
|
|
||||||
|
|
||||||
py::object val = py::eval("x", main_namespace);
|
|
||||||
|
|
||||||
if (val.cast<int>() == 42)
|
|
||||||
cout << "eval passed" << endl;
|
|
||||||
else
|
|
||||||
cout << "eval failed" << endl;
|
|
||||||
|
|
||||||
ok = false;
|
|
||||||
cout << "eval_single_statement test" << endl;
|
|
||||||
|
|
||||||
py::eval<py::eval_single_statement>(
|
|
||||||
"y = call_test();", main_namespace);
|
|
||||||
|
|
||||||
if (ok)
|
|
||||||
cout << "eval_single_statement passed" << endl;
|
|
||||||
else
|
|
||||||
cout << "eval_single_statement failed" << endl;
|
|
||||||
|
|
||||||
cout << "eval_file test" << endl;
|
|
||||||
|
|
||||||
int val_out;
|
|
||||||
main_module.def("call_test2", [&](int value) {val_out = value;});
|
|
||||||
|
|
||||||
try {
|
|
||||||
result = py::eval_file("example-eval_call.py", main_namespace);
|
|
||||||
} catch (...) {
|
|
||||||
result = py::eval_file("example/example-eval_call.py", main_namespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val_out == 42 && result == py::none())
|
|
||||||
cout << "eval_file passed" << endl;
|
|
||||||
else
|
|
||||||
cout << "eval_file failed" << endl;
|
|
||||||
|
|
||||||
ok = false;
|
|
||||||
cout << "eval failure test" << endl;
|
|
||||||
try {
|
|
||||||
py::eval("nonsense code ...");
|
|
||||||
} catch (py::error_already_set &) {
|
|
||||||
PyErr_Clear();
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok)
|
|
||||||
cout << "eval failure test passed" << endl;
|
|
||||||
else
|
|
||||||
cout << "eval failure test failed" << endl;
|
|
||||||
|
|
||||||
ok = false;
|
|
||||||
cout << "eval_file failure test" << endl;
|
|
||||||
try {
|
|
||||||
py::eval_file("nonexisting file");
|
|
||||||
} catch (std::exception &) {
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok)
|
|
||||||
cout << "eval_file failure test passed" << endl;
|
|
||||||
else
|
|
||||||
cout << "eval_file failure test failed" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_ex_eval(py::module & m) {
|
|
||||||
m.def("example_eval", &example_eval);
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
from example import example_eval
|
|
||||||
|
|
||||||
example_eval()
|
|
||||||
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
eval_statements test
|
|
||||||
eval_statements passed
|
|
||||||
eval test
|
|
||||||
eval passed
|
|
||||||
eval_single_statement test
|
|
||||||
eval_single_statement passed
|
|
||||||
eval_file test
|
|
||||||
eval_file passed
|
|
||||||
eval failure test
|
|
||||||
eval failure test passed
|
|
||||||
eval_file failure test
|
|
||||||
eval_file failure test passed
|
|
||||||
Hello World!
|
|
@ -1 +0,0 @@
|
|||||||
call_test2(y)
|
|
@ -1,12 +0,0 @@
|
|||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import return_class_1
|
|
||||||
from example import return_class_2
|
|
||||||
from example import return_none
|
|
||||||
|
|
||||||
print(type(return_class_1()).__name__)
|
|
||||||
print(type(return_class_2()).__name__)
|
|
||||||
print(type(return_none()).__name__)
|
|
@ -1,3 +0,0 @@
|
|||||||
DerivedClass1
|
|
||||||
DerivedClass2
|
|
||||||
NoneType
|
|
@ -1,67 +0,0 @@
|
|||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
import gc
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import Parent, Child
|
|
||||||
|
|
||||||
if True:
|
|
||||||
p = Parent()
|
|
||||||
p.addChild(Child())
|
|
||||||
gc.collect()
|
|
||||||
print(p)
|
|
||||||
p = None
|
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
print("")
|
|
||||||
|
|
||||||
if True:
|
|
||||||
p = Parent()
|
|
||||||
p.returnChild()
|
|
||||||
gc.collect()
|
|
||||||
print(p)
|
|
||||||
p = None
|
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
print("")
|
|
||||||
|
|
||||||
if True:
|
|
||||||
p = Parent()
|
|
||||||
p.addChildKeepAlive(Child())
|
|
||||||
gc.collect()
|
|
||||||
print(p)
|
|
||||||
p = None
|
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
print("")
|
|
||||||
|
|
||||||
if True:
|
|
||||||
p = Parent()
|
|
||||||
p.returnChildKeepAlive()
|
|
||||||
gc.collect()
|
|
||||||
print(p)
|
|
||||||
p = None
|
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
print("")
|
|
||||||
|
|
||||||
if True:
|
|
||||||
p = Parent()
|
|
||||||
p.returnNullChildKeepAliveChild()
|
|
||||||
gc.collect()
|
|
||||||
print(p)
|
|
||||||
p = None
|
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
print("")
|
|
||||||
|
|
||||||
if True:
|
|
||||||
p = Parent()
|
|
||||||
p.returnNullChildKeepAliveParent()
|
|
||||||
gc.collect()
|
|
||||||
print(p)
|
|
||||||
p = None
|
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
print("")
|
|
||||||
print("Terminating..")
|
|
@ -1,33 +0,0 @@
|
|||||||
Allocating parent.
|
|
||||||
Allocating child.
|
|
||||||
Releasing child.
|
|
||||||
<example.Parent object at 0x10eb726c0>
|
|
||||||
Releasing parent.
|
|
||||||
|
|
||||||
Allocating parent.
|
|
||||||
Allocating child.
|
|
||||||
Releasing child.
|
|
||||||
<example.Parent object at 0x10eb726c0>
|
|
||||||
Releasing parent.
|
|
||||||
|
|
||||||
Allocating parent.
|
|
||||||
Allocating child.
|
|
||||||
<example.Parent object at 0x10eb726c0>
|
|
||||||
Releasing parent.
|
|
||||||
Releasing child.
|
|
||||||
|
|
||||||
Allocating parent.
|
|
||||||
Allocating child.
|
|
||||||
<example.Parent object at 0x10eb726c0>
|
|
||||||
Releasing parent.
|
|
||||||
Releasing child.
|
|
||||||
|
|
||||||
Allocating parent.
|
|
||||||
<example.Parent object at 0x10eb726c0>
|
|
||||||
Releasing parent.
|
|
||||||
|
|
||||||
Allocating parent.
|
|
||||||
<example.Parent object at 0x10eb726c0>
|
|
||||||
Releasing parent.
|
|
||||||
|
|
||||||
Terminating..
|
|
@ -1,50 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import ExampleMandA
|
|
||||||
|
|
||||||
instance1 = ExampleMandA()
|
|
||||||
instance2 = ExampleMandA(32)
|
|
||||||
instance1.add1(instance2)
|
|
||||||
instance1.add2(instance2)
|
|
||||||
instance1.add3(instance2)
|
|
||||||
instance1.add4(instance2)
|
|
||||||
instance1.add5(instance2)
|
|
||||||
instance1.add6(32)
|
|
||||||
instance1.add7(32)
|
|
||||||
instance1.add8(32)
|
|
||||||
instance1.add9(32)
|
|
||||||
instance1.add10(32)
|
|
||||||
|
|
||||||
print("Instance 1: " + str(instance1))
|
|
||||||
print("Instance 2: " + str(instance2))
|
|
||||||
|
|
||||||
print(instance1.self1())
|
|
||||||
print(instance1.self2())
|
|
||||||
print(instance1.self3())
|
|
||||||
print(instance1.self4())
|
|
||||||
print(instance1.self5())
|
|
||||||
print(instance1.internal1())
|
|
||||||
print(instance1.internal2())
|
|
||||||
print(instance1.internal3())
|
|
||||||
print(instance1.internal4())
|
|
||||||
print(instance1.internal5())
|
|
||||||
|
|
||||||
print("Instance 1, direct access = %i" % instance1.value)
|
|
||||||
instance1.value = 100
|
|
||||||
print("Instance 1: " + str(instance1))
|
|
||||||
|
|
||||||
from example import ConstructorStats
|
|
||||||
|
|
||||||
cstats = ConstructorStats.get(ExampleMandA)
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
instance1 = instance2 = None
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
print("Constructor values:", cstats.values())
|
|
||||||
print("Default constructions:", cstats.default_constructions)
|
|
||||||
print("Copy constructions:", cstats.copy_constructions)
|
|
||||||
print("Move constructions:", cstats.move_constructions >= 1)
|
|
||||||
print("Copy assignments:", cstats.copy_assignments)
|
|
||||||
print("Move assignments:", cstats.move_assignments)
|
|
@ -1,34 +0,0 @@
|
|||||||
### ExampleMandA @ 0x2801910 created via default constructor
|
|
||||||
### ExampleMandA @ 0x27fa780 created 32
|
|
||||||
### ExampleMandA @ 0x7fff80a98a74 created via copy constructor
|
|
||||||
### ExampleMandA @ 0x7fff80a98a78 created via copy constructor
|
|
||||||
### ExampleMandA @ 0x7fff80a98a78 destroyed
|
|
||||||
### ExampleMandA @ 0x7fff80a98a74 destroyed
|
|
||||||
Instance 1: ExampleMandA[value=320]
|
|
||||||
Instance 2: ExampleMandA[value=32]
|
|
||||||
### ExampleMandA @ 0x7fff80a98a84 created via copy constructor
|
|
||||||
### ExampleMandA @ 0x2801fd0 created via move constructor
|
|
||||||
### ExampleMandA @ 0x7fff80a98a84 destroyed
|
|
||||||
ExampleMandA[value=320]
|
|
||||||
### ExampleMandA @ 0x2801fd0 destroyed
|
|
||||||
ExampleMandA[value=320]
|
|
||||||
ExampleMandA[value=320]
|
|
||||||
ExampleMandA[value=320]
|
|
||||||
ExampleMandA[value=320]
|
|
||||||
320
|
|
||||||
320
|
|
||||||
320
|
|
||||||
320
|
|
||||||
320
|
|
||||||
Instance 1, direct access = 320
|
|
||||||
Instance 1: ExampleMandA[value=100]
|
|
||||||
Instances not destroyed: 2
|
|
||||||
### ExampleMandA @ 0x2801910 destroyed
|
|
||||||
### ExampleMandA @ 0x27fa780 destroyed
|
|
||||||
Instances not destroyed: 0
|
|
||||||
Constructor values: ['32']
|
|
||||||
Default constructions: 1
|
|
||||||
Copy constructions: 3
|
|
||||||
Move constructions: True
|
|
||||||
Copy assignments: 0
|
|
||||||
Move assignments: 0
|
|
@ -1,43 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
import example
|
|
||||||
|
|
||||||
print(example.__name__)
|
|
||||||
print(example.submodule.__name__)
|
|
||||||
|
|
||||||
from example.submodule import *
|
|
||||||
from example import OD
|
|
||||||
|
|
||||||
submodule_func()
|
|
||||||
|
|
||||||
b = B()
|
|
||||||
print(b.get_a1())
|
|
||||||
print(b.a1)
|
|
||||||
print(b.get_a2())
|
|
||||||
print(b.a2)
|
|
||||||
|
|
||||||
b.a1 = A(42)
|
|
||||||
b.a2 = A(43)
|
|
||||||
|
|
||||||
print(b.get_a1())
|
|
||||||
print(b.a1)
|
|
||||||
print(b.get_a2())
|
|
||||||
print(b.a2)
|
|
||||||
|
|
||||||
print(OD([(1, 'a'), (2, 'b')]))
|
|
||||||
|
|
||||||
from example import ConstructorStats
|
|
||||||
|
|
||||||
cstats = [ConstructorStats.get(A), ConstructorStats.get(B)]
|
|
||||||
print("Instances not destroyed:", [x.alive() for x in cstats])
|
|
||||||
b = None
|
|
||||||
print("Instances not destroyed:", [x.alive() for x in cstats])
|
|
||||||
print("Constructor values:", [x.values() for x in cstats])
|
|
||||||
print("Default constructions:", [x.default_constructions for x in cstats])
|
|
||||||
print("Copy constructions:", [x.copy_constructions for x in cstats])
|
|
||||||
#print("Move constructions:", [x.move_constructions >= 0 for x in cstats]) # Don't invoke any
|
|
||||||
print("Copy assignments:", [x.copy_assignments for x in cstats])
|
|
||||||
print("Move assignments:", [x.move_assignments for x in cstats])
|
|
@ -1,31 +0,0 @@
|
|||||||
example
|
|
||||||
example.submodule
|
|
||||||
submodule_func()
|
|
||||||
### A @ 0x21a5bc0 created 1
|
|
||||||
### A @ 0x21a5bc4 created 2
|
|
||||||
### B @ 0x21a5bc0 created via default constructor
|
|
||||||
A[1]
|
|
||||||
A[1]
|
|
||||||
A[2]
|
|
||||||
A[2]
|
|
||||||
### A @ 0x20f93b0 created 42
|
|
||||||
### A @ 0x21a5bc0 assigned via copy assignment
|
|
||||||
### A @ 0x20f93b0 destroyed
|
|
||||||
### A @ 0x20f93d0 created 43
|
|
||||||
### A @ 0x21a5bc4 assigned via copy assignment
|
|
||||||
### A @ 0x20f93d0 destroyed
|
|
||||||
A[42]
|
|
||||||
A[42]
|
|
||||||
A[43]
|
|
||||||
A[43]
|
|
||||||
OrderedDict([(1, 'a'), (2, 'b')])
|
|
||||||
Instances not destroyed: [2, 1]
|
|
||||||
### B @ 0x21a5bc0 destroyed
|
|
||||||
### A @ 0x21a5bc4 destroyed
|
|
||||||
### A @ 0x21a5bc0 destroyed
|
|
||||||
Instances not destroyed: [0, 0]
|
|
||||||
Constructor values: [['1', '2', '42', '43'], []]
|
|
||||||
Default constructions: [0, 1]
|
|
||||||
Copy constructions: [0, 0]
|
|
||||||
Copy assignments: [2, 0]
|
|
||||||
Move assignments: [0, 0]
|
|
@ -1,102 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
from example import (
|
|
||||||
create_rec_simple, create_rec_packed, create_rec_nested, print_format_descriptors,
|
|
||||||
print_rec_simple, print_rec_packed, print_rec_nested, print_dtypes, get_format_unbound,
|
|
||||||
create_rec_partial, create_rec_partial_nested, create_string_array, print_string_array,
|
|
||||||
test_array_ctors, test_dtype_ctors, test_dtype_methods
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def check_eq(arr, data, dtype):
|
|
||||||
np.testing.assert_equal(arr, np.array(data, dtype=dtype))
|
|
||||||
|
|
||||||
try:
|
|
||||||
get_format_unbound()
|
|
||||||
raise Exception
|
|
||||||
except RuntimeError as e:
|
|
||||||
assert 'unsupported buffer format' in str(e)
|
|
||||||
|
|
||||||
print_format_descriptors()
|
|
||||||
print_dtypes()
|
|
||||||
|
|
||||||
simple_dtype = np.dtype({'names': ['x', 'y', 'z'],
|
|
||||||
'formats': ['?', 'u4', 'f4'],
|
|
||||||
'offsets': [0, 4, 8]})
|
|
||||||
packed_dtype = np.dtype([('x', '?'), ('y', 'u4'), ('z', 'f4')])
|
|
||||||
|
|
||||||
elements = [(False, 0, 0.0), (True, 1, 1.5), (False, 2, 3.0)]
|
|
||||||
|
|
||||||
for func, dtype in [(create_rec_simple, simple_dtype), (create_rec_packed, packed_dtype)]:
|
|
||||||
arr = func(0)
|
|
||||||
assert arr.dtype == dtype
|
|
||||||
check_eq(arr, [], simple_dtype)
|
|
||||||
check_eq(arr, [], packed_dtype)
|
|
||||||
|
|
||||||
arr = func(3)
|
|
||||||
assert arr.dtype == dtype
|
|
||||||
check_eq(arr, elements, simple_dtype)
|
|
||||||
check_eq(arr, elements, packed_dtype)
|
|
||||||
|
|
||||||
if dtype == simple_dtype:
|
|
||||||
print_rec_simple(arr)
|
|
||||||
else:
|
|
||||||
print_rec_packed(arr)
|
|
||||||
|
|
||||||
arr = create_rec_partial(3)
|
|
||||||
print(arr.dtype)
|
|
||||||
partial_dtype = arr.dtype
|
|
||||||
assert '' not in arr.dtype.fields
|
|
||||||
assert partial_dtype.itemsize > simple_dtype.itemsize
|
|
||||||
check_eq(arr, elements, simple_dtype)
|
|
||||||
check_eq(arr, elements, packed_dtype)
|
|
||||||
|
|
||||||
arr = create_rec_partial_nested(3)
|
|
||||||
print(arr.dtype)
|
|
||||||
assert '' not in arr.dtype.fields
|
|
||||||
assert '' not in arr.dtype.fields['a'][0].fields
|
|
||||||
assert arr.dtype.itemsize > partial_dtype.itemsize
|
|
||||||
np.testing.assert_equal(arr['a'], create_rec_partial(3))
|
|
||||||
|
|
||||||
nested_dtype = np.dtype([('a', simple_dtype), ('b', packed_dtype)])
|
|
||||||
|
|
||||||
arr = create_rec_nested(0)
|
|
||||||
assert arr.dtype == nested_dtype
|
|
||||||
check_eq(arr, [], nested_dtype)
|
|
||||||
|
|
||||||
arr = create_rec_nested(3)
|
|
||||||
assert arr.dtype == nested_dtype
|
|
||||||
check_eq(arr, [((False, 0, 0.0), (True, 1, 1.5)),
|
|
||||||
((True, 1, 1.5), (False, 2, 3.0)),
|
|
||||||
((False, 2, 3.0), (True, 3, 4.5))], nested_dtype)
|
|
||||||
print_rec_nested(arr)
|
|
||||||
|
|
||||||
assert create_rec_nested.__doc__.strip().endswith('numpy.ndarray[NestedStruct]')
|
|
||||||
|
|
||||||
arr = create_string_array(True)
|
|
||||||
print(arr.dtype)
|
|
||||||
print_string_array(arr)
|
|
||||||
dtype = arr.dtype
|
|
||||||
assert arr['a'].tolist() == [b'', b'a', b'ab', b'abc']
|
|
||||||
assert arr['b'].tolist() == [b'', b'a', b'ab', b'abc']
|
|
||||||
arr = create_string_array(False)
|
|
||||||
assert dtype == arr.dtype
|
|
||||||
|
|
||||||
data = np.arange(1, 7, dtype='int32')
|
|
||||||
for i in range(8):
|
|
||||||
np.testing.assert_array_equal(test_array_ctors(10 + i), data.reshape((3, 2)))
|
|
||||||
np.testing.assert_array_equal(test_array_ctors(20 + i), data.reshape((3, 2)))
|
|
||||||
for i in range(5):
|
|
||||||
np.testing.assert_array_equal(test_array_ctors(30 + i), data)
|
|
||||||
np.testing.assert_array_equal(test_array_ctors(40 + i), data)
|
|
||||||
|
|
||||||
d1 = np.dtype({'names': ['a', 'b'], 'formats': ['int32', 'float64'],
|
|
||||||
'offsets': [1, 10], 'itemsize': 20})
|
|
||||||
d2 = np.dtype([('a', 'i4'), ('b', 'f4')])
|
|
||||||
assert test_dtype_ctors() == [np.dtype('int32'), np.dtype('float64'),
|
|
||||||
np.dtype('bool'), d1, d1, np.dtype('uint32'), d2]
|
|
||||||
|
|
||||||
assert test_dtype_methods() == [np.dtype('int32'), simple_dtype, False, True,
|
|
||||||
np.dtype('int32').itemsize, simple_dtype.itemsize]
|
|
@ -1,28 +0,0 @@
|
|||||||
T{=?:x:3x=I:y:=f:z:}
|
|
||||||
T{=?:x:=I:y:=f:z:}
|
|
||||||
T{=T{=?:x:3x=I:y:=f:z:}:a:=T{=?:x:=I:y:=f:z:}:b:}
|
|
||||||
T{=?:x:3x=I:y:=f:z:12x}
|
|
||||||
T{8x=T{=?:x:3x=I:y:=f:z:12x}:a:8x}
|
|
||||||
T{=3s:a:=3s:b:}
|
|
||||||
{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':12}
|
|
||||||
[('x', '?'), ('y', '<u4'), ('z', '<f4')]
|
|
||||||
[('a', {'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':12}), ('b', [('x', '?'), ('y', '<u4'), ('z', '<f4')])]
|
|
||||||
{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}
|
|
||||||
{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}
|
|
||||||
[('a', 'S3'), ('b', 'S3')]
|
|
||||||
s:0,0,0
|
|
||||||
s:1,1,1.5
|
|
||||||
s:0,2,3
|
|
||||||
p:0,0,0
|
|
||||||
p:1,1,1.5
|
|
||||||
p:0,2,3
|
|
||||||
{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}
|
|
||||||
{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}
|
|
||||||
n:a=s:0,0,0;b=p:1,1,1.5
|
|
||||||
n:a=s:1,1,1.5;b=p:0,2,3
|
|
||||||
n:a=s:0,2,3;b=p:1,3,4.5
|
|
||||||
[('a', 'S3'), ('b', 'S3')]
|
|
||||||
a='',b=''
|
|
||||||
a='a',b='a'
|
|
||||||
a='ab',b='ab'
|
|
||||||
a='abc',b='abc'
|
|
@ -1,36 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
import example
|
|
||||||
try:
|
|
||||||
import numpy as np
|
|
||||||
except ImportError:
|
|
||||||
# NumPy missing: skip test
|
|
||||||
exit(99)
|
|
||||||
|
|
||||||
from example import vectorized_func
|
|
||||||
from example import vectorized_func2
|
|
||||||
from example import vectorized_func3
|
|
||||||
|
|
||||||
print(vectorized_func3(np.array(3+7j)))
|
|
||||||
|
|
||||||
for f in [vectorized_func, vectorized_func2]:
|
|
||||||
print(f(1, 2, 3))
|
|
||||||
print(f(np.array(1), np.array(2), 3))
|
|
||||||
print(f(np.array([1, 3]), np.array([2, 4]), 3))
|
|
||||||
print(f(np.array([[1, 3, 5], [7, 9, 11]]), np.array([[2, 4, 6], [8, 10, 12]]), 3))
|
|
||||||
print(np.array([[1, 3, 5], [7, 9, 11]])* np.array([[2, 4, 6], [8, 10, 12]])*3)
|
|
||||||
print(f(np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2))
|
|
||||||
print(np.array([[1, 2, 3], [4, 5, 6]])* np.array([2, 3, 4])* 2)
|
|
||||||
print(f(np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2))
|
|
||||||
print(np.array([[1, 2, 3], [4, 5, 6]])* np.array([[2], [3]])* 2)
|
|
||||||
|
|
||||||
from example import selective_func
|
|
||||||
|
|
||||||
selective_func(np.array([1], dtype=np.int32))
|
|
||||||
selective_func(np.array([1.0], dtype=np.float32))
|
|
||||||
selective_func(np.array([1.0j], dtype=np.complex64))
|
|
||||||
|
|
||||||
print(vectorized_func.__doc__)
|
|
@ -1,79 +0,0 @@
|
|||||||
(6+14j)
|
|
||||||
my_func(x:int=1, y:float=2, z:float=3)
|
|
||||||
6.0
|
|
||||||
my_func(x:int=1, y:float=2, z:float=3)
|
|
||||||
6.0
|
|
||||||
my_func(x:int=1, y:float=2, z:float=3)
|
|
||||||
my_func(x:int=3, y:float=4, z:float=3)
|
|
||||||
[ 6. 36.]
|
|
||||||
my_func(x:int=1, y:float=2, z:float=3)
|
|
||||||
my_func(x:int=3, y:float=4, z:float=3)
|
|
||||||
my_func(x:int=5, y:float=6, z:float=3)
|
|
||||||
my_func(x:int=7, y:float=8, z:float=3)
|
|
||||||
my_func(x:int=9, y:float=10, z:float=3)
|
|
||||||
my_func(x:int=11, y:float=12, z:float=3)
|
|
||||||
[[ 6. 36. 90.]
|
|
||||||
[ 168. 270. 396.]]
|
|
||||||
[[ 6 36 90]
|
|
||||||
[168 270 396]]
|
|
||||||
my_func(x:int=1, y:float=2, z:float=2)
|
|
||||||
my_func(x:int=2, y:float=3, z:float=2)
|
|
||||||
my_func(x:int=3, y:float=4, z:float=2)
|
|
||||||
my_func(x:int=4, y:float=2, z:float=2)
|
|
||||||
my_func(x:int=5, y:float=3, z:float=2)
|
|
||||||
my_func(x:int=6, y:float=4, z:float=2)
|
|
||||||
[[ 4. 12. 24.]
|
|
||||||
[ 16. 30. 48.]]
|
|
||||||
[[ 4 12 24]
|
|
||||||
[16 30 48]]
|
|
||||||
my_func(x:int=1, y:float=2, z:float=2)
|
|
||||||
my_func(x:int=2, y:float=2, z:float=2)
|
|
||||||
my_func(x:int=3, y:float=2, z:float=2)
|
|
||||||
my_func(x:int=4, y:float=3, z:float=2)
|
|
||||||
my_func(x:int=5, y:float=3, z:float=2)
|
|
||||||
my_func(x:int=6, y:float=3, z:float=2)
|
|
||||||
[[ 4. 8. 12.]
|
|
||||||
[ 24. 30. 36.]]
|
|
||||||
[[ 4 8 12]
|
|
||||||
[24 30 36]]
|
|
||||||
my_func(x:int=1, y:float=2, z:float=3)
|
|
||||||
6.0
|
|
||||||
my_func(x:int=1, y:float=2, z:float=3)
|
|
||||||
6.0
|
|
||||||
my_func(x:int=1, y:float=2, z:float=3)
|
|
||||||
my_func(x:int=3, y:float=4, z:float=3)
|
|
||||||
[ 6. 36.]
|
|
||||||
my_func(x:int=1, y:float=2, z:float=3)
|
|
||||||
my_func(x:int=3, y:float=4, z:float=3)
|
|
||||||
my_func(x:int=5, y:float=6, z:float=3)
|
|
||||||
my_func(x:int=7, y:float=8, z:float=3)
|
|
||||||
my_func(x:int=9, y:float=10, z:float=3)
|
|
||||||
my_func(x:int=11, y:float=12, z:float=3)
|
|
||||||
[[ 6. 36. 90.]
|
|
||||||
[ 168. 270. 396.]]
|
|
||||||
[[ 6 36 90]
|
|
||||||
[168 270 396]]
|
|
||||||
my_func(x:int=1, y:float=2, z:float=2)
|
|
||||||
my_func(x:int=2, y:float=3, z:float=2)
|
|
||||||
my_func(x:int=3, y:float=4, z:float=2)
|
|
||||||
my_func(x:int=4, y:float=2, z:float=2)
|
|
||||||
my_func(x:int=5, y:float=3, z:float=2)
|
|
||||||
my_func(x:int=6, y:float=4, z:float=2)
|
|
||||||
[[ 4. 12. 24.]
|
|
||||||
[ 16. 30. 48.]]
|
|
||||||
[[ 4 12 24]
|
|
||||||
[16 30 48]]
|
|
||||||
my_func(x:int=1, y:float=2, z:float=2)
|
|
||||||
my_func(x:int=2, y:float=2, z:float=2)
|
|
||||||
my_func(x:int=3, y:float=2, z:float=2)
|
|
||||||
my_func(x:int=4, y:float=3, z:float=2)
|
|
||||||
my_func(x:int=5, y:float=3, z:float=2)
|
|
||||||
my_func(x:int=6, y:float=3, z:float=2)
|
|
||||||
[[ 4. 8. 12.]
|
|
||||||
[ 24. 30. 36.]]
|
|
||||||
[[ 4 8 12]
|
|
||||||
[24 30 36]]
|
|
||||||
Int branch taken.
|
|
||||||
Float branch taken.
|
|
||||||
Complex float branch taken.
|
|
||||||
vectorized_func(arg0: numpy.ndarray[int], arg1: numpy.ndarray[float], arg2: numpy.ndarray[float]) -> object
|
|
@ -1,52 +0,0 @@
|
|||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import StringList, print_opaque_list
|
|
||||||
from example import ClassWithSTLVecProperty
|
|
||||||
from example import return_void_ptr, print_void_ptr
|
|
||||||
from example import return_null_str, print_null_str
|
|
||||||
from example import return_unique_ptr
|
|
||||||
from example import ExampleMandA
|
|
||||||
|
|
||||||
#####
|
|
||||||
|
|
||||||
l = StringList()
|
|
||||||
l.push_back("Element 1")
|
|
||||||
l.push_back("Element 2")
|
|
||||||
print_opaque_list(l)
|
|
||||||
print("Back element is %s" % l.back())
|
|
||||||
for i, k in enumerate(l):
|
|
||||||
print("%i/%i : %s" % (i + 1, len(l), k))
|
|
||||||
l.pop_back()
|
|
||||||
print_opaque_list(l)
|
|
||||||
|
|
||||||
#####
|
|
||||||
cvp = ClassWithSTLVecProperty()
|
|
||||||
print_opaque_list(cvp.stringList)
|
|
||||||
|
|
||||||
cvp.stringList = l
|
|
||||||
cvp.stringList.push_back("Element 3")
|
|
||||||
print_opaque_list(cvp.stringList)
|
|
||||||
|
|
||||||
#####
|
|
||||||
|
|
||||||
print_void_ptr(return_void_ptr())
|
|
||||||
print_void_ptr(ExampleMandA()) # Should also work for other C++ types
|
|
||||||
from example import ConstructorStats
|
|
||||||
print("ExampleMandA still alive:", ConstructorStats.get(ExampleMandA).alive())
|
|
||||||
|
|
||||||
try:
|
|
||||||
print_void_ptr([1, 2, 3]) # This should not work
|
|
||||||
except Exception as e:
|
|
||||||
print("Caught expected exception: " + str(e))
|
|
||||||
|
|
||||||
print(return_null_str())
|
|
||||||
print_null_str(return_null_str())
|
|
||||||
|
|
||||||
#####
|
|
||||||
|
|
||||||
ptr = return_unique_ptr()
|
|
||||||
print(ptr)
|
|
||||||
print_opaque_list(ptr)
|
|
@ -1,19 +0,0 @@
|
|||||||
Opaque list: [Element 1, Element 2]
|
|
||||||
Back element is Element 2
|
|
||||||
1/2 : Element 1
|
|
||||||
2/2 : Element 2
|
|
||||||
Opaque list: [Element 1]
|
|
||||||
Opaque list: []
|
|
||||||
Opaque list: [Element 1, Element 3]
|
|
||||||
Got void ptr : 0x1234
|
|
||||||
### ExampleMandA @ 0x2ac5370 created via default constructor
|
|
||||||
Got void ptr : 0x2ac5370
|
|
||||||
### ExampleMandA @ 0x2ac5370 destroyed
|
|
||||||
ExampleMandA still alive: 0
|
|
||||||
Caught expected exception: Incompatible function arguments. The following argument types are supported:
|
|
||||||
1. (arg0: capsule) -> None
|
|
||||||
Invoked with: [1, 2, 3]
|
|
||||||
None
|
|
||||||
Got null str : 0x0
|
|
||||||
<example.StringList object at 0x7f7ecde6fc00>
|
|
||||||
Opaque list: [some value]
|
|
@ -1,41 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import Vector2, Vector
|
|
||||||
|
|
||||||
v1 = Vector2(1, 2)
|
|
||||||
v2 = Vector(3, -1)
|
|
||||||
|
|
||||||
print("v1 = " + str(v1))
|
|
||||||
print("v2 = " + str(v2))
|
|
||||||
print("v1+v2 = " + str(v1+v2))
|
|
||||||
print("v1-v2 = " + str(v1-v2))
|
|
||||||
print("v1-8 = " + str(v1-8))
|
|
||||||
print("v1+8 = " + str(v1+8))
|
|
||||||
print("v1*8 = " + str(v1*8))
|
|
||||||
print("v1/8 = " + str(v1/8))
|
|
||||||
print("8-v1 = " + str(8-v1))
|
|
||||||
print("8+v1 = " + str(8+v1))
|
|
||||||
print("8*v1 = " + str(8*v1))
|
|
||||||
print("8/v1 = " + str(8/v1))
|
|
||||||
|
|
||||||
v1 += v2
|
|
||||||
v1 *= 2
|
|
||||||
|
|
||||||
print("(v1+v2)*2 = " + str(v1))
|
|
||||||
|
|
||||||
from example import ConstructorStats
|
|
||||||
cstats = ConstructorStats.get(Vector2)
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
v1 = None
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
v2 = None
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
print("Constructor values:", cstats.values())
|
|
||||||
print("Default constructions:", cstats.default_constructions)
|
|
||||||
print("Copy constructions:", cstats.copy_constructions)
|
|
||||||
print("Move constructions:", cstats.move_constructions >= 10)
|
|
||||||
print("Copy assignments:", cstats.copy_assignments)
|
|
||||||
print("Move assignments:", cstats.move_assignments)
|
|
@ -1,66 +0,0 @@
|
|||||||
### Vector2 @ 0x11f7830 created [1.000000, 2.000000]
|
|
||||||
### Vector2 @ 0x11427c0 created [3.000000, -1.000000]
|
|
||||||
v1 = [1.000000, 2.000000]
|
|
||||||
v2 = [3.000000, -1.000000]
|
|
||||||
### Vector2 @ 0x7ffef6b144b8 created [4.000000, 1.000000]
|
|
||||||
### Vector2 @ 0x11f7e90 created via move constructor
|
|
||||||
### Vector2 @ 0x7ffef6b144b8 destroyed
|
|
||||||
### Vector2 @ 0x11f7e90 destroyed
|
|
||||||
v1+v2 = [4.000000, 1.000000]
|
|
||||||
### Vector2 @ 0x7ffef6b144b8 created [-2.000000, 3.000000]
|
|
||||||
### Vector2 @ 0x11f7e90 created via move constructor
|
|
||||||
### Vector2 @ 0x7ffef6b144b8 destroyed
|
|
||||||
### Vector2 @ 0x11f7e90 destroyed
|
|
||||||
v1-v2 = [-2.000000, 3.000000]
|
|
||||||
### Vector2 @ 0x7ffef6b144c8 created [-7.000000, -6.000000]
|
|
||||||
### Vector2 @ 0x1115760 created via move constructor
|
|
||||||
### Vector2 @ 0x7ffef6b144c8 destroyed
|
|
||||||
### Vector2 @ 0x1115760 destroyed
|
|
||||||
v1-8 = [-7.000000, -6.000000]
|
|
||||||
### Vector2 @ 0x7ffef6b144c8 created [9.000000, 10.000000]
|
|
||||||
### Vector2 @ 0x1115760 created via move constructor
|
|
||||||
### Vector2 @ 0x7ffef6b144c8 destroyed
|
|
||||||
### Vector2 @ 0x1115760 destroyed
|
|
||||||
v1+8 = [9.000000, 10.000000]
|
|
||||||
### Vector2 @ 0x7ffef6b144b8 created [8.000000, 16.000000]
|
|
||||||
### Vector2 @ 0x1115760 created via move constructor
|
|
||||||
### Vector2 @ 0x7ffef6b144b8 destroyed
|
|
||||||
### Vector2 @ 0x1115760 destroyed
|
|
||||||
v1*8 = [8.000000, 16.000000]
|
|
||||||
### Vector2 @ 0x7ffef6b144a8 created [0.125000, 0.250000]
|
|
||||||
### Vector2 @ 0x112f150 created via move constructor
|
|
||||||
### Vector2 @ 0x7ffef6b144a8 destroyed
|
|
||||||
### Vector2 @ 0x112f150 destroyed
|
|
||||||
v1/8 = [0.125000, 0.250000]
|
|
||||||
### Vector2 @ 0x7ffef6b144f8 created [7.000000, 6.000000]
|
|
||||||
### Vector2 @ 0x112f1b0 created via move constructor
|
|
||||||
### Vector2 @ 0x7ffef6b144f8 destroyed
|
|
||||||
### Vector2 @ 0x112f1b0 destroyed
|
|
||||||
8-v1 = [7.000000, 6.000000]
|
|
||||||
### Vector2 @ 0x7ffef6b144f8 created [9.000000, 10.000000]
|
|
||||||
### Vector2 @ 0x112f1b0 created via move constructor
|
|
||||||
### Vector2 @ 0x7ffef6b144f8 destroyed
|
|
||||||
### Vector2 @ 0x112f1b0 destroyed
|
|
||||||
8+v1 = [9.000000, 10.000000]
|
|
||||||
### Vector2 @ 0x7ffef6b144e8 created [8.000000, 16.000000]
|
|
||||||
### Vector2 @ 0x112f230 created via move constructor
|
|
||||||
### Vector2 @ 0x7ffef6b144e8 destroyed
|
|
||||||
### Vector2 @ 0x112f230 destroyed
|
|
||||||
8*v1 = [8.000000, 16.000000]
|
|
||||||
### Vector2 @ 0x7ffef6b144d8 created [8.000000, 4.000000]
|
|
||||||
### Vector2 @ 0x11fb360 created via move constructor
|
|
||||||
### Vector2 @ 0x7ffef6b144d8 destroyed
|
|
||||||
### Vector2 @ 0x11fb360 destroyed
|
|
||||||
8/v1 = [8.000000, 4.000000]
|
|
||||||
(v1+v2)*2 = [8.000000, 2.000000]
|
|
||||||
Instances not destroyed: 2
|
|
||||||
### Vector2 @ 0x11f7830 destroyed
|
|
||||||
Instances not destroyed: 1
|
|
||||||
### Vector2 @ 0x11427c0 destroyed
|
|
||||||
Instances not destroyed: 0
|
|
||||||
Constructor values: ['[1.000000, 2.000000]', '[3.000000, -1.000000]', '[4.000000, 1.000000]', '[-2.000000, 3.000000]', '[-7.000000, -6.000000]', '[9.000000, 10.000000]', '[8.000000, 16.000000]', '[0.125000, 0.250000]', '[7.000000, 6.000000]', '[9.000000, 10.000000]', '[8.000000, 16.000000]', '[8.000000, 4.000000]']
|
|
||||||
Default constructions: 0
|
|
||||||
Copy constructions: 0
|
|
||||||
Move constructions: True
|
|
||||||
Copy assignments: 0
|
|
||||||
Move assignments: 0
|
|
@ -1,21 +0,0 @@
|
|||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import Pickleable
|
|
||||||
|
|
||||||
try:
|
|
||||||
import cPickle as pickle # Use cPickle on Python 2.7
|
|
||||||
except ImportError:
|
|
||||||
import pickle
|
|
||||||
|
|
||||||
p = Pickleable("test_value")
|
|
||||||
p.setExtra1(15)
|
|
||||||
p.setExtra2(48)
|
|
||||||
|
|
||||||
data = pickle.dumps(p, 2) # Must use pickle protocol >= 2
|
|
||||||
print("%s %i %i" % (p.value(), p.extra1(), p.extra2()))
|
|
||||||
|
|
||||||
p2 = pickle.loads(data)
|
|
||||||
print("%s %i %i" % (p2.value(), p2.extra1(), p2.extra2()))
|
|
@ -1,2 +0,0 @@
|
|||||||
test_value 15 48
|
|
||||||
test_value 15 48
|
|
@ -1,85 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys, pydoc
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
import example
|
|
||||||
from example import ExamplePythonTypes
|
|
||||||
|
|
||||||
ExamplePythonTypes.value = 15
|
|
||||||
print(ExamplePythonTypes.value)
|
|
||||||
print(ExamplePythonTypes.value2)
|
|
||||||
|
|
||||||
try:
|
|
||||||
ExamplePythonTypes()
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
|
|
||||||
try:
|
|
||||||
ExamplePythonTypes.value2 = 15
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
|
|
||||||
instance = ExamplePythonTypes.new_instance()
|
|
||||||
|
|
||||||
dict_result = instance.get_dict()
|
|
||||||
dict_result['key2'] = 'value2'
|
|
||||||
instance.print_dict(dict_result)
|
|
||||||
|
|
||||||
dict_result = instance.get_dict_2()
|
|
||||||
dict_result['key2'] = 'value2'
|
|
||||||
instance.print_dict_2(dict_result)
|
|
||||||
|
|
||||||
set_result = instance.get_set()
|
|
||||||
set_result.add('key3')
|
|
||||||
instance.print_set(set_result)
|
|
||||||
|
|
||||||
set_result = instance.get_set2()
|
|
||||||
set_result.add('key3')
|
|
||||||
instance.print_set_2(set_result)
|
|
||||||
|
|
||||||
list_result = instance.get_list()
|
|
||||||
list_result.append('value2')
|
|
||||||
instance.print_list(list_result)
|
|
||||||
|
|
||||||
list_result = instance.get_list_2()
|
|
||||||
list_result.append('value2')
|
|
||||||
instance.print_list_2(list_result)
|
|
||||||
|
|
||||||
array_result = instance.get_array()
|
|
||||||
print(array_result)
|
|
||||||
instance.print_array(array_result)
|
|
||||||
|
|
||||||
try:
|
|
||||||
instance.throw_exception()
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
|
|
||||||
print(instance.pair_passthrough((True, "test")))
|
|
||||||
print(instance.tuple_passthrough((True, "test", 5)))
|
|
||||||
|
|
||||||
print(pydoc.render_doc(ExamplePythonTypes, "Help on %s"))
|
|
||||||
|
|
||||||
print("__name__(example) = %s" % example.__name__)
|
|
||||||
print("__name__(example.ExamplePythonTypes) = %s" % ExamplePythonTypes.__name__)
|
|
||||||
print("__module__(example.ExamplePythonTypes) = %s" % ExamplePythonTypes.__module__)
|
|
||||||
print("__name__(example.ExamplePythonTypes.get_set) = %s" % ExamplePythonTypes.get_set.__name__)
|
|
||||||
print("__module__(example.ExamplePythonTypes.get_set) = %s" % ExamplePythonTypes.get_set.__module__)
|
|
||||||
|
|
||||||
print(instance.get_bytes_from_string().decode())
|
|
||||||
print(instance.get_bytes_from_str().decode())
|
|
||||||
print(instance.get_str_from_string().encode().decode())
|
|
||||||
print(instance.get_str_from_bytes().encode().decode())
|
|
||||||
|
|
||||||
class A(object):
|
|
||||||
__str__ = lambda _: 'this is a str'
|
|
||||||
__repr__ = lambda _: 'this is a repr'
|
|
||||||
|
|
||||||
instance.test_print(A())
|
|
||||||
|
|
||||||
from example import ConstructorStats
|
|
||||||
|
|
||||||
cstats = ConstructorStats.get(ExamplePythonTypes)
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
instance = None
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
@ -1,146 +0,0 @@
|
|||||||
15
|
|
||||||
5
|
|
||||||
example.ExamplePythonTypes: No constructor defined!
|
|
||||||
can't set attribute
|
|
||||||
### ExamplePythonTypes @ 0x1045b80 created via new_instance
|
|
||||||
key: key2, value=value2
|
|
||||||
key: key, value=value
|
|
||||||
key: key, value=value
|
|
||||||
key: key2, value=value2
|
|
||||||
key: key3
|
|
||||||
key: key2
|
|
||||||
key: key1
|
|
||||||
key: key1
|
|
||||||
key: key2
|
|
||||||
key: key3
|
|
||||||
Entry at positon 0: value
|
|
||||||
list item 0: overwritten
|
|
||||||
list item 1: value2
|
|
||||||
list item 0: value
|
|
||||||
list item 1: value2
|
|
||||||
[u'array entry 1', u'array entry 2']
|
|
||||||
array item 0: array entry 1
|
|
||||||
array item 1: array entry 2
|
|
||||||
This exception was intentionally thrown.
|
|
||||||
(u'test', True)
|
|
||||||
(5L, u'test', True)
|
|
||||||
Help on class ExamplePythonTypes in module example
|
|
||||||
|
|
||||||
class EExxaammpplleePPyytthhoonnTTyyppeess(__builtin__.object)
|
|
||||||
| Example 2 documentation
|
|
||||||
|
|
|
||||||
| Methods defined here:
|
|
||||||
|
|
|
||||||
| ____iinniitt____(...)
|
|
||||||
| x.__init__(...) initializes x; see help(type(x)) for signature
|
|
||||||
|
|
|
||||||
| ggeett__aarrrraayy(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes) -> List[unicode[2]]
|
|
||||||
| Return a C++ array
|
|
||||||
|
|
|
||||||
| ggeett__ddiicctt(...)
|
|
||||||
| Signature : (example.ExamplePythonTypes) -> dict
|
|
||||||
|
|
|
||||||
| Return a Python dictionary
|
|
||||||
|
|
|
||||||
| ggeett__ddiicctt__22(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes) -> Dict[unicode, unicode]
|
|
||||||
| Return a C++ dictionary
|
|
||||||
|
|
|
||||||
| ggeett__lliisstt(...)
|
|
||||||
| Signature : (example.ExamplePythonTypes) -> list
|
|
||||||
|
|
|
||||||
| Return a Python list
|
|
||||||
|
|
|
||||||
| ggeett__lliisstt__22(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes) -> List[unicode]
|
|
||||||
| Return a C++ list
|
|
||||||
|
|
|
||||||
| ggeett__sseett(...)
|
|
||||||
| Signature : (example.ExamplePythonTypes) -> set
|
|
||||||
|
|
|
||||||
| Return a Python set
|
|
||||||
|
|
|
||||||
| ggeett__sseett22(...)
|
|
||||||
| Signature : (example.ExamplePythonTypes) -> set
|
|
||||||
|
|
|
||||||
| Return a C++ set
|
|
||||||
|
|
|
||||||
| ppaaiirr__ppaasssstthhrroouugghh(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes, Tuple[bool, unicode]) -> Tuple[unicode, bool]
|
|
||||||
| Return a pair in reversed order
|
|
||||||
|
|
|
||||||
| pprriinntt__aarrrraayy(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes, List[unicode[2]]) -> None
|
|
||||||
| Print entries of a C++ array
|
|
||||||
|
|
|
||||||
| pprriinntt__ddiicctt(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes, dict) -> None
|
|
||||||
| Print entries of a Python dictionary
|
|
||||||
|
|
|
||||||
| pprriinntt__ddiicctt__22(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes, Dict[unicode, unicode]) -> None
|
|
||||||
| Print entries of a C++ dictionary
|
|
||||||
|
|
|
||||||
| pprriinntt__lliisstt(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes, list) -> None
|
|
||||||
| Print entries of a Python list
|
|
||||||
|
|
|
||||||
| pprriinntt__lliisstt__22(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes, List[unicode]) -> None
|
|
||||||
| Print entries of a C++ list
|
|
||||||
|
|
|
||||||
| pprriinntt__sseett(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes, set) -> None
|
|
||||||
| Print entries of a Python set
|
|
||||||
|
|
|
||||||
| pprriinntt__sseett__22(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes, Set[unicode]) -> None
|
|
||||||
| Print entries of a C++ set
|
|
||||||
|
|
|
||||||
| tthhrrooww__eexxcceeppttiioonn(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes) -> None
|
|
||||||
| Throw an exception
|
|
||||||
|
|
|
||||||
| ttuuppllee__ppaasssstthhrroouugghh(...)
|
|
||||||
|
|
|
||||||
| Signature : (example.ExamplePythonTypes, Tuple[bool, unicode, int]) -> Tuple[int, unicode, bool]
|
|
||||||
| Return a triple in reversed order
|
|
||||||
|
|
|
||||||
| ----------------------------------------------------------------------
|
|
||||||
| Data and other attributes defined here:
|
|
||||||
|
|
|
||||||
| ____nneeww____ = <built-in method __new__ of example.ExamplePythonTypes__Meta object>
|
|
||||||
| T.__new__(S, ...) -> a new object with type S, a subtype of T
|
|
||||||
|
|
|
||||||
| nneeww__iinnssttaannccee = <built-in method new_instance of PyCapsule object>
|
|
||||||
| Signature : () -> example.ExamplePythonTypes
|
|
||||||
|
|
|
||||||
| Return an instance
|
|
||||||
|
|
||||||
__name__(example) = example
|
|
||||||
__name__(example.ExamplePythonTypes) = ExamplePythonTypes
|
|
||||||
__module__(example.ExamplePythonTypes) = example
|
|
||||||
__name__(example.ExamplePythonTypes.get_set) = get_set
|
|
||||||
__module__(example.ExamplePythonTypes.get_set) = example
|
|
||||||
foo
|
|
||||||
bar
|
|
||||||
baz
|
|
||||||
boo
|
|
||||||
this is a str
|
|
||||||
this is a repr
|
|
||||||
Instances not destroyed: 1
|
|
||||||
### ExamplePythonTypes @ 0x1045b80 destroyed
|
|
||||||
Instances not destroyed: 0
|
|
@ -1,64 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import Sequence, StringMap
|
|
||||||
|
|
||||||
s = Sequence(5)
|
|
||||||
print("s = " + str(s))
|
|
||||||
print("len(s) = " + str(len(s)))
|
|
||||||
print("s[0], s[3] = %f %f" % (s[0], s[3]))
|
|
||||||
print('12.34 in s: ' + str(12.34 in s))
|
|
||||||
s[0], s[3] = 12.34, 56.78
|
|
||||||
print('12.34 in s: ' + str(12.34 in s))
|
|
||||||
print("s[0], s[3] = %f %f" % (s[0], s[3]))
|
|
||||||
rev = reversed(s)
|
|
||||||
rev2 = s[::-1]
|
|
||||||
print("rev[0], rev[1], rev[2], rev[3], rev[4] = %f %f %f %f %f" % (rev[0], rev[1], rev[2], rev[3], rev[4]))
|
|
||||||
|
|
||||||
for i in rev:
|
|
||||||
print(i, end=' ')
|
|
||||||
print('')
|
|
||||||
for i in rev2:
|
|
||||||
print(i, end=' ')
|
|
||||||
print('')
|
|
||||||
print(rev == rev2)
|
|
||||||
rev[0::2] = Sequence([2.0, 2.0, 2.0])
|
|
||||||
for i in rev:
|
|
||||||
print(i, end=' ')
|
|
||||||
print('')
|
|
||||||
|
|
||||||
m = StringMap({ 'hi': 'bye', 'black': 'white' })
|
|
||||||
print(m['hi'])
|
|
||||||
print(len(m))
|
|
||||||
print(m['black'])
|
|
||||||
try:
|
|
||||||
print(m['orange'])
|
|
||||||
print('Error: should have thrown exception')
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
m['orange'] = 'banana'
|
|
||||||
print(m['orange'])
|
|
||||||
|
|
||||||
for k in m:
|
|
||||||
print("key = %s, value = %s" % (k, m[k]))
|
|
||||||
|
|
||||||
for k,v in m.items():
|
|
||||||
print("item: (%s, %s)" % (k,v))
|
|
||||||
|
|
||||||
from example import ConstructorStats
|
|
||||||
cstats = ConstructorStats.get(Sequence)
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
s = None
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
rev = None
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
rev2 = None
|
|
||||||
print("Instances not destroyed:", cstats.alive())
|
|
||||||
print("Constructor values:", cstats.values())
|
|
||||||
print("Default constructions:", cstats.default_constructions)
|
|
||||||
print("Copy constructions:", cstats.copy_constructions)
|
|
||||||
print("Move constructions:", cstats.move_constructions >= 1)
|
|
||||||
print("Copy assignments:", cstats.copy_assignments)
|
|
||||||
print("Move assignments:", cstats.move_assignments)
|
|
@ -1,41 +0,0 @@
|
|||||||
### Sequence @ 0x1535b00 created of size 5
|
|
||||||
s = <example.Sequence object at 0x7efc73cfa4e0>
|
|
||||||
len(s) = 5
|
|
||||||
s[0], s[3] = 0.000000 0.000000
|
|
||||||
12.34 in s: False
|
|
||||||
12.34 in s: True
|
|
||||||
s[0], s[3] = 12.340000 56.779999
|
|
||||||
### Sequence @ 0x7fff22a45068 created of size 5
|
|
||||||
### Sequence @ 0x1538b90 created via move constructor
|
|
||||||
### Sequence @ 0x7fff22a45068 destroyed
|
|
||||||
### Sequence @ 0x1538bf0 created of size 5
|
|
||||||
rev[0], rev[1], rev[2], rev[3], rev[4] = 0.000000 56.779999 0.000000 0.000000 12.340000
|
|
||||||
0.0 56.779998779296875 0.0 0.0 12.34000015258789
|
|
||||||
0.0 56.779998779296875 0.0 0.0 12.34000015258789
|
|
||||||
True
|
|
||||||
### Sequence @ 0x1b4d1f0 created of size 3 from std::vector
|
|
||||||
### Sequence @ 0x1b4d1f0 destroyed
|
|
||||||
2.0 56.779998779296875 2.0 0.0 2.0
|
|
||||||
bye
|
|
||||||
2
|
|
||||||
white
|
|
||||||
banana
|
|
||||||
key = orange, value = banana
|
|
||||||
key = hi, value = bye
|
|
||||||
key = black, value = white
|
|
||||||
item: (orange, banana)
|
|
||||||
item: (hi, bye)
|
|
||||||
item: (black, white)
|
|
||||||
Instances not destroyed: 3
|
|
||||||
### Sequence @ 0x1535b00 destroyed
|
|
||||||
Instances not destroyed: 2
|
|
||||||
### Sequence @ 0x1538b90 destroyed
|
|
||||||
Instances not destroyed: 1
|
|
||||||
### Sequence @ 0x1538bf0 destroyed
|
|
||||||
Instances not destroyed: 0
|
|
||||||
Constructor values: ['of size', '5', 'of size', '5', 'of size', '5', 'of size', '3', 'from std::vector']
|
|
||||||
Default constructions: 0
|
|
||||||
Copy constructions: 0
|
|
||||||
Move constructions: True
|
|
||||||
Copy assignments: 0
|
|
||||||
Move assignments: 0
|
|
@ -1,85 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import MyObject1
|
|
||||||
from example import MyObject2
|
|
||||||
from example import MyObject3
|
|
||||||
|
|
||||||
from example import make_object_1
|
|
||||||
from example import make_object_2
|
|
||||||
from example import make_myobject1_1
|
|
||||||
from example import make_myobject1_2
|
|
||||||
from example import make_myobject2_1
|
|
||||||
from example import make_myobject2_2
|
|
||||||
from example import make_myobject3_1
|
|
||||||
from example import make_myobject3_2
|
|
||||||
|
|
||||||
from example import print_object_1
|
|
||||||
from example import print_object_2
|
|
||||||
from example import print_object_3
|
|
||||||
from example import print_object_4
|
|
||||||
|
|
||||||
from example import print_myobject1_1
|
|
||||||
from example import print_myobject1_2
|
|
||||||
from example import print_myobject1_3
|
|
||||||
from example import print_myobject1_4
|
|
||||||
|
|
||||||
from example import print_myobject2_1
|
|
||||||
from example import print_myobject2_2
|
|
||||||
from example import print_myobject2_3
|
|
||||||
from example import print_myobject2_4
|
|
||||||
|
|
||||||
from example import print_myobject3_1
|
|
||||||
from example import print_myobject3_2
|
|
||||||
from example import print_myobject3_3
|
|
||||||
from example import print_myobject3_4
|
|
||||||
|
|
||||||
for o in [make_object_1(), make_object_2(), MyObject1(3)]:
|
|
||||||
print("Reference count = %i" % o.getRefCount())
|
|
||||||
print_object_1(o)
|
|
||||||
print_object_2(o)
|
|
||||||
print_object_3(o)
|
|
||||||
print_object_4(o)
|
|
||||||
|
|
||||||
for o in [make_myobject1_1(), make_myobject1_2(), MyObject1(6), 7]:
|
|
||||||
print(o)
|
|
||||||
if not isinstance(o, int):
|
|
||||||
print_object_1(o)
|
|
||||||
print_object_2(o)
|
|
||||||
print_object_3(o)
|
|
||||||
print_object_4(o)
|
|
||||||
print_myobject1_1(o)
|
|
||||||
print_myobject1_2(o)
|
|
||||||
print_myobject1_3(o)
|
|
||||||
print_myobject1_4(o)
|
|
||||||
|
|
||||||
for o in [MyObject2(8), make_myobject2_1(), make_myobject2_2()]:
|
|
||||||
print(o)
|
|
||||||
print_myobject2_1(o)
|
|
||||||
print_myobject2_2(o)
|
|
||||||
print_myobject2_3(o)
|
|
||||||
print_myobject2_4(o)
|
|
||||||
|
|
||||||
for o in [MyObject3(9), make_myobject3_1(), make_myobject3_2()]:
|
|
||||||
print(o)
|
|
||||||
print_myobject3_1(o)
|
|
||||||
print_myobject3_2(o)
|
|
||||||
print_myobject3_3(o)
|
|
||||||
print_myobject3_4(o)
|
|
||||||
|
|
||||||
from example import ConstructorStats, cstats_ref, Object
|
|
||||||
|
|
||||||
cstats = [ConstructorStats.get(Object), ConstructorStats.get(MyObject1),
|
|
||||||
ConstructorStats.get(MyObject2), ConstructorStats.get(MyObject3),
|
|
||||||
cstats_ref()]
|
|
||||||
print("Instances not destroyed:", [x.alive() for x in cstats])
|
|
||||||
o = None
|
|
||||||
print("Instances not destroyed:", [x.alive() for x in cstats])
|
|
||||||
print("Object value constructions:", [x.values() for x in cstats])
|
|
||||||
print("Default constructions:", [x.default_constructions for x in cstats])
|
|
||||||
print("Copy constructions:", [x.copy_constructions for x in cstats])
|
|
||||||
#print("Move constructions:", [x.move_constructions >= 0 for x in cstats]) # Doesn't invoke any
|
|
||||||
print("Copy assignments:", [x.copy_assignments for x in cstats])
|
|
||||||
print("Move assignments:", [x.move_assignments for x in cstats])
|
|
@ -1,270 +0,0 @@
|
|||||||
### Object @ 0xdeffd0 created via default constructor
|
|
||||||
### MyObject1 @ 0xdeffd0 created MyObject1[1]
|
|
||||||
### ref<MyObject1> @ 0x7f6a2e03c4a8 created from pointer 0xdeffd0
|
|
||||||
### Object @ 0xe43f50 created via default constructor
|
|
||||||
### MyObject1 @ 0xe43f50 created MyObject1[2]
|
|
||||||
### ref<Object> @ 0x7fff136845d0 created from pointer 0xe43f50
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32aad8 created via copy constructor with pointer 0xe43f50
|
|
||||||
### ref<Object> @ 0x7fff136845d0 destroyed
|
|
||||||
### Object @ 0xee8cf0 created via default constructor
|
|
||||||
### MyObject1 @ 0xee8cf0 created MyObject1[3]
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee8cf0
|
|
||||||
Reference count = 1
|
|
||||||
MyObject1[1]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xdeffd0
|
|
||||||
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xdeffd0
|
|
||||||
MyObject1[1]
|
|
||||||
### ref<Object> @ 0x7fff136845a8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xdeffd0
|
|
||||||
MyObject1[1]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xdeffd0
|
|
||||||
MyObject1[1]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
Reference count = 1
|
|
||||||
MyObject1[2]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xe43f50
|
|
||||||
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xe43f50
|
|
||||||
MyObject1[2]
|
|
||||||
### ref<Object> @ 0x7fff136845a8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xe43f50
|
|
||||||
MyObject1[2]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xe43f50
|
|
||||||
MyObject1[2]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
Reference count = 1
|
|
||||||
MyObject1[3]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8cf0
|
|
||||||
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee8cf0
|
|
||||||
MyObject1[3]
|
|
||||||
### ref<Object> @ 0x7fff136845a8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8cf0
|
|
||||||
MyObject1[3]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8cf0
|
|
||||||
MyObject1[3]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### MyObject1 @ 0xe43f50 destroyed
|
|
||||||
### Object @ 0xe43f50 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32aad8 destroyed
|
|
||||||
### MyObject1 @ 0xdeffd0 destroyed
|
|
||||||
### Object @ 0xdeffd0 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7f6a2e03c4a8 destroyed
|
|
||||||
### Object @ 0xee8310 created via default constructor
|
|
||||||
### MyObject1 @ 0xee8310 created MyObject1[4]
|
|
||||||
### ref<MyObject1> @ 0x7f6a2e03c4a8 created from pointer 0xee8310
|
|
||||||
### Object @ 0xee8470 created via default constructor
|
|
||||||
### MyObject1 @ 0xee8470 created MyObject1[5]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845d0 created from pointer 0xee8470
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32aad8 created via copy constructor with pointer 0xee8470
|
|
||||||
### ref<MyObject1> @ 0x7fff136845d0 destroyed
|
|
||||||
### Object @ 0xee95a0 created via default constructor
|
|
||||||
### MyObject1 @ 0xee95a0 created MyObject1[6]
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab38 created from pointer 0xee95a0
|
|
||||||
### MyObject1 @ 0xee8cf0 destroyed
|
|
||||||
### Object @ 0xee8cf0 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
|
|
||||||
<example.MyObject1 object at 0x7f6a2e03c480>
|
|
||||||
MyObject1[4]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8310
|
|
||||||
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee8310
|
|
||||||
MyObject1[4]
|
|
||||||
### ref<Object> @ 0x7fff136845a8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8310
|
|
||||||
MyObject1[4]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8310
|
|
||||||
MyObject1[4]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
MyObject1[4]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8310
|
|
||||||
### ref<MyObject1> @ 0x7fff136845a8 created via copy constructor with pointer 0xee8310
|
|
||||||
MyObject1[4]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845a8 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8310
|
|
||||||
MyObject1[4]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8310
|
|
||||||
MyObject1[4]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
<example.MyObject1 object at 0x7f6a2c32aab0>
|
|
||||||
MyObject1[5]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8470
|
|
||||||
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee8470
|
|
||||||
MyObject1[5]
|
|
||||||
### ref<Object> @ 0x7fff136845a8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8470
|
|
||||||
MyObject1[5]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8470
|
|
||||||
MyObject1[5]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
MyObject1[5]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8470
|
|
||||||
### ref<MyObject1> @ 0x7fff136845a8 created via copy constructor with pointer 0xee8470
|
|
||||||
MyObject1[5]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845a8 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8470
|
|
||||||
MyObject1[5]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8470
|
|
||||||
MyObject1[5]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
<example.MyObject1 object at 0x7f6a2c32ab10>
|
|
||||||
MyObject1[6]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a0
|
|
||||||
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee95a0
|
|
||||||
MyObject1[6]
|
|
||||||
### ref<Object> @ 0x7fff136845a8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a0
|
|
||||||
MyObject1[6]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<Object> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a0
|
|
||||||
MyObject1[6]
|
|
||||||
### ref<Object> @ 0x7fff136845c8 destroyed
|
|
||||||
MyObject1[6]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a0
|
|
||||||
### ref<MyObject1> @ 0x7fff136845a8 created via copy constructor with pointer 0xee95a0
|
|
||||||
MyObject1[6]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845a8 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a0
|
|
||||||
MyObject1[6]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a0
|
|
||||||
MyObject1[6]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
7
|
|
||||||
### Object @ 0xee97f0 created via default constructor
|
|
||||||
### MyObject1 @ 0xee97f0 created MyObject1[7]
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee97f0
|
|
||||||
MyObject1[7]
|
|
||||||
### MyObject1 @ 0xee97f0 destroyed
|
|
||||||
### Object @ 0xee97f0 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### Object @ 0xee99e0 created via default constructor
|
|
||||||
### MyObject1 @ 0xee99e0 created MyObject1[7]
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee99e0
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee99e0
|
|
||||||
### ref<MyObject1> @ 0x7fff136845a8 created via copy constructor with pointer 0xee99e0
|
|
||||||
MyObject1[7]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845a8 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
### MyObject1 @ 0xee99e0 destroyed
|
|
||||||
### Object @ 0xee99e0 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### Object @ 0xee97f0 created via default constructor
|
|
||||||
### MyObject1 @ 0xee97f0 created MyObject1[7]
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee97f0
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee97f0
|
|
||||||
MyObject1[7]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
### MyObject1 @ 0xee97f0 destroyed
|
|
||||||
### Object @ 0xee97f0 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
|
|
||||||
### Object @ 0xee99e0 created via default constructor
|
|
||||||
### MyObject1 @ 0xee99e0 created MyObject1[7]
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee99e0
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee99e0
|
|
||||||
MyObject1[7]
|
|
||||||
### ref<MyObject1> @ 0x7fff136845c8 destroyed
|
|
||||||
### MyObject1 @ 0xee99e0 destroyed
|
|
||||||
### Object @ 0xee99e0 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
|
|
||||||
### MyObject1 @ 0xee95a0 destroyed
|
|
||||||
### Object @ 0xee95a0 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32ab38 destroyed
|
|
||||||
### MyObject1 @ 0xee8470 destroyed
|
|
||||||
### Object @ 0xee8470 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7f6a2c32aad8 destroyed
|
|
||||||
### MyObject1 @ 0xee8310 destroyed
|
|
||||||
### Object @ 0xee8310 destroyed
|
|
||||||
### ref<MyObject1> @ 0x7f6a2e03c4a8 destroyed
|
|
||||||
### MyObject2 @ 0xe43f50 created MyObject2[8]
|
|
||||||
### MyObject2 @ 0xee95a0 created MyObject2[6]
|
|
||||||
### MyObject2 @ 0xee95d0 created MyObject2[7]
|
|
||||||
<example.MyObject2 object at 0x7f6a2dfc8768>
|
|
||||||
MyObject2[8]
|
|
||||||
MyObject2[8]
|
|
||||||
MyObject2[8]
|
|
||||||
MyObject2[8]
|
|
||||||
<example.MyObject2 object at 0x7f6a2dfc86c0>
|
|
||||||
MyObject2[6]
|
|
||||||
MyObject2[6]
|
|
||||||
MyObject2[6]
|
|
||||||
MyObject2[6]
|
|
||||||
<example.MyObject2 object at 0x7f6a2c32d030>
|
|
||||||
MyObject2[7]
|
|
||||||
MyObject2[7]
|
|
||||||
MyObject2[7]
|
|
||||||
MyObject2[7]
|
|
||||||
### MyObject2 @ 0xee95a0 destroyed
|
|
||||||
### MyObject2 @ 0xe43f50 destroyed
|
|
||||||
### MyObject3 @ 0xee9ac0 created MyObject3[9]
|
|
||||||
### MyObject3 @ 0xe43f90 created MyObject3[8]
|
|
||||||
### MyObject3 @ 0xeea7d0 created MyObject3[9]
|
|
||||||
### MyObject2 @ 0xee95d0 destroyed
|
|
||||||
<example.MyObject3 object at 0x7f6a2dfc8768>
|
|
||||||
MyObject3[9]
|
|
||||||
MyObject3[9]
|
|
||||||
MyObject3[9]
|
|
||||||
MyObject3[9]
|
|
||||||
<example.MyObject3 object at 0x7f6a2dfc86c0>
|
|
||||||
MyObject3[8]
|
|
||||||
MyObject3[8]
|
|
||||||
MyObject3[8]
|
|
||||||
MyObject3[8]
|
|
||||||
<example.MyObject3 object at 0x7f6a2c32d068>
|
|
||||||
MyObject3[9]
|
|
||||||
MyObject3[9]
|
|
||||||
MyObject3[9]
|
|
||||||
MyObject3[9]
|
|
||||||
### MyObject3 @ 0xe43f90 destroyed
|
|
||||||
### MyObject3 @ 0xee9ac0 destroyed
|
|
||||||
Instances not destroyed: [0, 0, 0, 1, 0]
|
|
||||||
### MyObject3 @ 0xeea7d0 destroyed
|
|
||||||
Instances not destroyed: [0, 0, 0, 0, 0]
|
|
||||||
Object value constructions: [[], ['MyObject1[1]', 'MyObject1[2]', 'MyObject1[3]', 'MyObject1[4]', 'MyObject1[5]', 'MyObject1[6]', 'MyObject1[7]', 'MyObject1[7]', 'MyObject1[7]', 'MyObject1[7]'], ['MyObject2[8]', 'MyObject2[6]', 'MyObject2[7]'], ['MyObject3[9]', 'MyObject3[8]', 'MyObject3[9]'], ['from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer']]
|
|
||||||
Default constructions: [10, 0, 0, 0, 30]
|
|
||||||
Copy constructions: [0, 0, 0, 0, 12]
|
|
||||||
Copy assignments: [0, 0, 0, 0, 30]
|
|
||||||
Move assignments: [0, 0, 0, 0, 0]
|
|
@ -1,48 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from example import VectorInt, El, VectorEl, VectorVectorEl, VectorBool
|
|
||||||
|
|
||||||
v_int = VectorInt([0, 0])
|
|
||||||
print(len(v_int))
|
|
||||||
|
|
||||||
print(bool(v_int))
|
|
||||||
|
|
||||||
v_int2 = VectorInt([0, 0])
|
|
||||||
print(v_int == v_int2)
|
|
||||||
|
|
||||||
v_int2[1] = 1
|
|
||||||
print(v_int != v_int2)
|
|
||||||
|
|
||||||
v_int2.append(2)
|
|
||||||
v_int2.append(3)
|
|
||||||
v_int2.insert(0, 1)
|
|
||||||
v_int2.insert(0, 2)
|
|
||||||
v_int2.insert(0, 3)
|
|
||||||
print(v_int2)
|
|
||||||
|
|
||||||
v_int.append(99)
|
|
||||||
v_int2[2:-2] = v_int
|
|
||||||
print(v_int2)
|
|
||||||
del v_int2[1:3]
|
|
||||||
print(v_int2)
|
|
||||||
del v_int2[0]
|
|
||||||
print(v_int2)
|
|
||||||
|
|
||||||
v_a = VectorEl()
|
|
||||||
v_a.append(El(1))
|
|
||||||
v_a.append(El(2))
|
|
||||||
print(v_a)
|
|
||||||
|
|
||||||
vv_a = VectorVectorEl()
|
|
||||||
vv_a.append(v_a)
|
|
||||||
vv_b = vv_a[0]
|
|
||||||
print(vv_b)
|
|
||||||
|
|
||||||
vv_c = VectorBool()
|
|
||||||
for i in range(10):
|
|
||||||
vv_c.append(i % 2 == 0)
|
|
||||||
for i in range(10):
|
|
||||||
if vv_c[i] != (i % 2 == 0):
|
|
||||||
print("Error!")
|
|
||||||
print(vv_c)
|
|
@ -1,11 +0,0 @@
|
|||||||
2
|
|
||||||
True
|
|
||||||
True
|
|
||||||
True
|
|
||||||
VectorInt[3, 2, 1, 0, 1, 2, 3]
|
|
||||||
VectorInt[3, 2, 0, 0, 99, 2, 3]
|
|
||||||
VectorInt[3, 0, 99, 2, 3]
|
|
||||||
VectorInt[0, 99, 2, 3]
|
|
||||||
VectorEl[El{1}, El{2}]
|
|
||||||
VectorEl[El{1}, El{2}]
|
|
||||||
VectorBool[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
|
|
@ -1,135 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example import ExampleVirt, runExampleVirt, runExampleVirtVirtual, runExampleVirtBool
|
|
||||||
from example import A_Repeat, B_Repeat, C_Repeat, D_Repeat, A_Tpl, B_Tpl, C_Tpl, D_Tpl
|
|
||||||
from example import NCVirt, NonCopyable, Movable
|
|
||||||
|
|
||||||
|
|
||||||
class ExtendedExampleVirt(ExampleVirt):
|
|
||||||
def __init__(self, state):
|
|
||||||
super(ExtendedExampleVirt, self).__init__(state + 1)
|
|
||||||
self.data = "Hello world"
|
|
||||||
|
|
||||||
def run(self, value):
|
|
||||||
print('ExtendedExampleVirt::run(%i), calling parent..' % value)
|
|
||||||
return super(ExtendedExampleVirt, self).run(value + 1)
|
|
||||||
|
|
||||||
def run_bool(self):
|
|
||||||
print('ExtendedExampleVirt::run_bool()')
|
|
||||||
return False
|
|
||||||
|
|
||||||
def pure_virtual(self):
|
|
||||||
print('ExtendedExampleVirt::pure_virtual(): %s' % self.data)
|
|
||||||
|
|
||||||
|
|
||||||
ex12 = ExampleVirt(10)
|
|
||||||
print(runExampleVirt(ex12, 20))
|
|
||||||
try:
|
|
||||||
runExampleVirtVirtual(ex12)
|
|
||||||
except Exception as e:
|
|
||||||
print("Caught expected exception: " + str(e))
|
|
||||||
|
|
||||||
ex12p = ExtendedExampleVirt(10)
|
|
||||||
print(runExampleVirt(ex12p, 20))
|
|
||||||
print(runExampleVirtBool(ex12p))
|
|
||||||
runExampleVirtVirtual(ex12p)
|
|
||||||
|
|
||||||
class VI_AR(A_Repeat):
|
|
||||||
def unlucky_number(self):
|
|
||||||
return 99
|
|
||||||
class VI_AT(A_Tpl):
|
|
||||||
def unlucky_number(self):
|
|
||||||
return 999
|
|
||||||
|
|
||||||
class VI_CR(C_Repeat):
|
|
||||||
def lucky_number(self):
|
|
||||||
return C_Repeat.lucky_number(self) + 1.25
|
|
||||||
class VI_CT(C_Tpl):
|
|
||||||
pass
|
|
||||||
class VI_CCR(VI_CR):
|
|
||||||
def lucky_number(self):
|
|
||||||
return VI_CR.lucky_number(self) * 10
|
|
||||||
class VI_CCT(VI_CT):
|
|
||||||
def lucky_number(self):
|
|
||||||
return VI_CT.lucky_number(self) * 1000
|
|
||||||
|
|
||||||
|
|
||||||
class VI_DR(D_Repeat):
|
|
||||||
def unlucky_number(self):
|
|
||||||
return 123
|
|
||||||
def lucky_number(self):
|
|
||||||
return 42.0
|
|
||||||
class VI_DT(D_Tpl):
|
|
||||||
def say_something(self, times):
|
|
||||||
print("VI_DT says:" + (' quack' * times))
|
|
||||||
def unlucky_number(self):
|
|
||||||
return 1234
|
|
||||||
def lucky_number(self):
|
|
||||||
return -4.25
|
|
||||||
|
|
||||||
classes = [
|
|
||||||
# A_Repeat, A_Tpl, # abstract (they have a pure virtual unlucky_number)
|
|
||||||
VI_AR, VI_AT,
|
|
||||||
B_Repeat, B_Tpl,
|
|
||||||
C_Repeat, C_Tpl,
|
|
||||||
VI_CR, VI_CT, VI_CCR, VI_CCT,
|
|
||||||
D_Repeat, D_Tpl, VI_DR, VI_DT
|
|
||||||
]
|
|
||||||
|
|
||||||
for cl in classes:
|
|
||||||
print("\n%s:" % cl.__name__)
|
|
||||||
obj = cl()
|
|
||||||
obj.say_something(3)
|
|
||||||
print("Unlucky = %d" % obj.unlucky_number())
|
|
||||||
if hasattr(obj, "lucky_number"):
|
|
||||||
print("Lucky = %.2f" % obj.lucky_number())
|
|
||||||
|
|
||||||
class NCVirtExt(NCVirt):
|
|
||||||
def get_noncopyable(self, a, b):
|
|
||||||
# Constructs and returns a new instance:
|
|
||||||
nc = NonCopyable(a*a, b*b)
|
|
||||||
return nc
|
|
||||||
def get_movable(self, a, b):
|
|
||||||
# Return a referenced copy
|
|
||||||
self.movable = Movable(a, b)
|
|
||||||
return self.movable
|
|
||||||
|
|
||||||
class NCVirtExt2(NCVirt):
|
|
||||||
def get_noncopyable(self, a, b):
|
|
||||||
# Keep a reference: this is going to throw an exception
|
|
||||||
self.nc = NonCopyable(a, b)
|
|
||||||
return self.nc
|
|
||||||
def get_movable(self, a, b):
|
|
||||||
# Return a new instance without storing it
|
|
||||||
return Movable(a, b)
|
|
||||||
|
|
||||||
ncv1 = NCVirtExt()
|
|
||||||
print("2^2 * 3^2 =")
|
|
||||||
ncv1.print_nc(2, 3)
|
|
||||||
print("4 + 5 =")
|
|
||||||
ncv1.print_movable(4, 5)
|
|
||||||
ncv2 = NCVirtExt2()
|
|
||||||
print("7 + 7 =")
|
|
||||||
ncv2.print_movable(7, 7)
|
|
||||||
try:
|
|
||||||
ncv2.print_nc(9, 9)
|
|
||||||
print("Something's wrong: exception not raised!")
|
|
||||||
except RuntimeError as e:
|
|
||||||
# Don't print the exception message here because it differs under debug/non-debug mode
|
|
||||||
print("Caught expected exception")
|
|
||||||
|
|
||||||
from example import ConstructorStats
|
|
||||||
del ex12
|
|
||||||
del ex12p
|
|
||||||
del obj
|
|
||||||
del ncv1
|
|
||||||
del ncv2
|
|
||||||
cstats = [ConstructorStats.get(ExampleVirt), ConstructorStats.get(NonCopyable), ConstructorStats.get(Movable)]
|
|
||||||
print("Instances not destroyed:", [x.alive() for x in cstats])
|
|
||||||
print("Constructor values:", [x.values() for x in cstats])
|
|
||||||
print("Copy constructions:", [x.copy_constructions for x in cstats])
|
|
||||||
print("Move constructions:", [cstats[i].move_constructions >= 1 for i in range(1, len(cstats))])
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
|||||||
### ExampleVirt @ 0x2073a90 created 10
|
|
||||||
Original implementation of ExampleVirt::run(state=10, value=20)
|
|
||||||
30
|
|
||||||
Caught expected exception: Tried to call pure virtual function "ExampleVirt::pure_virtual"
|
|
||||||
### ExampleVirt @ 0x2076a00 created 11
|
|
||||||
ExtendedExampleVirt::run(20), calling parent..
|
|
||||||
Original implementation of ExampleVirt::run(state=11, value=21)
|
|
||||||
32
|
|
||||||
ExtendedExampleVirt::run_bool()
|
|
||||||
False
|
|
||||||
ExtendedExampleVirt::pure_virtual(): Hello world
|
|
||||||
|
|
||||||
VI_AR:
|
|
||||||
hihihi
|
|
||||||
Unlucky = 99
|
|
||||||
|
|
||||||
VI_AT:
|
|
||||||
hihihi
|
|
||||||
Unlucky = 999
|
|
||||||
|
|
||||||
B_Repeat:
|
|
||||||
B says hi 3 times
|
|
||||||
Unlucky = 13
|
|
||||||
Lucky = 7.00
|
|
||||||
|
|
||||||
B_Tpl:
|
|
||||||
B says hi 3 times
|
|
||||||
Unlucky = 13
|
|
||||||
Lucky = 7.00
|
|
||||||
|
|
||||||
C_Repeat:
|
|
||||||
B says hi 3 times
|
|
||||||
Unlucky = 4444
|
|
||||||
Lucky = 888.00
|
|
||||||
|
|
||||||
C_Tpl:
|
|
||||||
B says hi 3 times
|
|
||||||
Unlucky = 4444
|
|
||||||
Lucky = 888.00
|
|
||||||
|
|
||||||
VI_CR:
|
|
||||||
B says hi 3 times
|
|
||||||
Unlucky = 4444
|
|
||||||
Lucky = 889.25
|
|
||||||
|
|
||||||
VI_CT:
|
|
||||||
B says hi 3 times
|
|
||||||
Unlucky = 4444
|
|
||||||
Lucky = 888.00
|
|
||||||
|
|
||||||
VI_CCR:
|
|
||||||
B says hi 3 times
|
|
||||||
Unlucky = 4444
|
|
||||||
Lucky = 8892.50
|
|
||||||
|
|
||||||
VI_CCT:
|
|
||||||
B says hi 3 times
|
|
||||||
Unlucky = 4444
|
|
||||||
Lucky = 888000.00
|
|
||||||
|
|
||||||
D_Repeat:
|
|
||||||
B says hi 3 times
|
|
||||||
Unlucky = 4444
|
|
||||||
Lucky = 888.00
|
|
||||||
|
|
||||||
D_Tpl:
|
|
||||||
B says hi 3 times
|
|
||||||
Unlucky = 4444
|
|
||||||
Lucky = 888.00
|
|
||||||
|
|
||||||
VI_DR:
|
|
||||||
B says hi 3 times
|
|
||||||
Unlucky = 123
|
|
||||||
Lucky = 42.00
|
|
||||||
|
|
||||||
VI_DT:
|
|
||||||
VI_DT says: quack quack quack
|
|
||||||
Unlucky = 1234
|
|
||||||
Lucky = -4.25
|
|
||||||
2^2 * 3^2 =
|
|
||||||
### NonCopyable @ 0x207df10 created 4 9
|
|
||||||
### NonCopyable @ 0x7ffcfe866228 created via move constructor
|
|
||||||
### NonCopyable @ 0x207df10 destroyed
|
|
||||||
36
|
|
||||||
### NonCopyable @ 0x7ffcfe866228 destroyed
|
|
||||||
4 + 5 =
|
|
||||||
### Movable @ 0x207e230 created 4 5
|
|
||||||
### Movable @ 0x7ffcfe86624c created via copy constructor
|
|
||||||
9
|
|
||||||
### Movable @ 0x7ffcfe86624c destroyed
|
|
||||||
7 + 7 =
|
|
||||||
### Movable @ 0x20259e0 created 7 7
|
|
||||||
### Movable @ 0x7ffcfe86624c created via move constructor
|
|
||||||
### Movable @ 0x20259e0 destroyed
|
|
||||||
14
|
|
||||||
### Movable @ 0x7ffcfe86624c destroyed
|
|
||||||
### NonCopyable @ 0x2025a00 created 9 9
|
|
||||||
Caught expected exception
|
|
||||||
### ExampleVirt @ 0x2073a90 destroyed
|
|
||||||
### ExampleVirt @ 0x2076a00 destroyed
|
|
||||||
### Movable @ 0x207e230 destroyed
|
|
||||||
### NonCopyable @ 0x2025a00 destroyed
|
|
||||||
Instances not destroyed: [0, 0, 0]
|
|
||||||
Constructor values: [['10', '11'], ['4', '9', '9', '9'], ['4', '5', '7', '7']]
|
|
||||||
Copy constructions: [0, 0, 1]
|
|
||||||
Move constructions: [True, True]
|
|
@ -1,111 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from example.issues import print_cchar, print_char
|
|
||||||
from example.issues import DispatchIssue, dispatch_issue_go
|
|
||||||
from example.issues import Placeholder, return_vec_of_reference_wrapper
|
|
||||||
from example.issues import iterator_passthrough
|
|
||||||
from example.issues import ElementList, ElementA, print_element
|
|
||||||
from example.issues import expect_float, expect_int
|
|
||||||
from example.issues import A, call_f
|
|
||||||
from example.issues import StrIssue
|
|
||||||
from example.issues import NestA, NestB, NestC, print_NestA, print_NestB, print_NestC
|
|
||||||
import gc
|
|
||||||
|
|
||||||
print_cchar("const char *")
|
|
||||||
print_char('c')
|
|
||||||
|
|
||||||
|
|
||||||
class PyClass1(DispatchIssue):
|
|
||||||
def dispatch(self):
|
|
||||||
print("Yay..")
|
|
||||||
|
|
||||||
|
|
||||||
class PyClass2(DispatchIssue):
|
|
||||||
def dispatch(self):
|
|
||||||
try:
|
|
||||||
super(PyClass2, self).dispatch()
|
|
||||||
except Exception as e:
|
|
||||||
print("Failed as expected: " + str(e))
|
|
||||||
p = PyClass1()
|
|
||||||
dispatch_issue_go(p)
|
|
||||||
|
|
||||||
b = PyClass2()
|
|
||||||
dispatch_issue_go(b)
|
|
||||||
|
|
||||||
print(return_vec_of_reference_wrapper(Placeholder(4)))
|
|
||||||
|
|
||||||
print(list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15]))))
|
|
||||||
|
|
||||||
el = ElementList()
|
|
||||||
for i in range(10):
|
|
||||||
el.add(ElementA(i))
|
|
||||||
gc.collect()
|
|
||||||
for i, v in enumerate(el.get()):
|
|
||||||
print("%i==%i, " % (i, v.value()), end='')
|
|
||||||
print()
|
|
||||||
|
|
||||||
try:
|
|
||||||
print_element(None)
|
|
||||||
except Exception as e:
|
|
||||||
print("Failed as expected: " + str(e))
|
|
||||||
|
|
||||||
try:
|
|
||||||
print(expect_int(5.2))
|
|
||||||
except Exception as e:
|
|
||||||
print("Failed as expected: " + str(e))
|
|
||||||
|
|
||||||
print(expect_float(12))
|
|
||||||
|
|
||||||
class B(A):
|
|
||||||
def __init__(self):
|
|
||||||
super(B, self).__init__()
|
|
||||||
|
|
||||||
def f(self):
|
|
||||||
print("In python f()")
|
|
||||||
|
|
||||||
print("C++ version")
|
|
||||||
a = A()
|
|
||||||
call_f(a)
|
|
||||||
|
|
||||||
print("Python version")
|
|
||||||
b = B()
|
|
||||||
call_f(b)
|
|
||||||
|
|
||||||
print(StrIssue(3))
|
|
||||||
try:
|
|
||||||
print(StrIssue("no", "such", "constructor"))
|
|
||||||
except TypeError as e:
|
|
||||||
print("Failed as expected: " + str(e))
|
|
||||||
|
|
||||||
a = NestA()
|
|
||||||
b = NestB()
|
|
||||||
c = NestC()
|
|
||||||
a += 10
|
|
||||||
b.a += 100
|
|
||||||
c.b.a += 1000
|
|
||||||
b -= 1
|
|
||||||
c.b -= 3
|
|
||||||
c *= 7
|
|
||||||
print_NestA(a)
|
|
||||||
print_NestA(b.a)
|
|
||||||
print_NestA(c.b.a)
|
|
||||||
print_NestB(b)
|
|
||||||
print_NestB(c.b)
|
|
||||||
print_NestC(c)
|
|
||||||
abase = a.as_base()
|
|
||||||
print(abase.value)
|
|
||||||
a.as_base().value += 44
|
|
||||||
print(abase.value)
|
|
||||||
print(c.b.a.as_base().value)
|
|
||||||
c.b.a.as_base().value += 44
|
|
||||||
print(c.b.a.as_base().value)
|
|
||||||
del c
|
|
||||||
gc.collect()
|
|
||||||
del a # Should't delete while abase is still alive
|
|
||||||
gc.collect()
|
|
||||||
print(abase.value)
|
|
||||||
del abase
|
|
||||||
gc.collect()
|
|
@ -1,55 +0,0 @@
|
|||||||
const char *
|
|
||||||
c
|
|
||||||
Failed as expected: Tried to call pure virtual function "Base::dispatch"
|
|
||||||
Yay..
|
|
||||||
[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]]
|
|
||||||
[3, 5, 7, 9, 11, 13, 15]
|
|
||||||
0==0, 1==1, 2==2, 3==3, 4==4, 5==5, 6==6, 7==7, 8==8, 9==9,
|
|
||||||
Failed as expected: Incompatible function arguments. The following argument types are supported:
|
|
||||||
1. (arg0: example.issues.ElementA) -> None
|
|
||||||
Invoked with: None
|
|
||||||
Failed as expected: Incompatible function arguments. The following argument types are supported:
|
|
||||||
1. (arg0: int) -> int
|
|
||||||
Invoked with: 5.2
|
|
||||||
12.0
|
|
||||||
C++ version
|
|
||||||
A.f()
|
|
||||||
Python version
|
|
||||||
PyA.PyA()
|
|
||||||
PyA.f()
|
|
||||||
In python f()
|
|
||||||
StrIssue.__str__ called
|
|
||||||
StrIssue[3]
|
|
||||||
Failed as expected: Incompatible constructor arguments. The following argument types are supported:
|
|
||||||
1. example.issues.StrIssue(arg0: int)
|
|
||||||
2. example.issues.StrIssue()
|
|
||||||
Invoked with: no, such, constructor
|
|
||||||
### NestABase @ 0x15eb630 created via default constructor
|
|
||||||
### NestA @ 0x15eb630 created via default constructor
|
|
||||||
### NestABase @ 0x1704000 created via default constructor
|
|
||||||
### NestA @ 0x1704000 created via default constructor
|
|
||||||
### NestB @ 0x1704000 created via default constructor
|
|
||||||
### NestABase @ 0x1633110 created via default constructor
|
|
||||||
### NestA @ 0x1633110 created via default constructor
|
|
||||||
### NestB @ 0x1633110 created via default constructor
|
|
||||||
### NestC @ 0x1633110 created via default constructor
|
|
||||||
13
|
|
||||||
103
|
|
||||||
1003
|
|
||||||
3
|
|
||||||
1
|
|
||||||
35
|
|
||||||
-2
|
|
||||||
42
|
|
||||||
-2
|
|
||||||
42
|
|
||||||
### NestC @ 0x1633110 destroyed
|
|
||||||
### NestB @ 0x1633110 destroyed
|
|
||||||
### NestA @ 0x1633110 destroyed
|
|
||||||
### NestABase @ 0x1633110 destroyed
|
|
||||||
42
|
|
||||||
### NestA @ 0x15eb630 destroyed
|
|
||||||
### NestABase @ 0x15eb630 destroyed
|
|
||||||
### NestB @ 0x1704000 destroyed
|
|
||||||
### NestA @ 0x1704000 destroyed
|
|
||||||
### NestABase @ 0x1704000 destroyed
|
|
@ -1,67 +0,0 @@
|
|||||||
import sys
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
import difflib
|
|
||||||
|
|
||||||
remove_unicode_marker = re.compile(r'u(\'[^\']*\')')
|
|
||||||
remove_long_marker = re.compile(r'([0-9])L')
|
|
||||||
remove_hex = re.compile(r'0x[0-9a-fA-F]+')
|
|
||||||
shorten_floats = re.compile(r'([1-9][0-9]*\.[0-9]{4})[0-9]*')
|
|
||||||
|
|
||||||
def sanitize(lines):
|
|
||||||
lines = lines.split('\n')
|
|
||||||
for i in range(len(lines)):
|
|
||||||
line = lines[i]
|
|
||||||
if line.startswith(" |"):
|
|
||||||
line = ""
|
|
||||||
if line.startswith("### "):
|
|
||||||
# Constructor/destructor output. Useful for example, but unreliable across compilers;
|
|
||||||
# testing of proper construction/destruction occurs with ConstructorStats mechanism instead
|
|
||||||
line = ""
|
|
||||||
line = remove_unicode_marker.sub(r'\1', line)
|
|
||||||
line = remove_long_marker.sub(r'\1', line)
|
|
||||||
line = remove_hex.sub(r'0', line)
|
|
||||||
line = shorten_floats.sub(r'\1', line)
|
|
||||||
line = line.replace('__builtin__', 'builtins')
|
|
||||||
line = line.replace('example.', '')
|
|
||||||
line = line.replace('unicode', 'str')
|
|
||||||
line = line.replace('ExampleWithEnum.EMode', 'EMode')
|
|
||||||
line = line.replace('example.EMode', 'EMode')
|
|
||||||
line = line.replace('method of builtins.PyCapsule instance', '')
|
|
||||||
line = line.strip()
|
|
||||||
lines[i] = line
|
|
||||||
|
|
||||||
return '\n'.join(sorted([l for l in lines if l != ""]))
|
|
||||||
|
|
||||||
path = os.path.dirname(__file__)
|
|
||||||
if path != '':
|
|
||||||
os.chdir(path)
|
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
|
||||||
print("Syntax: %s <test name>" % sys.argv[0])
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
name = sys.argv[1]
|
|
||||||
try:
|
|
||||||
output_bytes = subprocess.check_output([sys.executable, "-u", name + ".py"],
|
|
||||||
stderr=subprocess.STDOUT)
|
|
||||||
except subprocess.CalledProcessError as exc:
|
|
||||||
print('Test `{}` failed:\n{}\n'.format(name, '-' * 50))
|
|
||||||
print(exc.output.decode())
|
|
||||||
print('-' * 50)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
output = sanitize(output_bytes.decode('utf-8'))
|
|
||||||
reference = sanitize(open(name + '.ref', 'r').read())
|
|
||||||
|
|
||||||
if output == reference:
|
|
||||||
print('Test "%s" succeeded.' % name)
|
|
||||||
exit(0)
|
|
||||||
else:
|
|
||||||
print('Test "%s" FAILED!' % name)
|
|
||||||
print('--- output')
|
|
||||||
print('+++ reference')
|
|
||||||
print(''.join(difflib.ndiff(output.splitlines(True),
|
|
||||||
reference.splitlines(True))))
|
|
||||||
exit(-1)
|
|
2
setup.py
2
setup.py
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# Setup script for PyPI; use CMakeFile.txt to build the example application
|
# Setup script for PyPI; use CMakeFile.txt to build extension modules
|
||||||
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
from pybind11 import __version__
|
from pybind11 import __version__
|
||||||
|
88
tests/CMakeLists.txt
Normal file
88
tests/CMakeLists.txt
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
message(STATUS "Setting tests build type to MinSizeRel as none was specified")
|
||||||
|
set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(PYBIND11_TEST_FILES
|
||||||
|
test_buffers.cpp
|
||||||
|
test_callbacks.cpp
|
||||||
|
test_constants_and_functions.cpp
|
||||||
|
test_enum.cpp
|
||||||
|
test_eval.cpp
|
||||||
|
test_exceptions.cpp
|
||||||
|
test_inheritance.cpp
|
||||||
|
test_issues.cpp
|
||||||
|
test_keep_alive.cpp
|
||||||
|
test_kwargs_and_defaults.cpp
|
||||||
|
test_methods_and_attributes.cpp
|
||||||
|
test_modules.cpp
|
||||||
|
test_numpy_dtypes.cpp
|
||||||
|
test_numpy_vectorize.cpp
|
||||||
|
test_opaque_types.cpp
|
||||||
|
test_operator_overloading.cpp
|
||||||
|
test_pickling.cpp
|
||||||
|
test_python_types.cpp
|
||||||
|
test_sequences_and_iterators.cpp
|
||||||
|
test_smart_ptr.cpp
|
||||||
|
test_stl_binders.cpp
|
||||||
|
test_virtual_functions.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check if Eigen is available
|
||||||
|
find_package(Eigen3 QUIET)
|
||||||
|
|
||||||
|
if(EIGEN3_FOUND)
|
||||||
|
list(APPEND PYBIND11_TEST_FILES test_eigen.cpp)
|
||||||
|
message(STATUS "Building tests with Eigen v${EIGEN3_VERSION}")
|
||||||
|
else()
|
||||||
|
message(STATUS "Building tests WITHOUT Eigen")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Create the binding library
|
||||||
|
pybind11_add_module(pybind11_tests pybind11_tests.cpp ${PYBIND11_TEST_FILES})
|
||||||
|
pybind11_enable_warnings(pybind11_tests)
|
||||||
|
|
||||||
|
if(EIGEN3_FOUND)
|
||||||
|
target_include_directories(pybind11_tests PRIVATE ${EIGEN3_INCLUDE_DIR})
|
||||||
|
target_compile_definitions(pybind11_tests PRIVATE -DPYBIND11_TEST_EIGEN)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(testdir ${PROJECT_SOURCE_DIR}/tests)
|
||||||
|
|
||||||
|
# Always write the output file directly into the 'tests' directory (even on MSVC)
|
||||||
|
if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
||||||
|
set_target_properties(pybind11_tests PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${testdir})
|
||||||
|
foreach(config ${CMAKE_CONFIGURATION_TYPES})
|
||||||
|
string(TOUPPER ${config} config)
|
||||||
|
set_target_properties(pybind11_tests PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${config} ${testdir})
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Make sure pytest is found or try to install it if it's not found
|
||||||
|
macro(pybind11_execute_python)
|
||||||
|
execute_process(COMMAND ${PYTHON_EXECUTABLE} -m ${ARGN} OUTPUT_QUIET ERROR_QUIET
|
||||||
|
RESULT_VARIABLE pybind11_execute_python_error)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
if(NOT PYBIND11_PYTEST_FOUND)
|
||||||
|
pybind11_execute_python(pytest --version --noconftest)
|
||||||
|
if(pybind11_execute_python_error)
|
||||||
|
message(STATUS "Installing pytest using pip")
|
||||||
|
pybind11_execute_python(pip install pytest)
|
||||||
|
if(pybind11_execute_python_error)
|
||||||
|
message(STATUS "Installing pytest using pip --user (fallback)")
|
||||||
|
pybind11_execute_python(pip install --user pytest)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
pybind11_execute_python(pytest --version --noconftest)
|
||||||
|
if(pybind11_execute_python_error)
|
||||||
|
message(FATAL_ERROR "Running the tests requires pytest. Please install it manually.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(PYBIND11_PYTEST_FOUND TRUE CACHE INTERAL "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# A single command to compile and run the tests
|
||||||
|
add_custom_target(pytest COMMAND ${PYTHON_EXECUTABLE} -m pytest -rws
|
||||||
|
DEPENDS pybind11_tests WORKING_DIRECTORY ${testdir})
|
204
tests/conftest.py
Normal file
204
tests/conftest.py
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
"""pytest configuration
|
||||||
|
|
||||||
|
Extends output capture as needed by pybind11: ignore constructors, optional unordered lines.
|
||||||
|
Adds docstring and exceptions message sanitizers: ignore Python 2 vs 3 differences.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import textwrap
|
||||||
|
import difflib
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import contextlib
|
||||||
|
|
||||||
|
_unicode_marker = re.compile(r'u(\'[^\']*\')')
|
||||||
|
_long_marker = re.compile(r'([0-9])L')
|
||||||
|
_hexadecimal = re.compile(r'0x[0-9a-fA-F]+')
|
||||||
|
|
||||||
|
|
||||||
|
def _strip_and_dedent(s):
|
||||||
|
"""For triple-quote strings"""
|
||||||
|
return textwrap.dedent(s.lstrip('\n').rstrip())
|
||||||
|
|
||||||
|
|
||||||
|
def _split_and_sort(s):
|
||||||
|
"""For output which does not require specific line order"""
|
||||||
|
return sorted(_strip_and_dedent(s).splitlines())
|
||||||
|
|
||||||
|
|
||||||
|
def _make_explanation(a, b):
|
||||||
|
"""Explanation for a failed assert -- the a and b arguments are List[str]"""
|
||||||
|
return ["--- actual / +++ expected"] + [line.strip('\n') for line in difflib.ndiff(a, b)]
|
||||||
|
|
||||||
|
|
||||||
|
class Output(object):
|
||||||
|
"""Basic output post-processing and comparison"""
|
||||||
|
def __init__(self, string):
|
||||||
|
self.string = string
|
||||||
|
self.explanation = []
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.string
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
# Ignore constructor/destructor output which is prefixed with "###"
|
||||||
|
a = [line for line in self.string.strip().splitlines() if not line.startswith("###")]
|
||||||
|
b = _strip_and_dedent(other).splitlines()
|
||||||
|
if a == b:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.explanation = _make_explanation(a, b)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class Unordered(Output):
|
||||||
|
"""Custom comparison for output without strict line ordering"""
|
||||||
|
def __eq__(self, other):
|
||||||
|
a = _split_and_sort(self.string)
|
||||||
|
b = _split_and_sort(other)
|
||||||
|
if a == b:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.explanation = _make_explanation(a, b)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class Capture(object):
|
||||||
|
def __init__(self, capfd):
|
||||||
|
self.capfd = capfd
|
||||||
|
self.out = ""
|
||||||
|
|
||||||
|
def _flush_stdout(self):
|
||||||
|
sys.stdout.flush()
|
||||||
|
os.fsync(sys.stdout.fileno()) # make sure C++ output is also read
|
||||||
|
return self.capfd.readouterr()[0]
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self._flush_stdout()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *_):
|
||||||
|
self.out = self._flush_stdout()
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
a = Output(self.out)
|
||||||
|
b = other
|
||||||
|
if a == b:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.explanation = a.explanation
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.out
|
||||||
|
|
||||||
|
def __contains__(self, item):
|
||||||
|
return item in self.out
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unordered(self):
|
||||||
|
return Unordered(self.out)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def capture(capfd):
|
||||||
|
"""Extended `capfd` with context manager and custom equality operators"""
|
||||||
|
return Capture(capfd)
|
||||||
|
|
||||||
|
|
||||||
|
class SanitizedString(object):
|
||||||
|
def __init__(self, sanitizer):
|
||||||
|
self.sanitizer = sanitizer
|
||||||
|
self.string = ""
|
||||||
|
self.explanation = []
|
||||||
|
|
||||||
|
def __call__(self, thing):
|
||||||
|
self.string = self.sanitizer(thing)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
a = self.string
|
||||||
|
b = _strip_and_dedent(other)
|
||||||
|
if a == b:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.explanation = _make_explanation(a.splitlines(), b.splitlines())
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _sanitize_general(s):
|
||||||
|
s = s.strip()
|
||||||
|
s = s.replace("pybind11_tests.", "m.")
|
||||||
|
s = s.replace("unicode", "str")
|
||||||
|
s = _long_marker.sub(r"\1", s)
|
||||||
|
s = _unicode_marker.sub(r"\1", s)
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def _sanitize_docstring(thing):
|
||||||
|
s = thing.__doc__
|
||||||
|
s = _sanitize_general(s)
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def doc():
|
||||||
|
"""Sanitize docstrings and add custom failure explanation"""
|
||||||
|
return SanitizedString(_sanitize_docstring)
|
||||||
|
|
||||||
|
|
||||||
|
def _sanitize_message(thing):
|
||||||
|
s = str(thing)
|
||||||
|
s = _sanitize_general(s)
|
||||||
|
s = _hexadecimal.sub("0", s)
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def msg():
|
||||||
|
"""Sanitize messages and add custom failure explanation"""
|
||||||
|
return SanitizedString(_sanitize_message)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
|
def pytest_assertrepr_compare(op, left, right):
|
||||||
|
"""Hook to insert custom failure explanation"""
|
||||||
|
if hasattr(left, 'explanation'):
|
||||||
|
return left.explanation
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def suppress(exception):
|
||||||
|
"""Suppress the desired exception"""
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
except exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_namespace():
|
||||||
|
"""Add import suppression and test requirements to `pytest` namespace"""
|
||||||
|
try:
|
||||||
|
import numpy as np
|
||||||
|
except ImportError:
|
||||||
|
np = None
|
||||||
|
try:
|
||||||
|
import scipy
|
||||||
|
except ImportError:
|
||||||
|
scipy = None
|
||||||
|
try:
|
||||||
|
from pybind11_tests import have_eigen
|
||||||
|
except ImportError:
|
||||||
|
have_eigen = False
|
||||||
|
|
||||||
|
skipif = pytest.mark.skipif
|
||||||
|
return {
|
||||||
|
'suppress': suppress,
|
||||||
|
'requires_numpy': skipif(not np, reason="numpy is not installed"),
|
||||||
|
'requires_scipy': skipif(not np, reason="scipy is not installed"),
|
||||||
|
'requires_eigen_and_numpy': skipif(not have_eigen or not np,
|
||||||
|
reason="eigen and/or numpy are not installed"),
|
||||||
|
'requires_eigen_and_scipy': skipif(not have_eigen or not scipy,
|
||||||
|
reason="eigen and/or scipy are not installed"),
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/*
|
/*
|
||||||
example/constructor-stats.h -- framework for printing and tracking object
|
tests/constructor_stats.h -- framework for printing and tracking object
|
||||||
instance lifetimes in example/test code.
|
instance lifetimes in example/test code.
|
||||||
|
|
||||||
Copyright (c) 2016 Jason Rhinelander <jason@imaginary.ca>
|
Copyright (c) 2016 Jason Rhinelander <jason@imaginary.ca>
|
||||||
@ -64,7 +64,7 @@ inspection/testing in python) by using the functions with `print_` replaced with
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <typeindex>
|
#include <typeindex>
|
||||||
@ -117,9 +117,12 @@ public:
|
|||||||
_values.push_back(oss.str());
|
_values.push_back(oss.str());
|
||||||
value(std::forward<Tmore>(args)...);
|
value(std::forward<Tmore>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move out stored values
|
||||||
py::list values() {
|
py::list values() {
|
||||||
py::list l;
|
py::list l;
|
||||||
for (const auto &v : _values) l.append(py::cast(v));
|
for (const auto &v : _values) l.append(py::cast(v));
|
||||||
|
_values.clear();
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
#define __OBJECT_H
|
#define __OBJECT_H
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include "constructor-stats.h"
|
#include "constructor_stats.h"
|
||||||
|
|
||||||
/// Reference counted object base class
|
/// Reference counted object base class
|
||||||
class Object {
|
class Object {
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example.cpp -- pybind example plugin
|
tests/pybind11_tests.cpp -- pybind example plugin
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
@ -7,8 +7,8 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include "constructor-stats.h"
|
#include "constructor_stats.h"
|
||||||
|
|
||||||
void init_ex_methods_and_attributes(py::module &);
|
void init_ex_methods_and_attributes(py::module &);
|
||||||
void init_ex_python_types(py::module &);
|
void init_ex_python_types(py::module &);
|
||||||
@ -30,6 +30,7 @@ void init_ex_stl_binder_vector(py::module &);
|
|||||||
void init_ex_eval(py::module &);
|
void init_ex_eval(py::module &);
|
||||||
void init_ex_custom_exceptions(py::module &);
|
void init_ex_custom_exceptions(py::module &);
|
||||||
void init_ex_numpy_dtypes(py::module &);
|
void init_ex_numpy_dtypes(py::module &);
|
||||||
|
void init_ex_enum(py::module &);
|
||||||
void init_issues(py::module &);
|
void init_issues(py::module &);
|
||||||
|
|
||||||
#if defined(PYBIND11_TEST_EIGEN)
|
#if defined(PYBIND11_TEST_EIGEN)
|
||||||
@ -49,8 +50,8 @@ void bind_ConstructorStats(py::module &m) {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_PLUGIN(example) {
|
PYBIND11_PLUGIN(pybind11_tests) {
|
||||||
py::module m("example", "pybind example plugin");
|
py::module m("pybind11_tests", "pybind example plugin");
|
||||||
|
|
||||||
bind_ConstructorStats(m);
|
bind_ConstructorStats(m);
|
||||||
|
|
||||||
@ -74,11 +75,15 @@ PYBIND11_PLUGIN(example) {
|
|||||||
init_ex_eval(m);
|
init_ex_eval(m);
|
||||||
init_ex_custom_exceptions(m);
|
init_ex_custom_exceptions(m);
|
||||||
init_ex_numpy_dtypes(m);
|
init_ex_numpy_dtypes(m);
|
||||||
|
init_ex_enum(m);
|
||||||
init_issues(m);
|
init_issues(m);
|
||||||
|
|
||||||
#if defined(PYBIND11_TEST_EIGEN)
|
#if defined(PYBIND11_TEST_EIGEN)
|
||||||
init_eigen(m);
|
init_eigen(m);
|
||||||
#endif
|
m.attr("have_eigen") = py::cast(true);
|
||||||
|
#else
|
||||||
|
m.attr("have_eigen") = py::cast(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
return m.ptr();
|
return m.ptr();
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-buffers.cpp -- supporting Pythons' buffer protocol
|
tests/test_buffers.cpp -- supporting Pythons' buffer protocol
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
@ -7,8 +7,8 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include "constructor-stats.h"
|
#include "constructor_stats.h"
|
||||||
|
|
||||||
class Matrix {
|
class Matrix {
|
||||||
public:
|
public:
|
57
tests/test_buffers.py
Normal file
57
tests/test_buffers.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import pytest
|
||||||
|
from pybind11_tests import Matrix, ConstructorStats
|
||||||
|
|
||||||
|
with pytest.suppress(ImportError):
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_numpy
|
||||||
|
def test_to_python():
|
||||||
|
m = Matrix(5, 5)
|
||||||
|
|
||||||
|
assert m[2, 3] == 0
|
||||||
|
m[2, 3] = 4
|
||||||
|
assert m[2, 3] == 4
|
||||||
|
|
||||||
|
m2 = np.array(m, copy=False)
|
||||||
|
assert m2.shape == (5, 5)
|
||||||
|
assert abs(m2).sum() == 4
|
||||||
|
assert m2[2, 3] == 4
|
||||||
|
m2[2, 3] = 5
|
||||||
|
assert m2[2, 3] == 5
|
||||||
|
|
||||||
|
cstats = ConstructorStats.get(Matrix)
|
||||||
|
assert cstats.alive() == 1
|
||||||
|
del m
|
||||||
|
assert cstats.alive() == 1
|
||||||
|
del m2 # holds an m reference
|
||||||
|
assert cstats.alive() == 0
|
||||||
|
assert cstats.values() == ["5x5 matrix"]
|
||||||
|
assert cstats.copy_constructions == 0
|
||||||
|
# assert cstats.move_constructions >= 0 # Don't invoke any
|
||||||
|
assert cstats.copy_assignments == 0
|
||||||
|
assert cstats.move_assignments == 0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_numpy
|
||||||
|
def test_from_python():
|
||||||
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
|
Matrix(np.array([1, 2, 3])) # trying to assign a 1D array
|
||||||
|
assert str(excinfo.value) == "Incompatible buffer format!"
|
||||||
|
|
||||||
|
m3 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)
|
||||||
|
m4 = Matrix(m3)
|
||||||
|
|
||||||
|
for i in range(m4.rows()):
|
||||||
|
for j in range(m4.cols()):
|
||||||
|
assert m3[i, j] == m4[i, j]
|
||||||
|
|
||||||
|
cstats = ConstructorStats.get(Matrix)
|
||||||
|
assert cstats.alive() == 1
|
||||||
|
del m3, m4
|
||||||
|
assert cstats.alive() == 0
|
||||||
|
assert cstats.values() == ["2x3 matrix"]
|
||||||
|
assert cstats.copy_constructions == 0
|
||||||
|
# assert cstats.move_constructions >= 0 # Don't invoke any
|
||||||
|
assert cstats.copy_assignments == 0
|
||||||
|
assert cstats.move_assignments == 0
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-callbacks.cpp -- callbacks
|
tests/test_callbacks.cpp -- callbacks
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
@ -7,23 +7,21 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include "constructor-stats.h"
|
#include "constructor_stats.h"
|
||||||
#include <pybind11/functional.h>
|
#include <pybind11/functional.h>
|
||||||
|
|
||||||
|
|
||||||
bool test_callback1(py::object func) {
|
py::object test_callback1(py::object func) {
|
||||||
func();
|
return func();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_callback2(py::object func) {
|
py::tuple test_callback2(py::object func) {
|
||||||
py::object result = func("Hello", 'x', true, 5);
|
return func("Hello", 'x', true, 5);
|
||||||
return result.cast<int>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_callback3(const std::function<int(int)> &func) {
|
std::string test_callback3(const std::function<int(int)> &func) {
|
||||||
cout << "func(43) = " << func(43)<< std::endl;
|
return "func(43) = " + std::to_string(func(43));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<int(int)> test_callback4() {
|
std::function<int(int)> test_callback4() {
|
||||||
@ -37,27 +35,24 @@ py::cpp_function test_callback5() {
|
|||||||
|
|
||||||
int dummy_function(int i) { return i + 1; }
|
int dummy_function(int i) { return i + 1; }
|
||||||
int dummy_function2(int i, int j) { return i + j; }
|
int dummy_function2(int i, int j) { return i + j; }
|
||||||
std::function<int(int)> roundtrip(std::function<int(int)> f) {
|
std::function<int(int)> roundtrip(std::function<int(int)> f, bool expect_none = false) {
|
||||||
if (!f)
|
if (expect_none && f) {
|
||||||
std::cout << "roundtrip (got None).." << std::endl;
|
throw std::runtime_error("Expected None to be converted to empty std::function");
|
||||||
else
|
}
|
||||||
std::cout << "roundtrip.." << std::endl;
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_dummy_function(const std::function<int(int)> &f) {
|
std::string test_dummy_function(const std::function<int(int)> &f) {
|
||||||
using fn_type = int (*)(int);
|
using fn_type = int (*)(int);
|
||||||
auto result = f.target<fn_type>();
|
auto result = f.target<fn_type>();
|
||||||
if (!result) {
|
if (!result) {
|
||||||
std::cout << "could not convert to a function pointer." << std::endl;
|
|
||||||
auto r = f(1);
|
auto r = f(1);
|
||||||
std::cout << "eval(1) = " << r << std::endl;
|
return "can't convert to function pointer: eval(1) = " + std::to_string(r);
|
||||||
} else if (*result == dummy_function) {
|
} else if (*result == dummy_function) {
|
||||||
std::cout << "argument matches dummy_function" << std::endl;
|
|
||||||
auto r = (*result)(1);
|
auto r = (*result)(1);
|
||||||
std::cout << "eval(1) = " << r << std::endl;
|
return "matches dummy_function: eval(1) = " + std::to_string(r);
|
||||||
} else {
|
} else {
|
||||||
std::cout << "argument does NOT match dummy_function. This should never happen!" << std::endl;
|
return "argument does NOT match dummy_function. This should never happen!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +91,7 @@ void init_ex_callbacks(py::module &m) {
|
|||||||
/* Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer */
|
/* Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer */
|
||||||
m.def("dummy_function", &dummy_function);
|
m.def("dummy_function", &dummy_function);
|
||||||
m.def("dummy_function2", &dummy_function2);
|
m.def("dummy_function2", &dummy_function2);
|
||||||
m.def("roundtrip", &roundtrip);
|
m.def("roundtrip", &roundtrip, py::arg("f"), py::arg("expect_none")=false);
|
||||||
m.def("test_dummy_function", &test_dummy_function);
|
m.def("test_dummy_function", &test_dummy_function);
|
||||||
// Export the payload constructor statistics for testing purposes:
|
// Export the payload constructor statistics for testing purposes:
|
||||||
m.def("payload_cstats", &ConstructorStats::get<Payload>);
|
m.def("payload_cstats", &ConstructorStats::get<Payload>);
|
63
tests/test_callbacks.py
Normal file
63
tests/test_callbacks.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def test_callbacks():
|
||||||
|
from functools import partial
|
||||||
|
from pybind11_tests import (test_callback1, test_callback2, test_callback3,
|
||||||
|
test_callback4, test_callback5)
|
||||||
|
|
||||||
|
def func1():
|
||||||
|
return "func1"
|
||||||
|
|
||||||
|
def func2(a, b, c, d):
|
||||||
|
return "func2", a, b, c, d
|
||||||
|
|
||||||
|
def func3(a):
|
||||||
|
return "func3({})".format(a)
|
||||||
|
|
||||||
|
assert test_callback1(func1) == "func1"
|
||||||
|
assert test_callback2(func2) == ("func2", "Hello", "x", True, 5)
|
||||||
|
assert test_callback1(partial(func2, 1, 2, 3, 4)) == ("func2", 1, 2, 3, 4)
|
||||||
|
assert test_callback1(partial(func3, "partial")) == "func3(partial)"
|
||||||
|
assert test_callback3(lambda i: i + 1) == "func(43) = 44"
|
||||||
|
|
||||||
|
f = test_callback4()
|
||||||
|
assert f(43) == 44
|
||||||
|
f = test_callback5()
|
||||||
|
assert f(number=43) == 44
|
||||||
|
|
||||||
|
|
||||||
|
def test_lambda_closure_cleanup():
|
||||||
|
from pybind11_tests import test_cleanup, payload_cstats
|
||||||
|
|
||||||
|
test_cleanup()
|
||||||
|
cstats = payload_cstats()
|
||||||
|
assert cstats.alive() == 0
|
||||||
|
assert cstats.copy_constructions == 1
|
||||||
|
assert cstats.move_constructions >= 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_cpp_function_roundtrip():
|
||||||
|
"""Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer"""
|
||||||
|
from pybind11_tests import dummy_function, dummy_function2, test_dummy_function, roundtrip
|
||||||
|
|
||||||
|
assert test_dummy_function(dummy_function) == "matches dummy_function: eval(1) = 2"
|
||||||
|
assert test_dummy_function(roundtrip(dummy_function)) == "matches dummy_function: eval(1) = 2"
|
||||||
|
assert roundtrip(None, expect_none=True) is None
|
||||||
|
assert test_dummy_function(lambda x: x + 2) == "can't convert to function pointer: eval(1) = 3"
|
||||||
|
|
||||||
|
with pytest.raises(TypeError) as excinfo:
|
||||||
|
test_dummy_function(dummy_function2)
|
||||||
|
assert "Incompatible function arguments" in str(excinfo.value)
|
||||||
|
|
||||||
|
with pytest.raises(TypeError) as excinfo:
|
||||||
|
test_dummy_function(lambda x, y: x + y)
|
||||||
|
assert any(s in str(excinfo.value) for s in ("missing 1 required positional argument",
|
||||||
|
"takes exactly 2 arguments"))
|
||||||
|
|
||||||
|
|
||||||
|
def test_function_signatures(doc):
|
||||||
|
from pybind11_tests import test_callback3, test_callback4
|
||||||
|
|
||||||
|
assert doc(test_callback3) == "test_callback3(arg0: Callable[[int], int]) -> str"
|
||||||
|
assert doc(test_callback4) == "test_callback4() -> Callable[[int], int]"
|
55
tests/test_constants_and_functions.cpp
Normal file
55
tests/test_constants_and_functions.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
tests/test_constants_and_functions.cpp -- global constants and functions, enumerations, raw byte strings
|
||||||
|
|
||||||
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
|
All rights reserved. Use of this source code is governed by a
|
||||||
|
BSD-style license that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
|
enum MyEnum { EFirstEntry = 1, ESecondEntry };
|
||||||
|
|
||||||
|
std::string test_function1() {
|
||||||
|
return "test_function()";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string test_function2(MyEnum k) {
|
||||||
|
return "test_function(enum=" + std::to_string(k) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string test_function3(int i) {
|
||||||
|
return "test_function(" + std::to_string(i) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
py::bytes return_bytes() {
|
||||||
|
const char *data = "\x01\x00\x02\x00";
|
||||||
|
return std::string(data, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string print_bytes(py::bytes bytes) {
|
||||||
|
std::string ret = "bytes[";
|
||||||
|
const auto value = static_cast<std::string>(bytes);
|
||||||
|
for (size_t i = 0; i < value.length(); ++i) {
|
||||||
|
ret += std::to_string(static_cast<int>(value[i])) + " ";
|
||||||
|
}
|
||||||
|
ret.back() = ']';
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_ex_constants_and_functions(py::module &m) {
|
||||||
|
m.attr("some_constant") = py::int_(14);
|
||||||
|
|
||||||
|
m.def("test_function", &test_function1);
|
||||||
|
m.def("test_function", &test_function2);
|
||||||
|
m.def("test_function", &test_function3);
|
||||||
|
|
||||||
|
py::enum_<MyEnum>(m, "MyEnum")
|
||||||
|
.value("EFirstEntry", EFirstEntry)
|
||||||
|
.value("ESecondEntry", ESecondEntry)
|
||||||
|
.export_values();
|
||||||
|
|
||||||
|
m.def("return_bytes", &return_bytes);
|
||||||
|
m.def("print_bytes", &print_bytes);
|
||||||
|
}
|
21
tests/test_constants_and_functions.py
Normal file
21
tests/test_constants_and_functions.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
|
||||||
|
def test_constants():
|
||||||
|
from pybind11_tests import some_constant
|
||||||
|
|
||||||
|
assert some_constant == 14
|
||||||
|
|
||||||
|
|
||||||
|
def test_function_overloading():
|
||||||
|
from pybind11_tests import MyEnum, test_function
|
||||||
|
|
||||||
|
assert test_function() == "test_function()"
|
||||||
|
assert test_function(7) == "test_function(7)"
|
||||||
|
assert test_function(MyEnum.EFirstEntry) == "test_function(enum=1)"
|
||||||
|
assert test_function(MyEnum.ESecondEntry) == "test_function(enum=2)"
|
||||||
|
|
||||||
|
|
||||||
|
def test_bytes():
|
||||||
|
from pybind11_tests import return_bytes, print_bytes
|
||||||
|
|
||||||
|
assert print_bytes(return_bytes()) == "bytes[1 0 2 0]"
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/eigen.cpp -- automatic conversion of Eigen types
|
tests/eigen.cpp -- automatic conversion of Eigen types
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
@ -7,7 +7,7 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include <pybind11/eigen.h>
|
#include <pybind11/eigen.h>
|
||||||
#include <Eigen/Cholesky>
|
#include <Eigen/Cholesky>
|
||||||
|
|
136
tests/test_eigen.py
Normal file
136
tests/test_eigen.py
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
with pytest.suppress(ImportError):
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
ref = np.array([[ 0, 3, 0, 0, 0, 11],
|
||||||
|
[22, 0, 0, 0, 17, 11],
|
||||||
|
[ 7, 5, 0, 1, 0, 11],
|
||||||
|
[ 0, 0, 0, 0, 0, 11],
|
||||||
|
[ 0, 0, 14, 0, 8, 11]])
|
||||||
|
|
||||||
|
|
||||||
|
def assert_equal_ref(mat):
|
||||||
|
np.testing.assert_array_equal(mat, ref)
|
||||||
|
|
||||||
|
|
||||||
|
def assert_sparse_equal_ref(sparse_mat):
|
||||||
|
assert_equal_ref(sparse_mat.todense())
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_eigen_and_numpy
|
||||||
|
def test_fixed():
|
||||||
|
from pybind11_tests import fixed_r, fixed_c, fixed_passthrough_r, fixed_passthrough_c
|
||||||
|
|
||||||
|
assert_equal_ref(fixed_c())
|
||||||
|
assert_equal_ref(fixed_r())
|
||||||
|
assert_equal_ref(fixed_passthrough_r(fixed_r()))
|
||||||
|
assert_equal_ref(fixed_passthrough_c(fixed_c()))
|
||||||
|
assert_equal_ref(fixed_passthrough_r(fixed_c()))
|
||||||
|
assert_equal_ref(fixed_passthrough_c(fixed_r()))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_eigen_and_numpy
|
||||||
|
def test_dense():
|
||||||
|
from pybind11_tests import dense_r, dense_c, dense_passthrough_r, dense_passthrough_c
|
||||||
|
|
||||||
|
assert_equal_ref(dense_r())
|
||||||
|
assert_equal_ref(dense_c())
|
||||||
|
assert_equal_ref(dense_passthrough_r(dense_r()))
|
||||||
|
assert_equal_ref(dense_passthrough_c(dense_c()))
|
||||||
|
assert_equal_ref(dense_passthrough_r(dense_c()))
|
||||||
|
assert_equal_ref(dense_passthrough_c(dense_r()))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_eigen_and_numpy
|
||||||
|
def test_nonunit_stride_from_python():
|
||||||
|
from pybind11_tests import double_row, double_col, double_mat_cm, double_mat_rm
|
||||||
|
|
||||||
|
counting_mat = np.arange(9.0, dtype=np.float32).reshape((3, 3))
|
||||||
|
first_row = counting_mat[0, :]
|
||||||
|
first_col = counting_mat[:, 0]
|
||||||
|
assert np.array_equal(double_row(first_row), 2.0 * first_row)
|
||||||
|
assert np.array_equal(double_col(first_row), 2.0 * first_row)
|
||||||
|
assert np.array_equal(double_row(first_col), 2.0 * first_col)
|
||||||
|
assert np.array_equal(double_col(first_col), 2.0 * first_col)
|
||||||
|
|
||||||
|
counting_3d = np.arange(27.0, dtype=np.float32).reshape((3, 3, 3))
|
||||||
|
slices = [counting_3d[0, :, :], counting_3d[:, 0, :], counting_3d[:, :, 0]]
|
||||||
|
for slice_idx, ref_mat in enumerate(slices):
|
||||||
|
assert np.array_equal(double_mat_cm(ref_mat), 2.0 * ref_mat)
|
||||||
|
assert np.array_equal(double_mat_rm(ref_mat), 2.0 * ref_mat)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_eigen_and_numpy
|
||||||
|
def test_nonunit_stride_to_python():
|
||||||
|
from pybind11_tests import diagonal, diagonal_1, diagonal_n, block
|
||||||
|
|
||||||
|
assert np.all(diagonal(ref) == ref.diagonal())
|
||||||
|
assert np.all(diagonal_1(ref) == ref.diagonal(1))
|
||||||
|
for i in range(-5, 7):
|
||||||
|
assert np.all(diagonal_n(ref, i) == ref.diagonal(i)), "diagonal_n({})".format(i)
|
||||||
|
|
||||||
|
assert np.all(block(ref, 2, 1, 3, 3) == ref[2:5, 1:4])
|
||||||
|
assert np.all(block(ref, 1, 4, 4, 2) == ref[1:, 4:])
|
||||||
|
assert np.all(block(ref, 1, 4, 3, 2) == ref[1:4, 4:])
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_eigen_and_numpy
|
||||||
|
def test_eigen_ref_to_python():
|
||||||
|
from pybind11_tests import cholesky1, cholesky2, cholesky3, cholesky4, cholesky5, cholesky6
|
||||||
|
|
||||||
|
chols = [cholesky1, cholesky2, cholesky3, cholesky4, cholesky5, cholesky6]
|
||||||
|
for i, chol in enumerate(chols, start=1):
|
||||||
|
mymat = chol(np.array([[1, 2, 4], [2, 13, 23], [4, 23, 77]]))
|
||||||
|
assert np.all(mymat == np.array([[1, 0, 0], [2, 3, 0], [4, 5, 6]])), "cholesky{}".format(i)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_eigen_and_numpy
|
||||||
|
def test_special_matrix_objects():
|
||||||
|
from pybind11_tests import incr_diag, symmetric_upper, symmetric_lower
|
||||||
|
|
||||||
|
assert np.all(incr_diag(7) == np.diag([1, 2, 3, 4, 5, 6, 7]))
|
||||||
|
|
||||||
|
asymm = np.array([[ 1, 2, 3, 4],
|
||||||
|
[ 5, 6, 7, 8],
|
||||||
|
[ 9, 10, 11, 12],
|
||||||
|
[13, 14, 15, 16]])
|
||||||
|
symm_lower = np.array(asymm)
|
||||||
|
symm_upper = np.array(asymm)
|
||||||
|
for i in range(4):
|
||||||
|
for j in range(i + 1, 4):
|
||||||
|
symm_lower[i, j] = symm_lower[j, i]
|
||||||
|
symm_upper[j, i] = symm_upper[i, j]
|
||||||
|
|
||||||
|
assert np.all(symmetric_lower(asymm) == symm_lower)
|
||||||
|
assert np.all(symmetric_upper(asymm) == symm_upper)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_eigen_and_numpy
|
||||||
|
def test_dense_signature(doc):
|
||||||
|
from pybind11_tests import double_col, double_row, double_mat_rm
|
||||||
|
|
||||||
|
assert doc(double_col) == "double_col(arg0: numpy.ndarray[float32[m, 1]]) -> numpy.ndarray[float32[m, 1]]"
|
||||||
|
assert doc(double_row) == "double_row(arg0: numpy.ndarray[float32[1, n]]) -> numpy.ndarray[float32[1, n]]"
|
||||||
|
assert doc(double_mat_rm) == "double_mat_rm(arg0: numpy.ndarray[float32[m, n]]) -> numpy.ndarray[float32[m, n]]"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_eigen_and_scipy
|
||||||
|
def test_sparse():
|
||||||
|
from pybind11_tests import sparse_r, sparse_c, sparse_passthrough_r, sparse_passthrough_c
|
||||||
|
|
||||||
|
assert_sparse_equal_ref(sparse_r())
|
||||||
|
assert_sparse_equal_ref(sparse_c())
|
||||||
|
assert_sparse_equal_ref(sparse_passthrough_r(sparse_r()))
|
||||||
|
assert_sparse_equal_ref(sparse_passthrough_c(sparse_c()))
|
||||||
|
assert_sparse_equal_ref(sparse_passthrough_r(sparse_c()))
|
||||||
|
assert_sparse_equal_ref(sparse_passthrough_c(sparse_r()))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_eigen_and_scipy
|
||||||
|
def test_sparse_signature(doc):
|
||||||
|
from pybind11_tests import sparse_passthrough_r, sparse_passthrough_c
|
||||||
|
|
||||||
|
assert doc(sparse_passthrough_r) == "sparse_passthrough_r(arg0: scipy.sparse.csr_matrix[float32]) -> scipy.sparse.csr_matrix[float32]"
|
||||||
|
assert doc(sparse_passthrough_c) == "sparse_passthrough_c(arg0: scipy.sparse.csc_matrix[float32]) -> scipy.sparse.csc_matrix[float32]"
|
57
tests/test_enum.cpp
Normal file
57
tests/test_enum.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
tests/test_enums.cpp -- enumerations
|
||||||
|
|
||||||
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
|
All rights reserved. Use of this source code is governed by a
|
||||||
|
BSD-style license that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
|
enum UnscopedEnum {
|
||||||
|
EOne = 1,
|
||||||
|
ETwo
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ScopedEnum {
|
||||||
|
Two = 2,
|
||||||
|
Three
|
||||||
|
};
|
||||||
|
|
||||||
|
class ClassWithUnscopedEnum {
|
||||||
|
public:
|
||||||
|
enum EMode {
|
||||||
|
EFirstMode = 1,
|
||||||
|
ESecondMode
|
||||||
|
};
|
||||||
|
|
||||||
|
static EMode test_function(EMode mode) {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string test_scoped_enum(ScopedEnum z) {
|
||||||
|
return "ScopedEnum::" + std::string(z == ScopedEnum::Two ? "Two" : "Three");
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_ex_enum(py::module &m) {
|
||||||
|
m.def("test_scoped_enum", &test_scoped_enum);
|
||||||
|
|
||||||
|
py::enum_<UnscopedEnum>(m, "UnscopedEnum")
|
||||||
|
.value("EOne", EOne)
|
||||||
|
.value("ETwo", ETwo)
|
||||||
|
.export_values();
|
||||||
|
|
||||||
|
py::enum_<ScopedEnum>(m, "ScopedEnum")
|
||||||
|
.value("Two", ScopedEnum::Two)
|
||||||
|
.value("Three", ScopedEnum::Three)
|
||||||
|
;
|
||||||
|
|
||||||
|
py::class_<ClassWithUnscopedEnum> exenum_class(m, "ClassWithUnscopedEnum");
|
||||||
|
exenum_class.def_static("test_function", &ClassWithUnscopedEnum::test_function);
|
||||||
|
py::enum_<ClassWithUnscopedEnum::EMode>(exenum_class, "EMode")
|
||||||
|
.value("EFirstMode", ClassWithUnscopedEnum::EFirstMode)
|
||||||
|
.value("ESecondMode", ClassWithUnscopedEnum::ESecondMode)
|
||||||
|
.export_values();
|
||||||
|
}
|
63
tests/test_enum.py
Normal file
63
tests/test_enum.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def test_unscoped_enum():
|
||||||
|
from pybind11_tests import UnscopedEnum, EOne
|
||||||
|
|
||||||
|
assert str(UnscopedEnum.EOne) == "UnscopedEnum.EOne"
|
||||||
|
assert str(UnscopedEnum.ETwo) == "UnscopedEnum.ETwo"
|
||||||
|
assert str(EOne) == "UnscopedEnum.EOne"
|
||||||
|
|
||||||
|
# no TypeError exception for unscoped enum ==/!= int comparisons
|
||||||
|
y = UnscopedEnum.ETwo
|
||||||
|
assert y == 2
|
||||||
|
assert y != 3
|
||||||
|
|
||||||
|
assert int(UnscopedEnum.ETwo) == 2
|
||||||
|
assert str(UnscopedEnum(2)) == "UnscopedEnum.ETwo"
|
||||||
|
|
||||||
|
|
||||||
|
def test_scoped_enum():
|
||||||
|
from pybind11_tests import ScopedEnum, test_scoped_enum
|
||||||
|
|
||||||
|
assert test_scoped_enum(ScopedEnum.Three) == "ScopedEnum::Three"
|
||||||
|
z = ScopedEnum.Two
|
||||||
|
assert test_scoped_enum(z) == "ScopedEnum::Two"
|
||||||
|
|
||||||
|
# expected TypeError exceptions for scoped enum ==/!= int comparisons
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
assert z == 2
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
assert z != 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_implicit_conversion():
|
||||||
|
from pybind11_tests import ClassWithUnscopedEnum
|
||||||
|
|
||||||
|
assert str(ClassWithUnscopedEnum.EMode.EFirstMode) == "EMode.EFirstMode"
|
||||||
|
assert str(ClassWithUnscopedEnum.EFirstMode) == "EMode.EFirstMode"
|
||||||
|
|
||||||
|
f = ClassWithUnscopedEnum.test_function
|
||||||
|
first = ClassWithUnscopedEnum.EFirstMode
|
||||||
|
second = ClassWithUnscopedEnum.ESecondMode
|
||||||
|
|
||||||
|
assert f(first) == 1
|
||||||
|
|
||||||
|
assert f(first) == f(first)
|
||||||
|
assert not f(first) != f(first)
|
||||||
|
|
||||||
|
assert f(first) != f(second)
|
||||||
|
assert not f(first) == f(second)
|
||||||
|
|
||||||
|
assert f(first) == int(f(first))
|
||||||
|
assert not f(first) != int(f(first))
|
||||||
|
|
||||||
|
assert f(first) != int(f(second))
|
||||||
|
assert not f(first) == int(f(second))
|
||||||
|
|
||||||
|
# noinspection PyDictCreation
|
||||||
|
x = {f(first): 1, f(second): 2}
|
||||||
|
x[f(first)] = 3
|
||||||
|
x[f(second)] = 4
|
||||||
|
# Hashing test
|
||||||
|
assert str(x) == "{EMode.EFirstMode: 3, EMode.ESecondMode: 4}"
|
80
tests/test_eval.cpp
Normal file
80
tests/test_eval.cpp
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
tests/test_eval.cpp -- Usage of eval() and eval_file()
|
||||||
|
|
||||||
|
Copyright (c) 2016 Klemens D. Morgenstern
|
||||||
|
|
||||||
|
All rights reserved. Use of this source code is governed by a
|
||||||
|
BSD-style license that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <pybind11/eval.h>
|
||||||
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
|
void init_ex_eval(py::module & m) {
|
||||||
|
auto global = py::dict(py::module::import("__main__").attr("__dict__"));
|
||||||
|
|
||||||
|
m.def("test_eval_statements", [global]() {
|
||||||
|
auto local = py::dict();
|
||||||
|
local["call_test"] = py::cpp_function([&]() -> int {
|
||||||
|
return 42;
|
||||||
|
});
|
||||||
|
|
||||||
|
auto result = py::eval<py::eval_statements>(
|
||||||
|
"print('Hello World!');\n"
|
||||||
|
"x = call_test();",
|
||||||
|
global, local
|
||||||
|
);
|
||||||
|
auto x = local["x"].cast<int>();
|
||||||
|
|
||||||
|
return result == py::none() && x == 42;
|
||||||
|
});
|
||||||
|
|
||||||
|
m.def("test_eval", [global]() {
|
||||||
|
auto local = py::dict();
|
||||||
|
local["x"] = py::int_(42);
|
||||||
|
auto x = py::eval("x", global, local);
|
||||||
|
return x.cast<int>() == 42;
|
||||||
|
});
|
||||||
|
|
||||||
|
m.def("test_eval_single_statement", []() {
|
||||||
|
auto local = py::dict();
|
||||||
|
local["call_test"] = py::cpp_function([&]() -> int {
|
||||||
|
return 42;
|
||||||
|
});
|
||||||
|
|
||||||
|
auto result = py::eval<py::eval_single_statement>("x = call_test()", py::dict(), local);
|
||||||
|
auto x = local["x"].cast<int>();
|
||||||
|
return result == py::none() && x == 42;
|
||||||
|
});
|
||||||
|
|
||||||
|
m.def("test_eval_file", [global](py::str filename) {
|
||||||
|
auto local = py::dict();
|
||||||
|
local["y"] = py::int_(43);
|
||||||
|
|
||||||
|
int val_out;
|
||||||
|
local["call_test2"] = py::cpp_function([&](int value) { val_out = value; });
|
||||||
|
|
||||||
|
auto result = py::eval_file(filename, global, local);
|
||||||
|
return val_out == 43 && result == py::none();
|
||||||
|
});
|
||||||
|
|
||||||
|
m.def("test_eval_failure", []() {
|
||||||
|
try {
|
||||||
|
py::eval("nonsense code ...");
|
||||||
|
} catch (py::error_already_set &) {
|
||||||
|
PyErr_Clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
m.def("test_eval_file_failure", []() {
|
||||||
|
try {
|
||||||
|
py::eval_file("non-existing file");
|
||||||
|
} catch (std::exception &) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
19
tests/test_eval.py
Normal file
19
tests/test_eval.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def test_evals(capture):
|
||||||
|
from pybind11_tests import (test_eval_statements, test_eval, test_eval_single_statement,
|
||||||
|
test_eval_file, test_eval_failure, test_eval_file_failure)
|
||||||
|
|
||||||
|
with capture:
|
||||||
|
assert test_eval_statements()
|
||||||
|
assert capture == "Hello World!"
|
||||||
|
|
||||||
|
assert test_eval()
|
||||||
|
assert test_eval_single_statement()
|
||||||
|
|
||||||
|
filename = os.path.join(os.path.dirname(__file__), "test_eval_call.py")
|
||||||
|
assert test_eval_file(filename)
|
||||||
|
|
||||||
|
assert test_eval_failure()
|
||||||
|
assert test_eval_file_failure()
|
4
tests/test_eval_call.py
Normal file
4
tests/test_eval_call.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# This file is called from 'test_eval.py'
|
||||||
|
|
||||||
|
if 'call_test2' in locals():
|
||||||
|
call_test2(y)
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-custom-exceptions.cpp -- exception translation
|
tests/test_custom-exceptions.cpp -- exception translation
|
||||||
|
|
||||||
Copyright (c) 2016 Pim Schellart <P.Schellart@princeton.edu>
|
Copyright (c) 2016 Pim Schellart <P.Schellart@princeton.edu>
|
||||||
|
|
||||||
@ -7,7 +7,7 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
// A type that should be raised as an exeption in Python
|
// A type that should be raised as an exeption in Python
|
||||||
class MyException : public std::exception {
|
class MyException : public std::exception {
|
31
tests/test_exceptions.py
Normal file
31
tests/test_exceptions.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def test_custom(msg):
|
||||||
|
from pybind11_tests import (MyException, throws1, throws2, throws3, throws4,
|
||||||
|
throws_logic_error)
|
||||||
|
|
||||||
|
# Can we catch a MyException?"
|
||||||
|
with pytest.raises(MyException) as excinfo:
|
||||||
|
throws1()
|
||||||
|
assert msg(excinfo.value) == "this error should go to a custom type"
|
||||||
|
|
||||||
|
# Can we translate to standard Python exceptions?
|
||||||
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
|
throws2()
|
||||||
|
assert msg(excinfo.value) == "this error should go to a standard Python exception"
|
||||||
|
|
||||||
|
# Can we handle unknown exceptions?
|
||||||
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
|
throws3()
|
||||||
|
assert msg(excinfo.value) == "Caught an unknown exception!"
|
||||||
|
|
||||||
|
# Can we delegate to another handler by rethrowing?
|
||||||
|
with pytest.raises(MyException) as excinfo:
|
||||||
|
throws4()
|
||||||
|
assert msg(excinfo.value) == "this error is rethrown"
|
||||||
|
|
||||||
|
# "Can we fall-through to the default handler?"
|
||||||
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
|
throws_logic_error()
|
||||||
|
assert msg(excinfo.value) == "this error should fall through to the standard handler"
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-inheritance.cpp -- inheritance, automatic upcasting for polymorphic types
|
tests/test_inheritance.cpp -- inheritance, automatic upcasting for polymorphic types
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
@ -7,7 +7,7 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
class Pet {
|
class Pet {
|
||||||
public:
|
public:
|
||||||
@ -23,7 +23,7 @@ private:
|
|||||||
class Dog : public Pet {
|
class Dog : public Pet {
|
||||||
public:
|
public:
|
||||||
Dog(const std::string &name) : Pet(name, "dog") {}
|
Dog(const std::string &name) : Pet(name, "dog") {}
|
||||||
void bark() const { std::cout << "Woof!" << std::endl; }
|
std::string bark() const { return "Woof!"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Rabbit : public Pet {
|
class Rabbit : public Pet {
|
||||||
@ -31,12 +31,12 @@ public:
|
|||||||
Rabbit(const std::string &name) : Pet(name, "parrot") {}
|
Rabbit(const std::string &name) : Pet(name, "parrot") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
void pet_print(const Pet &pet) {
|
std::string pet_name_species(const Pet &pet) {
|
||||||
std::cout << pet.name() + " is a " + pet.species() << std::endl;
|
return pet.name() + " is a " + pet.species();
|
||||||
}
|
}
|
||||||
|
|
||||||
void dog_bark(const Dog &dog) {
|
std::string dog_bark(const Dog &dog) {
|
||||||
dog.bark();
|
return dog.bark();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ void init_ex_inheritance(py::module &m) {
|
|||||||
py::class_<Rabbit>(m, "Rabbit", py::base<Pet>())
|
py::class_<Rabbit>(m, "Rabbit", py::base<Pet>())
|
||||||
.def(py::init<std::string>());
|
.def(py::init<std::string>());
|
||||||
|
|
||||||
m.def("pet_print", pet_print);
|
m.def("pet_name_species", pet_name_species);
|
||||||
m.def("dog_bark", dog_bark);
|
m.def("dog_bark", dog_bark);
|
||||||
|
|
||||||
py::class_<BaseClass>(m, "BaseClass").def(py::init<>());
|
py::class_<BaseClass>(m, "BaseClass").def(py::init<>());
|
35
tests/test_inheritance.py
Normal file
35
tests/test_inheritance.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def test_inheritance(msg):
|
||||||
|
from pybind11_tests import Pet, Dog, Rabbit, dog_bark, pet_name_species
|
||||||
|
|
||||||
|
roger = Rabbit('Rabbit')
|
||||||
|
assert roger.name() + " is a " + roger.species() == "Rabbit is a parrot"
|
||||||
|
assert pet_name_species(roger) == "Rabbit is a parrot"
|
||||||
|
|
||||||
|
polly = Pet('Polly', 'parrot')
|
||||||
|
assert polly.name() + " is a " + polly.species() == "Polly is a parrot"
|
||||||
|
assert pet_name_species(polly) == "Polly is a parrot"
|
||||||
|
|
||||||
|
molly = Dog('Molly')
|
||||||
|
assert molly.name() + " is a " + molly.species() == "Molly is a dog"
|
||||||
|
assert pet_name_species(molly) == "Molly is a dog"
|
||||||
|
|
||||||
|
assert dog_bark(molly) == "Woof!"
|
||||||
|
|
||||||
|
with pytest.raises(TypeError) as excinfo:
|
||||||
|
dog_bark(polly)
|
||||||
|
assert msg(excinfo.value) == """
|
||||||
|
Incompatible function arguments. The following argument types are supported:
|
||||||
|
1. (arg0: m.Dog) -> str
|
||||||
|
Invoked with: <m.Pet object at 0>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_automatic_upcasting():
|
||||||
|
from pybind11_tests import return_class_1, return_class_2, return_none
|
||||||
|
|
||||||
|
assert type(return_class_1()).__name__ == "DerivedClass1"
|
||||||
|
assert type(return_class_2()).__name__ == "DerivedClass2"
|
||||||
|
assert type(return_none()).__name__ == "NoneType"
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/issues.cpp -- collection of testcases for miscellaneous issues
|
tests/test_issues.cpp -- collection of testcases for miscellaneous issues
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
@ -7,8 +7,8 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include "constructor-stats.h"
|
#include "constructor_stats.h"
|
||||||
#include <pybind11/stl.h>
|
#include <pybind11/stl.h>
|
||||||
#include <pybind11/operators.h>
|
#include <pybind11/operators.h>
|
||||||
|
|
||||||
@ -34,19 +34,20 @@ void init_issues(py::module &m) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #137: const char* isn't handled properly
|
// #137: const char* isn't handled properly
|
||||||
m2.def("print_cchar", [](const char *string) { std::cout << string << std::endl; });
|
m2.def("print_cchar", [](const char *s) { return std::string(s); });
|
||||||
|
|
||||||
// #150: char bindings broken
|
// #150: char bindings broken
|
||||||
m2.def("print_char", [](char c) { std::cout << c << std::endl; });
|
m2.def("print_char", [](char c) { return std::string(1, c); });
|
||||||
|
|
||||||
// #159: virtual function dispatch has problems with similar-named functions
|
// #159: virtual function dispatch has problems with similar-named functions
|
||||||
struct Base { virtual void dispatch(void) const {
|
struct Base { virtual std::string dispatch() const {
|
||||||
/* for some reason MSVC2015 can't compile this if the function is pure virtual */
|
/* for some reason MSVC2015 can't compile this if the function is pure virtual */
|
||||||
|
return {};
|
||||||
}; };
|
}; };
|
||||||
|
|
||||||
struct DispatchIssue : Base {
|
struct DispatchIssue : Base {
|
||||||
virtual void dispatch(void) const {
|
virtual std::string dispatch() const {
|
||||||
PYBIND11_OVERLOAD_PURE(void, Base, dispatch, /* no arguments */);
|
PYBIND11_OVERLOAD_PURE(std::string, Base, dispatch, /* no arguments */);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ void init_issues(py::module &m) {
|
|||||||
.def(py::init<>())
|
.def(py::init<>())
|
||||||
.def("dispatch", &Base::dispatch);
|
.def("dispatch", &Base::dispatch);
|
||||||
|
|
||||||
m2.def("dispatch_issue_go", [](const Base * b) { b->dispatch(); });
|
m2.def("dispatch_issue_go", [](const Base * b) { return b->dispatch(); });
|
||||||
|
|
||||||
struct Placeholder { int i; Placeholder(int i) : i(i) { } };
|
struct Placeholder { int i; Placeholder(int i) : i(i) { } };
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ void init_issues(py::module &m) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// (no id): should not be able to pass 'None' to a reference argument
|
// (no id): should not be able to pass 'None' to a reference argument
|
||||||
m2.def("print_element", [](ElementA &el) { std::cout << el.value() << std::endl; });
|
m2.def("get_element", [](ElementA &el) { return el.value(); });
|
||||||
|
|
||||||
// (no id): don't cast doubles to ints
|
// (no id): don't cast doubles to ints
|
||||||
m2.def("expect_float", [](float f) { return f; });
|
m2.def("expect_float", [](float f) { return f; });
|
||||||
@ -159,10 +160,7 @@ void init_issues(py::module &m) {
|
|||||||
py::class_<StrIssue> si(m2, "StrIssue");
|
py::class_<StrIssue> si(m2, "StrIssue");
|
||||||
si .def(py::init<int>())
|
si .def(py::init<int>())
|
||||||
.def(py::init<>())
|
.def(py::init<>())
|
||||||
.def("__str__", [](const StrIssue &si) {
|
.def("__str__", [](const StrIssue &si) { return "StrIssue[" + std::to_string(si.value()) + "]"; })
|
||||||
std::cout << "StrIssue.__str__ called" << std::endl;
|
|
||||||
return "StrIssue[" + std::to_string(si.value()) + "]";
|
|
||||||
})
|
|
||||||
;
|
;
|
||||||
|
|
||||||
// Issue #328: first member in a class can't be used in operators
|
// Issue #328: first member in a class can't be used in operators
|
||||||
@ -171,7 +169,7 @@ void init_issues(py::module &m) {
|
|||||||
.def("as_base", [](NestA &a) -> NestABase& { return (NestABase&) a; }, py::return_value_policy::reference_internal);
|
.def("as_base", [](NestA &a) -> NestABase& { return (NestABase&) a; }, py::return_value_policy::reference_internal);
|
||||||
py::class_<NestB>(m2, "NestB").def(py::init<>()).def(py::self -= int()).def_readwrite("a", &NestB::a);
|
py::class_<NestB>(m2, "NestB").def(py::init<>()).def(py::self -= int()).def_readwrite("a", &NestB::a);
|
||||||
py::class_<NestC>(m2, "NestC").def(py::init<>()).def(py::self *= int()).def_readwrite("b", &NestC::b);
|
py::class_<NestC>(m2, "NestC").def(py::init<>()).def(py::self *= int()).def_readwrite("b", &NestC::b);
|
||||||
m2.def("print_NestA", [](const NestA &a) { std::cout << a.value << std::endl; });
|
m2.def("get_NestA", [](const NestA &a) { return a.value; });
|
||||||
m2.def("print_NestB", [](const NestB &b) { std::cout << b.value << std::endl; });
|
m2.def("get_NestB", [](const NestB &b) { return b.value; });
|
||||||
m2.def("print_NestC", [](const NestC &c) { std::cout << c.value << std::endl; });
|
m2.def("get_NestC", [](const NestC &c) { return c.value; });
|
||||||
}
|
}
|
160
tests/test_issues.py
Normal file
160
tests/test_issues.py
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import pytest
|
||||||
|
import gc
|
||||||
|
|
||||||
|
|
||||||
|
def test_regressions():
|
||||||
|
from pybind11_tests.issues import print_cchar, print_char
|
||||||
|
|
||||||
|
# #137: const char* isn't handled properly
|
||||||
|
assert print_cchar("const char *") == "const char *"
|
||||||
|
# #150: char bindings broken
|
||||||
|
assert print_char("c") == "c"
|
||||||
|
|
||||||
|
|
||||||
|
def test_dispatch_issue(msg):
|
||||||
|
"""#159: virtual function dispatch has problems with similar-named functions"""
|
||||||
|
from pybind11_tests.issues import DispatchIssue, dispatch_issue_go
|
||||||
|
|
||||||
|
class PyClass1(DispatchIssue):
|
||||||
|
def dispatch(self):
|
||||||
|
return "Yay.."
|
||||||
|
|
||||||
|
class PyClass2(DispatchIssue):
|
||||||
|
def dispatch(self):
|
||||||
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
|
super(PyClass2, self).dispatch()
|
||||||
|
assert msg(excinfo.value) == 'Tried to call pure virtual function "Base::dispatch"'
|
||||||
|
|
||||||
|
p = PyClass1()
|
||||||
|
return dispatch_issue_go(p)
|
||||||
|
|
||||||
|
b = PyClass2()
|
||||||
|
assert dispatch_issue_go(b) == "Yay.."
|
||||||
|
|
||||||
|
|
||||||
|
def test_reference_wrapper():
|
||||||
|
"""#171: Can't return reference wrappers (or STL data structures containing them)"""
|
||||||
|
from pybind11_tests.issues import Placeholder, return_vec_of_reference_wrapper
|
||||||
|
|
||||||
|
assert str(return_vec_of_reference_wrapper(Placeholder(4))) == \
|
||||||
|
"[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]]"
|
||||||
|
|
||||||
|
|
||||||
|
def test_iterator_passthrough():
|
||||||
|
"""#181: iterator passthrough did not compile"""
|
||||||
|
from pybind11_tests.issues import iterator_passthrough
|
||||||
|
|
||||||
|
assert list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15]))) == [3, 5, 7, 9, 11, 13, 15]
|
||||||
|
|
||||||
|
|
||||||
|
def test_shared_ptr_gc():
|
||||||
|
"""// #187: issue involving std::shared_ptr<> return value policy & garbage collection"""
|
||||||
|
from pybind11_tests.issues import ElementList, ElementA
|
||||||
|
|
||||||
|
el = ElementList()
|
||||||
|
for i in range(10):
|
||||||
|
el.add(ElementA(i))
|
||||||
|
gc.collect()
|
||||||
|
for i, v in enumerate(el.get()):
|
||||||
|
assert i == v.value()
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_id(capture, msg):
|
||||||
|
from pybind11_tests.issues import get_element, expect_float, expect_int
|
||||||
|
|
||||||
|
with pytest.raises(TypeError) as excinfo:
|
||||||
|
get_element(None)
|
||||||
|
assert msg(excinfo.value) == """
|
||||||
|
Incompatible function arguments. The following argument types are supported:
|
||||||
|
1. (arg0: m.issues.ElementA) -> int
|
||||||
|
Invoked with: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
with pytest.raises(TypeError) as excinfo:
|
||||||
|
expect_int(5.2)
|
||||||
|
assert msg(excinfo.value) == """
|
||||||
|
Incompatible function arguments. The following argument types are supported:
|
||||||
|
1. (arg0: int) -> int
|
||||||
|
Invoked with: 5.2
|
||||||
|
"""
|
||||||
|
assert expect_float(12) == 12
|
||||||
|
|
||||||
|
from pybind11_tests.issues import A, call_f
|
||||||
|
|
||||||
|
class B(A):
|
||||||
|
def __init__(self):
|
||||||
|
super(B, self).__init__()
|
||||||
|
|
||||||
|
def f(self):
|
||||||
|
print("In python f()")
|
||||||
|
|
||||||
|
# C++ version
|
||||||
|
with capture:
|
||||||
|
a = A()
|
||||||
|
call_f(a)
|
||||||
|
assert capture == "A.f()"
|
||||||
|
|
||||||
|
# Python version
|
||||||
|
with capture:
|
||||||
|
b = B()
|
||||||
|
call_f(b)
|
||||||
|
assert capture == """
|
||||||
|
PyA.PyA()
|
||||||
|
PyA.f()
|
||||||
|
In python f()
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_str_issue(msg):
|
||||||
|
"""Issue #283: __str__ called on uninitialized instance when constructor arguments invalid"""
|
||||||
|
from pybind11_tests.issues import StrIssue
|
||||||
|
|
||||||
|
assert str(StrIssue(3)) == "StrIssue[3]"
|
||||||
|
|
||||||
|
with pytest.raises(TypeError) as excinfo:
|
||||||
|
str(StrIssue("no", "such", "constructor"))
|
||||||
|
assert msg(excinfo.value) == """
|
||||||
|
Incompatible constructor arguments. The following argument types are supported:
|
||||||
|
1. m.issues.StrIssue(arg0: int)
|
||||||
|
2. m.issues.StrIssue()
|
||||||
|
Invoked with: no, such, constructor
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_nested():
|
||||||
|
""" #328: first member in a class can't be used in operators"""
|
||||||
|
from pybind11_tests.issues import NestA, NestB, NestC, get_NestA, get_NestB, get_NestC
|
||||||
|
|
||||||
|
a = NestA()
|
||||||
|
b = NestB()
|
||||||
|
c = NestC()
|
||||||
|
|
||||||
|
a += 10
|
||||||
|
assert get_NestA(a) == 13
|
||||||
|
b.a += 100
|
||||||
|
assert get_NestA(b.a) == 103
|
||||||
|
c.b.a += 1000
|
||||||
|
assert get_NestA(c.b.a) == 1003
|
||||||
|
b -= 1
|
||||||
|
assert get_NestB(b) == 3
|
||||||
|
c.b -= 3
|
||||||
|
assert get_NestB(c.b) == 1
|
||||||
|
c *= 7
|
||||||
|
assert get_NestC(c) == 35
|
||||||
|
|
||||||
|
abase = a.as_base()
|
||||||
|
assert abase.value == -2
|
||||||
|
a.as_base().value += 44
|
||||||
|
assert abase.value == 42
|
||||||
|
assert c.b.a.as_base().value == -2
|
||||||
|
c.b.a.as_base().value += 44
|
||||||
|
assert c.b.a.as_base().value == 42
|
||||||
|
|
||||||
|
del c
|
||||||
|
gc.collect()
|
||||||
|
del a # Should't delete while abase is still alive
|
||||||
|
gc.collect()
|
||||||
|
|
||||||
|
assert abase.value == 42
|
||||||
|
del abase, b
|
||||||
|
gc.collect()
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-keep-alive.cpp -- keep_alive modifier (pybind11's version
|
tests/test_keep_alive.cpp -- keep_alive modifier (pybind11's version
|
||||||
of Boost.Python's with_custodian_and_ward / with_custodian_and_ward_postcall)
|
of Boost.Python's with_custodian_and_ward / with_custodian_and_ward_postcall)
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
@ -8,7 +8,7 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
class Child {
|
class Child {
|
||||||
public:
|
public:
|
98
tests/test_keep_alive.py
Normal file
98
tests/test_keep_alive.py
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import gc
|
||||||
|
|
||||||
|
|
||||||
|
def test_keep_alive_argument(capture):
|
||||||
|
from pybind11_tests import Parent, Child
|
||||||
|
|
||||||
|
with capture:
|
||||||
|
p = Parent()
|
||||||
|
assert capture == "Allocating parent."
|
||||||
|
with capture:
|
||||||
|
p.addChild(Child())
|
||||||
|
gc.collect()
|
||||||
|
assert capture == """
|
||||||
|
Allocating child.
|
||||||
|
Releasing child.
|
||||||
|
"""
|
||||||
|
with capture:
|
||||||
|
del p
|
||||||
|
gc.collect()
|
||||||
|
assert capture == "Releasing parent."
|
||||||
|
|
||||||
|
with capture:
|
||||||
|
p = Parent()
|
||||||
|
assert capture == "Allocating parent."
|
||||||
|
with capture:
|
||||||
|
p.addChildKeepAlive(Child())
|
||||||
|
gc.collect()
|
||||||
|
assert capture == "Allocating child."
|
||||||
|
with capture:
|
||||||
|
del p
|
||||||
|
gc.collect()
|
||||||
|
assert capture == """
|
||||||
|
Releasing parent.
|
||||||
|
Releasing child.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_keep_alive_return_value(capture):
|
||||||
|
from pybind11_tests import Parent
|
||||||
|
|
||||||
|
with capture:
|
||||||
|
p = Parent()
|
||||||
|
assert capture == "Allocating parent."
|
||||||
|
with capture:
|
||||||
|
p.returnChild()
|
||||||
|
gc.collect()
|
||||||
|
assert capture == """
|
||||||
|
Allocating child.
|
||||||
|
Releasing child.
|
||||||
|
"""
|
||||||
|
with capture:
|
||||||
|
del p
|
||||||
|
gc.collect()
|
||||||
|
assert capture == "Releasing parent."
|
||||||
|
|
||||||
|
with capture:
|
||||||
|
p = Parent()
|
||||||
|
assert capture == "Allocating parent."
|
||||||
|
with capture:
|
||||||
|
p.returnChildKeepAlive()
|
||||||
|
gc.collect()
|
||||||
|
assert capture == "Allocating child."
|
||||||
|
with capture:
|
||||||
|
del p
|
||||||
|
gc.collect()
|
||||||
|
assert capture == """
|
||||||
|
Releasing parent.
|
||||||
|
Releasing child.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_return_none(capture):
|
||||||
|
from pybind11_tests import Parent
|
||||||
|
|
||||||
|
with capture:
|
||||||
|
p = Parent()
|
||||||
|
assert capture == "Allocating parent."
|
||||||
|
with capture:
|
||||||
|
p.returnNullChildKeepAliveChild()
|
||||||
|
gc.collect()
|
||||||
|
assert capture == ""
|
||||||
|
with capture:
|
||||||
|
del p
|
||||||
|
gc.collect()
|
||||||
|
assert capture == "Releasing parent."
|
||||||
|
|
||||||
|
with capture:
|
||||||
|
p = Parent()
|
||||||
|
assert capture == "Allocating parent."
|
||||||
|
with capture:
|
||||||
|
p.returnNullChildKeepAliveParent()
|
||||||
|
gc.collect()
|
||||||
|
assert capture == ""
|
||||||
|
with capture:
|
||||||
|
del p
|
||||||
|
gc.collect()
|
||||||
|
assert capture == "Releasing parent."
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-arg-keywords-and-defaults.cpp -- keyword arguments and default values
|
tests/test_kwargs_and_defaults.cpp -- keyword arguments and default values
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
@ -7,16 +7,17 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include <pybind11/stl.h>
|
#include <pybind11/stl.h>
|
||||||
|
|
||||||
void kw_func(int x, int y) { std::cout << "kw_func(x=" << x << ", y=" << y << ")" << std::endl; }
|
std::string kw_func(int x, int y) { return "x=" + std::to_string(x) + ", y=" + std::to_string(y); }
|
||||||
|
|
||||||
void kw_func4(const std::vector<int> &entries) {
|
std::string kw_func4(const std::vector<int> &entries) {
|
||||||
std::cout << "kw_func4: ";
|
std::string ret = "{";
|
||||||
for (int i : entries)
|
for (int i : entries)
|
||||||
std::cout << i << " ";
|
ret += std::to_string(i) + " ";
|
||||||
std::cout << endl;
|
ret.back() = '}';
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
py::object call_kw_func(py::function f) {
|
py::object call_kw_func(py::function f) {
|
||||||
@ -26,18 +27,12 @@ py::object call_kw_func(py::function f) {
|
|||||||
return f(*args, **kwargs);
|
return f(*args, **kwargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void args_function(py::args args) {
|
py::tuple args_function(py::args args) {
|
||||||
for (size_t it=0; it<args.size(); ++it)
|
return args;
|
||||||
std::cout << "got argument: " << py::object(args[it]) << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void args_kwargs_function(py::args args, py::kwargs kwargs) {
|
py::tuple args_kwargs_function(py::args args, py::kwargs kwargs) {
|
||||||
for (auto item : args)
|
return py::make_tuple(args, kwargs);
|
||||||
std::cout << "got argument: " << item << std::endl;
|
|
||||||
if (kwargs) {
|
|
||||||
for (auto item : kwargs)
|
|
||||||
std::cout << "got keyword argument: " << item.first << " -> " << item.second << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct KWClass {
|
struct KWClass {
|
59
tests/test_kwargs_and_defaults.py
Normal file
59
tests/test_kwargs_and_defaults.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import pytest
|
||||||
|
from pybind11_tests import (kw_func0, kw_func1, kw_func2, kw_func3, kw_func4, call_kw_func,
|
||||||
|
args_function, args_kwargs_function, kw_func_udl, kw_func_udl_z,
|
||||||
|
KWClass)
|
||||||
|
|
||||||
|
|
||||||
|
def test_function_signatures(doc):
|
||||||
|
assert doc(kw_func0) == "kw_func0(arg0: int, arg1: int) -> str"
|
||||||
|
assert doc(kw_func1) == "kw_func1(x: int, y: int) -> str"
|
||||||
|
assert doc(kw_func2) == "kw_func2(x: int=100, y: int=200) -> str"
|
||||||
|
assert doc(kw_func3) == "kw_func3(data: str='Hello world!') -> None"
|
||||||
|
assert doc(kw_func4) == "kw_func4(myList: List[int]=[13, 17]) -> str"
|
||||||
|
assert doc(kw_func_udl) == "kw_func_udl(x: int, y: int=300) -> str"
|
||||||
|
assert doc(kw_func_udl_z) == "kw_func_udl_z(x: int, y: int=0) -> str"
|
||||||
|
assert doc(args_function) == "args_function(*args) -> tuple"
|
||||||
|
assert doc(args_kwargs_function) == "args_kwargs_function(*args, **kwargs) -> tuple"
|
||||||
|
assert doc(KWClass.foo0) == "foo0(self: m.KWClass, arg0: int, arg1: float) -> None"
|
||||||
|
assert doc(KWClass.foo1) == "foo1(self: m.KWClass, x: int, y: float) -> None"
|
||||||
|
|
||||||
|
|
||||||
|
def test_named_arguments(msg):
|
||||||
|
assert kw_func0(5, 10) == "x=5, y=10"
|
||||||
|
|
||||||
|
assert kw_func1(5, 10) == "x=5, y=10"
|
||||||
|
assert kw_func1(5, y=10) == "x=5, y=10"
|
||||||
|
assert kw_func1(y=10, x=5) == "x=5, y=10"
|
||||||
|
|
||||||
|
assert kw_func2() == "x=100, y=200"
|
||||||
|
assert kw_func2(5) == "x=5, y=200"
|
||||||
|
assert kw_func2(x=5) == "x=5, y=200"
|
||||||
|
assert kw_func2(y=10) == "x=100, y=10"
|
||||||
|
assert kw_func2(5, 10) == "x=5, y=10"
|
||||||
|
assert kw_func2(x=5, y=10) == "x=5, y=10"
|
||||||
|
|
||||||
|
with pytest.raises(TypeError) as excinfo:
|
||||||
|
# noinspection PyArgumentList
|
||||||
|
kw_func2(x=5, y=10, z=12)
|
||||||
|
assert msg(excinfo.value) == """
|
||||||
|
Incompatible function arguments. The following argument types are supported:
|
||||||
|
1. (x: int=100, y: int=200) -> str
|
||||||
|
Invoked with:
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert kw_func4() == "{13 17}"
|
||||||
|
assert kw_func4(myList=[1, 2, 3]) == "{1 2 3}"
|
||||||
|
|
||||||
|
assert kw_func_udl(x=5, y=10) == "x=5, y=10"
|
||||||
|
assert kw_func_udl_z(x=5) == "x=5, y=0"
|
||||||
|
|
||||||
|
|
||||||
|
def test_arg_and_kwargs():
|
||||||
|
assert call_kw_func(kw_func2) == "x=1234, y=5678"
|
||||||
|
|
||||||
|
args = 'arg1_value', 'arg2_value', 3
|
||||||
|
assert args_function(*args) == args
|
||||||
|
|
||||||
|
args = 'a1', 'a2'
|
||||||
|
kwargs = dict(arg3='a3', arg4=4)
|
||||||
|
assert args_kwargs_function(*args, **kwargs) == (args, kwargs)
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-methods-and-attributes.cpp -- constructors, deconstructors, attribute access,
|
tests/test_methods_and_attributes.cpp -- constructors, deconstructors, attribute access,
|
||||||
__str__, argument and return value conventions
|
__str__, argument and return value conventions
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
@ -8,8 +8,8 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include "constructor-stats.h"
|
#include "constructor_stats.h"
|
||||||
|
|
||||||
class ExampleMandA {
|
class ExampleMandA {
|
||||||
public:
|
public:
|
46
tests/test_methods_and_attributes.py
Normal file
46
tests/test_methods_and_attributes.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
from pybind11_tests import ExampleMandA, ConstructorStats
|
||||||
|
|
||||||
|
|
||||||
|
def test_methods_and_attributes():
|
||||||
|
instance1 = ExampleMandA()
|
||||||
|
instance2 = ExampleMandA(32)
|
||||||
|
|
||||||
|
instance1.add1(instance2)
|
||||||
|
instance1.add2(instance2)
|
||||||
|
instance1.add3(instance2)
|
||||||
|
instance1.add4(instance2)
|
||||||
|
instance1.add5(instance2)
|
||||||
|
instance1.add6(32)
|
||||||
|
instance1.add7(32)
|
||||||
|
instance1.add8(32)
|
||||||
|
instance1.add9(32)
|
||||||
|
instance1.add10(32)
|
||||||
|
|
||||||
|
assert str(instance1) == "ExampleMandA[value=320]"
|
||||||
|
assert str(instance2) == "ExampleMandA[value=32]"
|
||||||
|
assert str(instance1.self1()) == "ExampleMandA[value=320]"
|
||||||
|
assert str(instance1.self2()) == "ExampleMandA[value=320]"
|
||||||
|
assert str(instance1.self3()) == "ExampleMandA[value=320]"
|
||||||
|
assert str(instance1.self4()) == "ExampleMandA[value=320]"
|
||||||
|
assert str(instance1.self5()) == "ExampleMandA[value=320]"
|
||||||
|
|
||||||
|
assert instance1.internal1() == 320
|
||||||
|
assert instance1.internal2() == 320
|
||||||
|
assert instance1.internal3() == 320
|
||||||
|
assert instance1.internal4() == 320
|
||||||
|
assert instance1.internal5() == 320
|
||||||
|
|
||||||
|
assert instance1.value == 320
|
||||||
|
instance1.value = 100
|
||||||
|
assert str(instance1) == "ExampleMandA[value=100]"
|
||||||
|
|
||||||
|
cstats = ConstructorStats.get(ExampleMandA)
|
||||||
|
assert cstats.alive() == 2
|
||||||
|
del instance1, instance2
|
||||||
|
assert cstats.alive() == 0
|
||||||
|
assert cstats.values() == ["32"]
|
||||||
|
assert cstats.default_constructions == 1
|
||||||
|
assert cstats.copy_constructions == 3
|
||||||
|
assert cstats.move_constructions >= 1
|
||||||
|
assert cstats.copy_assignments == 0
|
||||||
|
assert cstats.move_assignments == 0
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-modules.cpp -- nested modules, importing modules, and
|
tests/test_modules.cpp -- nested modules, importing modules, and
|
||||||
internal references
|
internal references
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
@ -8,11 +8,11 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include "constructor-stats.h"
|
#include "constructor_stats.h"
|
||||||
|
|
||||||
void submodule_func() {
|
std::string submodule_func() {
|
||||||
std::cout << "submodule_func()" << std::endl;
|
return "submodule_func()";
|
||||||
}
|
}
|
||||||
|
|
||||||
class A {
|
class A {
|
54
tests/test_modules.py
Normal file
54
tests/test_modules.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
def test_nested_modules():
|
||||||
|
import pybind11_tests
|
||||||
|
from pybind11_tests.submodule import submodule_func
|
||||||
|
|
||||||
|
assert pybind11_tests.__name__ == "pybind11_tests"
|
||||||
|
assert pybind11_tests.submodule.__name__ == "pybind11_tests.submodule"
|
||||||
|
|
||||||
|
assert submodule_func() == "submodule_func()"
|
||||||
|
|
||||||
|
|
||||||
|
def test_reference_internal():
|
||||||
|
from pybind11_tests import ConstructorStats
|
||||||
|
from pybind11_tests.submodule import A, B
|
||||||
|
|
||||||
|
b = B()
|
||||||
|
assert str(b.get_a1()) == "A[1]"
|
||||||
|
assert str(b.a1) == "A[1]"
|
||||||
|
assert str(b.get_a2()) == "A[2]"
|
||||||
|
assert str(b.a2) == "A[2]"
|
||||||
|
|
||||||
|
b.a1 = A(42)
|
||||||
|
b.a2 = A(43)
|
||||||
|
assert str(b.get_a1()) == "A[42]"
|
||||||
|
assert str(b.a1) == "A[42]"
|
||||||
|
assert str(b.get_a2()) == "A[43]"
|
||||||
|
assert str(b.a2) == "A[43]"
|
||||||
|
|
||||||
|
astats, bstats = ConstructorStats.get(A), ConstructorStats.get(B)
|
||||||
|
assert astats.alive() == 2
|
||||||
|
assert bstats.alive() == 1
|
||||||
|
del b
|
||||||
|
assert astats.alive() == 0
|
||||||
|
assert bstats.alive() == 0
|
||||||
|
assert astats.values() == ['1', '2', '42', '43']
|
||||||
|
assert bstats.values() == []
|
||||||
|
assert astats.default_constructions == 0
|
||||||
|
assert bstats.default_constructions == 1
|
||||||
|
assert astats.copy_constructions == 0
|
||||||
|
assert bstats.copy_constructions == 0
|
||||||
|
# assert astats.move_constructions >= 0 # Don't invoke any
|
||||||
|
# assert bstats.move_constructions >= 0 # Don't invoke any
|
||||||
|
assert astats.copy_assignments == 2
|
||||||
|
assert bstats.copy_assignments == 0
|
||||||
|
assert astats.move_assignments == 0
|
||||||
|
assert bstats.move_assignments == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_importing():
|
||||||
|
from pybind11_tests import OD
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
assert OD is OrderedDict
|
||||||
|
assert str(OD([(1, 'a'), (2, 'b')])) == "OrderedDict([(1, 'a'), (2, 'b')])"
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-numpy-dtypes.cpp -- Structured and compound NumPy dtypes
|
tests/test_numpy_dtypes.cpp -- Structured and compound NumPy dtypes
|
||||||
|
|
||||||
Copyright (c) 2016 Ivan Smirnov
|
Copyright (c) 2016 Ivan Smirnov
|
||||||
|
|
||||||
@ -7,11 +7,8 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
#include <pybind11/numpy.h>
|
#include <pybind11/numpy.h>
|
||||||
#include <cstdint>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define PYBIND11_PACKED(cls) cls __attribute__((__packed__))
|
#define PYBIND11_PACKED(cls) cls __attribute__((__packed__))
|
||||||
@ -141,29 +138,48 @@ py::array_t<StringStruct, 0> create_string_array(bool non_empty) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
void print_recarray(py::array_t<S, 0> arr) {
|
py::list print_recarray(py::array_t<S, 0> arr) {
|
||||||
auto req = arr.request();
|
const auto req = arr.request();
|
||||||
auto ptr = static_cast<S*>(req.ptr);
|
const auto ptr = static_cast<S*>(req.ptr);
|
||||||
for (size_t i = 0; i < req.size; i++)
|
auto l = py::list();
|
||||||
std::cout << ptr[i] << std::endl;
|
for (size_t i = 0; i < req.size; i++) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << ptr[i];
|
||||||
|
l.append(py::str(ss.str()));
|
||||||
|
}
|
||||||
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_format_descriptors() {
|
py::list print_format_descriptors() {
|
||||||
std::cout << py::format_descriptor<SimpleStruct>::format() << std::endl;
|
const auto fmts = {
|
||||||
std::cout << py::format_descriptor<PackedStruct>::format() << std::endl;
|
py::format_descriptor<SimpleStruct>::format(),
|
||||||
std::cout << py::format_descriptor<NestedStruct>::format() << std::endl;
|
py::format_descriptor<PackedStruct>::format(),
|
||||||
std::cout << py::format_descriptor<PartialStruct>::format() << std::endl;
|
py::format_descriptor<NestedStruct>::format(),
|
||||||
std::cout << py::format_descriptor<PartialNestedStruct>::format() << std::endl;
|
py::format_descriptor<PartialStruct>::format(),
|
||||||
std::cout << py::format_descriptor<StringStruct>::format() << std::endl;
|
py::format_descriptor<PartialNestedStruct>::format(),
|
||||||
|
py::format_descriptor<StringStruct>::format()
|
||||||
|
};
|
||||||
|
auto l = py::list();
|
||||||
|
for (const auto &fmt : fmts) {
|
||||||
|
l.append(py::cast(fmt));
|
||||||
|
}
|
||||||
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_dtypes() {
|
py::list print_dtypes() {
|
||||||
std::cout << (std::string) py::dtype::of<SimpleStruct>().str() << std::endl;
|
const auto dtypes = {
|
||||||
std::cout << (std::string) py::dtype::of<PackedStruct>().str() << std::endl;
|
py::dtype::of<SimpleStruct>().str(),
|
||||||
std::cout << (std::string) py::dtype::of<NestedStruct>().str() << std::endl;
|
py::dtype::of<PackedStruct>().str(),
|
||||||
std::cout << (std::string) py::dtype::of<PartialStruct>().str() << std::endl;
|
py::dtype::of<NestedStruct>().str(),
|
||||||
std::cout << (std::string) py::dtype::of<PartialNestedStruct>().str() << std::endl;
|
py::dtype::of<PartialStruct>().str(),
|
||||||
std::cout << (std::string) py::dtype::of<StringStruct>().str() << std::endl;
|
py::dtype::of<PartialNestedStruct>().str(),
|
||||||
|
py::dtype::of<StringStruct>().str()
|
||||||
|
};
|
||||||
|
auto l = py::list();
|
||||||
|
for (const auto &s : dtypes) {
|
||||||
|
l.append(s);
|
||||||
|
}
|
||||||
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
py::array_t<int32_t, 0> test_array_ctors(int i) {
|
py::array_t<int32_t, 0> test_array_ctors(int i) {
|
157
tests/test_numpy_dtypes.py
Normal file
157
tests/test_numpy_dtypes.py
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import pytest
|
||||||
|
with pytest.suppress(ImportError):
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def assert_equal(actual, expected_data, expected_dtype):
|
||||||
|
np.testing.assert_equal(actual, np.array(expected_data, dtype=expected_dtype))
|
||||||
|
|
||||||
|
simple_dtype = np.dtype({'names': ['x', 'y', 'z'],
|
||||||
|
'formats': ['?', 'u4', 'f4'],
|
||||||
|
'offsets': [0, 4, 8]})
|
||||||
|
packed_dtype = np.dtype([('x', '?'), ('y', 'u4'), ('z', 'f4')])
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_numpy
|
||||||
|
def test_format_descriptors():
|
||||||
|
from pybind11_tests import get_format_unbound, print_format_descriptors
|
||||||
|
|
||||||
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
|
get_format_unbound()
|
||||||
|
assert 'unsupported buffer format' in str(excinfo.value)
|
||||||
|
|
||||||
|
assert print_format_descriptors() == [
|
||||||
|
"T{=?:x:3x=I:y:=f:z:}",
|
||||||
|
"T{=?:x:=I:y:=f:z:}",
|
||||||
|
"T{=T{=?:x:3x=I:y:=f:z:}:a:=T{=?:x:=I:y:=f:z:}:b:}",
|
||||||
|
"T{=?:x:3x=I:y:=f:z:12x}",
|
||||||
|
"T{8x=T{=?:x:3x=I:y:=f:z:12x}:a:8x}",
|
||||||
|
"T{=3s:a:=3s:b:}"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_numpy
|
||||||
|
def test_dtype():
|
||||||
|
from pybind11_tests import print_dtypes, test_dtype_ctors, test_dtype_methods
|
||||||
|
|
||||||
|
assert print_dtypes() == [
|
||||||
|
"{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':12}",
|
||||||
|
"[('x', '?'), ('y', '<u4'), ('z', '<f4')]",
|
||||||
|
"[('a', {'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':12}), ('b', [('x', '?'), ('y', '<u4'), ('z', '<f4')])]",
|
||||||
|
"{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}",
|
||||||
|
"{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}",
|
||||||
|
"[('a', 'S3'), ('b', 'S3')]"
|
||||||
|
]
|
||||||
|
|
||||||
|
d1 = np.dtype({'names': ['a', 'b'], 'formats': ['int32', 'float64'],
|
||||||
|
'offsets': [1, 10], 'itemsize': 20})
|
||||||
|
d2 = np.dtype([('a', 'i4'), ('b', 'f4')])
|
||||||
|
assert test_dtype_ctors() == [np.dtype('int32'), np.dtype('float64'),
|
||||||
|
np.dtype('bool'), d1, d1, np.dtype('uint32'), d2]
|
||||||
|
|
||||||
|
assert test_dtype_methods() == [np.dtype('int32'), simple_dtype, False, True,
|
||||||
|
np.dtype('int32').itemsize, simple_dtype.itemsize]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_numpy
|
||||||
|
def test_recarray():
|
||||||
|
from pybind11_tests import (create_rec_simple, create_rec_packed, create_rec_nested,
|
||||||
|
print_rec_simple, print_rec_packed, print_rec_nested,
|
||||||
|
create_rec_partial, create_rec_partial_nested)
|
||||||
|
|
||||||
|
elements = [(False, 0, 0.0), (True, 1, 1.5), (False, 2, 3.0)]
|
||||||
|
|
||||||
|
for func, dtype in [(create_rec_simple, simple_dtype), (create_rec_packed, packed_dtype)]:
|
||||||
|
arr = func(0)
|
||||||
|
assert arr.dtype == dtype
|
||||||
|
assert_equal(arr, [], simple_dtype)
|
||||||
|
assert_equal(arr, [], packed_dtype)
|
||||||
|
|
||||||
|
arr = func(3)
|
||||||
|
assert arr.dtype == dtype
|
||||||
|
assert_equal(arr, elements, simple_dtype)
|
||||||
|
assert_equal(arr, elements, packed_dtype)
|
||||||
|
|
||||||
|
if dtype == simple_dtype:
|
||||||
|
assert print_rec_simple(arr) == [
|
||||||
|
"s:0,0,0",
|
||||||
|
"s:1,1,1.5",
|
||||||
|
"s:0,2,3"
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
assert print_rec_packed(arr) == [
|
||||||
|
"p:0,0,0",
|
||||||
|
"p:1,1,1.5",
|
||||||
|
"p:0,2,3"
|
||||||
|
]
|
||||||
|
|
||||||
|
nested_dtype = np.dtype([('a', simple_dtype), ('b', packed_dtype)])
|
||||||
|
|
||||||
|
arr = create_rec_nested(0)
|
||||||
|
assert arr.dtype == nested_dtype
|
||||||
|
assert_equal(arr, [], nested_dtype)
|
||||||
|
|
||||||
|
arr = create_rec_nested(3)
|
||||||
|
assert arr.dtype == nested_dtype
|
||||||
|
assert_equal(arr, [((False, 0, 0.0), (True, 1, 1.5)),
|
||||||
|
((True, 1, 1.5), (False, 2, 3.0)),
|
||||||
|
((False, 2, 3.0), (True, 3, 4.5))], nested_dtype)
|
||||||
|
assert print_rec_nested(arr) == [
|
||||||
|
"n:a=s:0,0,0;b=p:1,1,1.5",
|
||||||
|
"n:a=s:1,1,1.5;b=p:0,2,3",
|
||||||
|
"n:a=s:0,2,3;b=p:1,3,4.5"
|
||||||
|
]
|
||||||
|
|
||||||
|
arr = create_rec_partial(3)
|
||||||
|
assert str(arr.dtype) == "{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}"
|
||||||
|
partial_dtype = arr.dtype
|
||||||
|
assert '' not in arr.dtype.fields
|
||||||
|
assert partial_dtype.itemsize > simple_dtype.itemsize
|
||||||
|
assert_equal(arr, elements, simple_dtype)
|
||||||
|
assert_equal(arr, elements, packed_dtype)
|
||||||
|
|
||||||
|
arr = create_rec_partial_nested(3)
|
||||||
|
assert str(arr.dtype) == "{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}"
|
||||||
|
assert '' not in arr.dtype.fields
|
||||||
|
assert '' not in arr.dtype.fields['a'][0].fields
|
||||||
|
assert arr.dtype.itemsize > partial_dtype.itemsize
|
||||||
|
np.testing.assert_equal(arr['a'], create_rec_partial(3))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_numpy
|
||||||
|
def test_array_constructors():
|
||||||
|
from pybind11_tests import test_array_ctors
|
||||||
|
|
||||||
|
data = np.arange(1, 7, dtype='int32')
|
||||||
|
for i in range(8):
|
||||||
|
np.testing.assert_array_equal(test_array_ctors(10 + i), data.reshape((3, 2)))
|
||||||
|
np.testing.assert_array_equal(test_array_ctors(20 + i), data.reshape((3, 2)))
|
||||||
|
for i in range(5):
|
||||||
|
np.testing.assert_array_equal(test_array_ctors(30 + i), data)
|
||||||
|
np.testing.assert_array_equal(test_array_ctors(40 + i), data)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_numpy
|
||||||
|
def test_string_array():
|
||||||
|
from pybind11_tests import create_string_array, print_string_array
|
||||||
|
|
||||||
|
arr = create_string_array(True)
|
||||||
|
assert str(arr.dtype) == "[('a', 'S3'), ('b', 'S3')]"
|
||||||
|
assert print_string_array(arr) == [
|
||||||
|
"a='',b=''",
|
||||||
|
"a='a',b='a'",
|
||||||
|
"a='ab',b='ab'",
|
||||||
|
"a='abc',b='abc'"
|
||||||
|
]
|
||||||
|
dtype = arr.dtype
|
||||||
|
assert arr['a'].tolist() == [b'', b'a', b'ab', b'abc']
|
||||||
|
assert arr['b'].tolist() == [b'', b'a', b'ab', b'abc']
|
||||||
|
arr = create_string_array(False)
|
||||||
|
assert dtype == arr.dtype
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_numpy
|
||||||
|
def test_signature(doc):
|
||||||
|
from pybind11_tests import create_rec_nested
|
||||||
|
|
||||||
|
assert doc(create_rec_nested) == "create_rec_nested(arg0: int) -> numpy.ndarray[NestedStruct]"
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-numpy-vectorize.cpp -- auto-vectorize functions over NumPy array
|
tests/test_numpy_vectorize.cpp -- auto-vectorize functions over NumPy array
|
||||||
arguments
|
arguments
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
@ -8,7 +8,7 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include <pybind11/numpy.h>
|
#include <pybind11/numpy.h>
|
||||||
|
|
||||||
double my_func(int x, float y, double z) {
|
double my_func(int x, float y, double z) {
|
||||||
@ -35,7 +35,7 @@ void init_ex_numpy_vectorize(py::module &m) {
|
|||||||
m.def("vectorized_func3", py::vectorize(my_func3));
|
m.def("vectorized_func3", py::vectorize(my_func3));
|
||||||
|
|
||||||
/// Numpy function which only accepts specific data types
|
/// Numpy function which only accepts specific data types
|
||||||
m.def("selective_func", [](py::array_t<int, py::array::c_style>) { std::cout << "Int branch taken. "<< std::endl; });
|
m.def("selective_func", [](py::array_t<int, py::array::c_style>) { return "Int branch taken."; });
|
||||||
m.def("selective_func", [](py::array_t<float, py::array::c_style>) { std::cout << "Float branch taken. "<< std::endl; });
|
m.def("selective_func", [](py::array_t<float, py::array::c_style>) { return "Float branch taken."; });
|
||||||
m.def("selective_func", [](py::array_t<std::complex<float>, py::array::c_style>) { std::cout << "Complex float branch taken. "<< std::endl; });
|
m.def("selective_func", [](py::array_t<std::complex<float>, py::array::c_style>) { return "Complex float branch taken."; });
|
||||||
}
|
}
|
74
tests/test_numpy_vectorize.py
Normal file
74
tests/test_numpy_vectorize.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
with pytest.suppress(ImportError):
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_numpy
|
||||||
|
def test_vectorize(capture):
|
||||||
|
from pybind11_tests import vectorized_func, vectorized_func2, vectorized_func3
|
||||||
|
|
||||||
|
assert np.isclose(vectorized_func3(np.array(3 + 7j)), [6 + 14j])
|
||||||
|
|
||||||
|
for f in [vectorized_func, vectorized_func2]:
|
||||||
|
with capture:
|
||||||
|
assert np.isclose(f(1, 2, 3), 6)
|
||||||
|
assert capture == "my_func(x:int=1, y:float=2, z:float=3)"
|
||||||
|
with capture:
|
||||||
|
assert np.isclose(f(np.array(1), np.array(2), 3), 6)
|
||||||
|
assert capture == "my_func(x:int=1, y:float=2, z:float=3)"
|
||||||
|
with capture:
|
||||||
|
assert np.allclose(f(np.array([1, 3]), np.array([2, 4]), 3), [6, 36])
|
||||||
|
assert capture == """
|
||||||
|
my_func(x:int=1, y:float=2, z:float=3)
|
||||||
|
my_func(x:int=3, y:float=4, z:float=3)
|
||||||
|
"""
|
||||||
|
with capture:
|
||||||
|
a, b, c = np.array([[1, 3, 5], [7, 9, 11]]), np.array([[2, 4, 6], [8, 10, 12]]), 3
|
||||||
|
assert np.allclose(f(a, b, c), a * b * c)
|
||||||
|
assert capture == """
|
||||||
|
my_func(x:int=1, y:float=2, z:float=3)
|
||||||
|
my_func(x:int=3, y:float=4, z:float=3)
|
||||||
|
my_func(x:int=5, y:float=6, z:float=3)
|
||||||
|
my_func(x:int=7, y:float=8, z:float=3)
|
||||||
|
my_func(x:int=9, y:float=10, z:float=3)
|
||||||
|
my_func(x:int=11, y:float=12, z:float=3)
|
||||||
|
"""
|
||||||
|
with capture:
|
||||||
|
a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2
|
||||||
|
assert np.allclose(f(a, b, c), a * b * c)
|
||||||
|
assert capture == """
|
||||||
|
my_func(x:int=1, y:float=2, z:float=2)
|
||||||
|
my_func(x:int=2, y:float=3, z:float=2)
|
||||||
|
my_func(x:int=3, y:float=4, z:float=2)
|
||||||
|
my_func(x:int=4, y:float=2, z:float=2)
|
||||||
|
my_func(x:int=5, y:float=3, z:float=2)
|
||||||
|
my_func(x:int=6, y:float=4, z:float=2)
|
||||||
|
"""
|
||||||
|
with capture:
|
||||||
|
a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2
|
||||||
|
assert np.allclose(f(a, b, c), a * b * c)
|
||||||
|
assert capture == """
|
||||||
|
my_func(x:int=1, y:float=2, z:float=2)
|
||||||
|
my_func(x:int=2, y:float=2, z:float=2)
|
||||||
|
my_func(x:int=3, y:float=2, z:float=2)
|
||||||
|
my_func(x:int=4, y:float=3, z:float=2)
|
||||||
|
my_func(x:int=5, y:float=3, z:float=2)
|
||||||
|
my_func(x:int=6, y:float=3, z:float=2)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_numpy
|
||||||
|
def test_type_selection():
|
||||||
|
from pybind11_tests import selective_func
|
||||||
|
|
||||||
|
assert selective_func(np.array([1], dtype=np.int32)) == "Int branch taken."
|
||||||
|
assert selective_func(np.array([1.0], dtype=np.float32)) == "Float branch taken."
|
||||||
|
assert selective_func(np.array([1.0j], dtype=np.complex64)) == "Complex float branch taken."
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.requires_numpy
|
||||||
|
def test_docs(doc):
|
||||||
|
from pybind11_tests import vectorized_func
|
||||||
|
|
||||||
|
assert doc(vectorized_func) == "vectorized_func(arg0: numpy.ndarray[int], arg1: numpy.ndarray[float], arg2: numpy.ndarray[float]) -> object"
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-opaque-types.cpp -- opaque types, passing void pointers
|
tests/test_opaque_types.cpp -- opaque types, passing void pointers
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
@ -7,7 +7,7 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include <pybind11/stl.h>
|
#include <pybind11/stl.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -38,21 +38,21 @@ void init_ex_opaque_types(py::module &m) {
|
|||||||
.def_readwrite("stringList", &ClassWithSTLVecProperty::stringList);
|
.def_readwrite("stringList", &ClassWithSTLVecProperty::stringList);
|
||||||
|
|
||||||
m.def("print_opaque_list", [](const StringList &l) {
|
m.def("print_opaque_list", [](const StringList &l) {
|
||||||
std::cout << "Opaque list: [";
|
std::string ret = "Opaque list: [";
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto entry : l) {
|
for (auto entry : l) {
|
||||||
if (!first)
|
if (!first)
|
||||||
std::cout << ", ";
|
ret += ", ";
|
||||||
std::cout << entry;
|
ret += entry;
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
std::cout << "]" << std::endl;
|
return ret + "]";
|
||||||
});
|
});
|
||||||
|
|
||||||
m.def("return_void_ptr", []() { return (void *) 0x1234; });
|
m.def("return_void_ptr", []() { return (void *) 0x1234; });
|
||||||
m.def("print_void_ptr", [](void *ptr) { std::cout << "Got void ptr : 0x" << std::hex << (uint64_t) ptr << std::endl; });
|
m.def("get_void_ptr_value", [](void *ptr) { return reinterpret_cast<std::intptr_t>(ptr); });
|
||||||
m.def("return_null_str", []() { return (char *) nullptr; });
|
m.def("return_null_str", []() { return (char *) nullptr; });
|
||||||
m.def("print_null_str", [](char *ptr) { std::cout << "Got null str : 0x" << std::hex << (uint64_t) ptr << std::endl; });
|
m.def("get_null_str_value", [](char *ptr) { return reinterpret_cast<std::intptr_t>(ptr); });
|
||||||
|
|
||||||
m.def("return_unique_ptr", []() -> std::unique_ptr<StringList> {
|
m.def("return_unique_ptr", []() -> std::unique_ptr<StringList> {
|
||||||
StringList *result = new StringList();
|
StringList *result = new StringList();
|
48
tests/test_opaque_types.py
Normal file
48
tests/test_opaque_types.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def test_string_list():
|
||||||
|
from pybind11_tests import StringList, ClassWithSTLVecProperty, print_opaque_list
|
||||||
|
|
||||||
|
l = StringList()
|
||||||
|
l.push_back("Element 1")
|
||||||
|
l.push_back("Element 2")
|
||||||
|
assert print_opaque_list(l) == "Opaque list: [Element 1, Element 2]"
|
||||||
|
assert l.back() == "Element 2"
|
||||||
|
|
||||||
|
for i, k in enumerate(l, start=1):
|
||||||
|
assert k == "Element {}".format(i)
|
||||||
|
l.pop_back()
|
||||||
|
assert print_opaque_list(l) == "Opaque list: [Element 1]"
|
||||||
|
|
||||||
|
cvp = ClassWithSTLVecProperty()
|
||||||
|
assert print_opaque_list(cvp.stringList) == "Opaque list: []"
|
||||||
|
|
||||||
|
cvp.stringList = l
|
||||||
|
cvp.stringList.push_back("Element 3")
|
||||||
|
assert print_opaque_list(cvp.stringList) == "Opaque list: [Element 1, Element 3]"
|
||||||
|
|
||||||
|
|
||||||
|
def test_pointers(msg):
|
||||||
|
from pybind11_tests import (return_void_ptr, get_void_ptr_value, ExampleMandA,
|
||||||
|
print_opaque_list, return_null_str, get_null_str_value,
|
||||||
|
return_unique_ptr, ConstructorStats)
|
||||||
|
|
||||||
|
assert get_void_ptr_value(return_void_ptr()) == 0x1234
|
||||||
|
assert get_void_ptr_value(ExampleMandA()) # Should also work for other C++ types
|
||||||
|
assert ConstructorStats.get(ExampleMandA).alive() == 0
|
||||||
|
|
||||||
|
with pytest.raises(TypeError) as excinfo:
|
||||||
|
get_void_ptr_value([1, 2, 3]) # This should not work
|
||||||
|
assert msg(excinfo.value) == """
|
||||||
|
Incompatible function arguments. The following argument types are supported:
|
||||||
|
1. (arg0: capsule) -> int
|
||||||
|
Invoked with: [1, 2, 3]
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert return_null_str() is None
|
||||||
|
assert get_null_str_value(return_null_str()) is not None
|
||||||
|
|
||||||
|
ptr = return_unique_ptr()
|
||||||
|
assert "StringList" in repr(ptr)
|
||||||
|
assert print_opaque_list(ptr) == "Opaque list: [some value]"
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-operator-overloading.cpp -- operator overloading
|
tests/test_operator_overloading.cpp -- operator overloading
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
@ -7,8 +7,8 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include "constructor-stats.h"
|
#include "constructor_stats.h"
|
||||||
#include <pybind11/operators.h>
|
#include <pybind11/operators.h>
|
||||||
|
|
||||||
class Vector2 {
|
class Vector2 {
|
41
tests/test_operator_overloading.py
Normal file
41
tests/test_operator_overloading.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
def test_operator_overloading():
|
||||||
|
from pybind11_tests import Vector2, Vector, ConstructorStats
|
||||||
|
|
||||||
|
v1 = Vector2(1, 2)
|
||||||
|
v2 = Vector(3, -1)
|
||||||
|
assert str(v1) == "[1.000000, 2.000000]"
|
||||||
|
assert str(v2) == "[3.000000, -1.000000]"
|
||||||
|
|
||||||
|
assert str(v1 + v2) == "[4.000000, 1.000000]"
|
||||||
|
assert str(v1 - v2) == "[-2.000000, 3.000000]"
|
||||||
|
assert str(v1 - 8) == "[-7.000000, -6.000000]"
|
||||||
|
assert str(v1 + 8) == "[9.000000, 10.000000]"
|
||||||
|
assert str(v1 * 8) == "[8.000000, 16.000000]"
|
||||||
|
assert str(v1 / 8) == "[0.125000, 0.250000]"
|
||||||
|
assert str(8 - v1) == "[7.000000, 6.000000]"
|
||||||
|
assert str(8 + v1) == "[9.000000, 10.000000]"
|
||||||
|
assert str(8 * v1) == "[8.000000, 16.000000]"
|
||||||
|
assert str(8 / v1) == "[8.000000, 4.000000]"
|
||||||
|
|
||||||
|
v1 += v2
|
||||||
|
v1 *= 2
|
||||||
|
assert str(v1) == "[8.000000, 2.000000]"
|
||||||
|
|
||||||
|
cstats = ConstructorStats.get(Vector2)
|
||||||
|
assert cstats.alive() == 2
|
||||||
|
del v1
|
||||||
|
assert cstats.alive() == 1
|
||||||
|
del v2
|
||||||
|
assert cstats.alive() == 0
|
||||||
|
assert cstats.values() == ['[1.000000, 2.000000]', '[3.000000, -1.000000]',
|
||||||
|
'[4.000000, 1.000000]', '[-2.000000, 3.000000]',
|
||||||
|
'[-7.000000, -6.000000]', '[9.000000, 10.000000]',
|
||||||
|
'[8.000000, 16.000000]', '[0.125000, 0.250000]',
|
||||||
|
'[7.000000, 6.000000]', '[9.000000, 10.000000]',
|
||||||
|
'[8.000000, 16.000000]', '[8.000000, 4.000000]']
|
||||||
|
assert cstats.default_constructions == 0
|
||||||
|
assert cstats.copy_constructions == 0
|
||||||
|
assert cstats.move_constructions >= 10
|
||||||
|
assert cstats.copy_assignments == 0
|
||||||
|
assert cstats.move_assignments == 0
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-pickling.cpp -- pickle support
|
tests/test_pickling.cpp -- pickle support
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
|
|
||||||
@ -7,7 +7,7 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
class Pickleable {
|
class Pickleable {
|
||||||
public:
|
public:
|
18
tests/test_pickling.py
Normal file
18
tests/test_pickling.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
try:
|
||||||
|
import cPickle as pickle # Use cPickle on Python 2.7
|
||||||
|
except ImportError:
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
from pybind11_tests import Pickleable
|
||||||
|
|
||||||
|
|
||||||
|
def test_roundtrip():
|
||||||
|
p = Pickleable("test_value")
|
||||||
|
p.setExtra1(15)
|
||||||
|
p.setExtra2(48)
|
||||||
|
|
||||||
|
data = pickle.dumps(p, 2) # Must use pickle protocol >= 2
|
||||||
|
p2 = pickle.loads(data)
|
||||||
|
assert p2.value() == p.value()
|
||||||
|
assert p2.extra1() == p.extra1()
|
||||||
|
assert p2.extra2() == p.extra2()
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example-python-types.cpp2 -- singleton design pattern, static functions and
|
tests/test_python_types.cpp -- singleton design pattern, static functions and
|
||||||
variables, passing and interacting with Python types
|
variables, passing and interacting with Python types
|
||||||
|
|
||||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||||
@ -8,8 +8,8 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "example.h"
|
#include "pybind11_tests.h"
|
||||||
#include "constructor-stats.h"
|
#include "constructor_stats.h"
|
||||||
#include <pybind11/stl.h>
|
#include <pybind11/stl.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user