Merge pull request #321 from dean0x7d/pytest

Port test suite to pytest
This commit is contained in:
Wenzel Jakob 2016-08-22 13:02:27 +02:00 committed by GitHub
commit faec30c4db
109 changed files with 2567 additions and 3168 deletions

View File

@ -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
View File

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

View File

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

View File

@ -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)
@ -154,9 +154,7 @@ function(pybind11_enable_warnings target_name)
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)

View File

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

View File

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

View File

@ -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()

View File

@ -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__)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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__)

View File

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

View File

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

View File

@ -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())

View File

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

View File

@ -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("")

View File

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

View File

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

View File

@ -1,5 +0,0 @@
from example import example_eval
example_eval()

View File

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

View File

@ -1 +0,0 @@
call_test2(y)

View File

@ -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__)

View File

@ -1,3 +0,0 @@
DerivedClass1
DerivedClass2
NoneType

View File

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

View File

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

View File

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

View File

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

View File

@ -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])

View File

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

View File

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

View File

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

View File

@ -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__)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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()))

View File

@ -1,2 +0,0 @@
test_value 15 48
test_value 15 48

View File

@ -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())

View File

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

View File

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

View File

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

View File

@ -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])

View File

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

View File

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

View File

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

View File

@ -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))])

View File

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

View File

@ -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()

View File

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

View File

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

View File

@ -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
View 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
View 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"),
}

View File

@ -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;
} }

View File

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

View File

@ -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,10 +75,14 @@ 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);
m.attr("have_eigen") = py::cast(true);
#else
m.attr("have_eigen") = py::cast(false);
#endif #endif
return m.ptr(); return m.ptr();

View File

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

View File

@ -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
View 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]"

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

View 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]"

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,4 @@
# This file is called from 'test_eval.py'
if 'call_test2' in locals():
call_test2(y)

View File

@ -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
View 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"

View File

@ -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
View 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"

View File

@ -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
View 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()

View File

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

View File

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

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

View File

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

View 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

View File

@ -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
View 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')])"

View File

@ -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
View 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]"

View File

@ -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."; });
} }

View 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"

View File

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

View 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]"

View File

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

View 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

View File

@ -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
View 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()

View File

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