Commit faec30c4 authored by Wenzel Jakob's avatar Wenzel Jakob Committed by GitHub
Browse files

Merge pull request #321 from dean0x7d/pytest

Port test suite to pytest
parents bf099587 99dbdc16
...@@ -5,7 +5,6 @@ platform: ...@@ -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: ...@@ -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: ...@@ -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%
...@@ -3,10 +3,9 @@ CMakeFiles ...@@ -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 ...@@ -32,3 +31,4 @@ MANIFEST
/dist /dist
/build /build
/cmake/ /cmake/
.cache/
...@@ -39,7 +39,7 @@ matrix: ...@@ -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: ...@@ -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: ...@@ -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
# 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 ...@@ -20,7 +20,7 @@ option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJE
option(PYBIND11_WERROR "Report all warnings as errors" OFF) option(PYBIND11_WERROR "Report all warnings as errors" OFF)
# Add a CMake parameter for choosing a desired Python version # Add a CMake parameter for choosing a desired Python version
set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling the example application") set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling modules")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/tools") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/tools")
set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7) set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
...@@ -146,17 +146,15 @@ function(pybind11_enable_warnings target_name) ...@@ -146,17 +146,15 @@ function(pybind11_enable_warnings target_name)
if(PYBIND11_WERROR) if(PYBIND11_WERROR)
if(MSVC) if(MSVC)
target_compile_options(${target_name} PRIVATE /WX) target_compile_options(${target_name} PRIVATE /WX)
else() else()
target_compile_options(${target_name} PRIVATE -Werror) target_compile_options(${target_name} PRIVATE -Werror)
endif() endif()
endif() endif()
endfunction() endfunction()
if (PYBIND11_TEST) if (PYBIND11_TEST)
enable_testing() add_subdirectory(tests)
add_subdirectory(example)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> DEPENDS example)
endif() endif()
if (PYBIND11_INSTALL) if (PYBIND11_INSTALL)
......
...@@ -102,7 +102,7 @@ C++ side, or to perform other types of customization. ...@@ -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. ...@@ -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. ...@@ -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``: ...@@ -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. ...@@ -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. ...@@ -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: ...@@ -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. ...@@ -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). ...@@ -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. ...@@ -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. ...@@ -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`. ...@@ -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``). ...@@ -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. ...@@ -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: ...@@ -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. ...@@ -1799,7 +1799,7 @@ memory corruption and/or segmentation faults.
.. seealso:: .. seealso::
The file :file:`example/example-pickling.cpp` contains a complete example The file :file:`tests/test_pickling.cpp` contains a complete example
that demonstrates how to pickle and unpickle types using pybind11 in more that demonstrates how to pickle and unpickle types using pybind11 in more
detail. detail.
......
...@@ -5,7 +5,7 @@ First steps ...@@ -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 ...@@ -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:
.. Note:: .. code-block:: batch
mkdir build
cd build
cmake ..
cmake --build . --config Release --target pytest
When all tests fail, make sure that This will create a Visual Studio project, compile and run the target, all from the
command line.
1. The Python binary and the testcases are compiled for the same processor .. Note::
type and bitness (i.e. either **i386** or **x86_64**)
2. The Python binary used to run :file:`example\\run_test.py` matches the If all tests fail, make sure that the Python binary and the testcases are compiled
Python version specified in the CMake GUI. This is controlled via for the same processor type and bitness (i.e. either **i386** or **x86_64**). You
the ``PYTHON_EXECUTABLE`` ``PYTHON_INCLUDE_DIR``, and can specify **x86_64** as the target architecture for the generated Visual Studio
``PYTHON_LIBRARY`` variables. project using ``cmake -A x64 ..``.
.. 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
......
# 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()
#!/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__)
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]
#!/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)
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)
#!/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)
### 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
#!/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__)
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]
#!/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())
<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
#!/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("")
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
/*
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);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment