This adds the infrastructure for a separate test plugin for cross-module
tests. (This commit contains no tests that actually use it, but the
following commits do; this is separated simply to provide a cleaner
commit history).
At this point, there is only a single test for interpreter basics.
Apart from embedding itself, having a C++ test framework will also
benefit the C++-side features by allowing them to be tested directly.
All targets provided by pybind11:
* pybind11::module - the existing target for creating extension modules
* pybind11::embed - new target for embedding the interpreter
* pybind11::pybind11 - common "base" target (headers only)
MSVC by default uses the local codepage, which fails when it sees the
utf-8 in test_python_types.cpp. This adds the /utf-8 flag to the test
suite compilation to force it to interpret source code as utf-8.
Fixes#869
This commit allows type_casters to allow their local values to be moved
away, rather than copied, when the type caster instance itself is an rvalue.
This only applies (automatically) to type casters using
PYBIND11_TYPE_CASTER; the generic type type casters don't own their own
pointer, and various value casters (e.g. std::string, std::pair,
arithmetic types) already cast to an rvalue (i.e. they return by value).
This updates various calling code to attempt to get a movable value
whenever the value is itself coming from a type caster about to be
destroyed: for example, when constructing an std::pair or various stl.h
containers. For types that don't support value moving, the cast_op
falls back to an lvalue cast.
There wasn't an obvious place to add the tests, so I added them to
test_copy_move_policies, but also renamed it to drop the _policies as it
now tests more than just policies.
* Add `pytest.ini` config file and set default options there instead of
in `CMakeLists.txt` (command line arguments).
* Change all output capture from `capfd` (filedescriptors) to `capsys`
(Python's `sys.stdout` and `sys.stderr`). This avoids capturing
low-level C errors, e.g. from the debug build of Python.
* Set pytest minimum version to 3.0 to make it easier to use new
features. Removed conditional use of `excinfo.match()`.
* Clean up some leftover function-level `@pytest.requires_numpy`.
* Make tests buildable independently
This makes "tests" buildable as a separate project that uses
find_package(pybind11 CONFIG) when invoked independently.
This also moves the WERROR option into tests/CMakeLists.txt, as that's
the only place it is used.
* Use Eigen 3.3.1's cmake target, if available
This changes the eigen finding code to attempt to use Eigen's
system-installed Eigen3Config first. In Eigen 3.3.1, it exports a cmake
Eigen3::Eigen target to get dependencies from (rather than setting the
include path directly).
If it fails, we fall back to the trying to load allowing modules (i.e.
allowing our tools/FindEigen3.cmake). If we either fallback, or the
eigen version is older than 3.3.1 (or , we still set the include
directory manually; otherwise, for CONFIG + new Eigen, we get it via
the target.
This is also needed to allow 'tests' to be built independently, when
the find_package(Eigen3) is going to find via the system-installed
Eigen3Config.cmake.
* Add a install-then-build test, using clang on linux
This tests that `make install` to the actual system, followed by a build
of the tests (without the main pybind11 repository available) works as
expected.
To also expand the testing variety a bit, it also builds using
clang-3.9 instead of gcc.
* Don't try loading Eigen3Config in cmake < 3.0
It could FATAL_ERROR as the newer cmake includes a cmake 3.0 required
line.
If doing an independent, out-of-tree "tests" build, the regular
find_package(Eigen3) is likely to fail with the same error, but I think
we can just let that be: if you want a recent Eigen with proper cmake
loading support *and* want to do an independent tests build, you'll
need at least cmake 3.0.
Clang on linux currently fails to run cmake:
$ CC=clang CXX=clang++ cmake ..
...
-- Configuring done
CMake Error at tools/pybind11Tools.cmake:135 (target_compile_options):
Error evaluating generator expression:
$<:-flto>
Expression did not evaluate to a known generator expression
Call Stack (most recent call first):
tests/CMakeLists.txt:68 (pybind11_add_module)
But investigating this led to various other -flto detection problems;
this commit thus overhauls LTO flag detection:
- -flto needs to be passed to the linker as well
- Also compile with -fno-fat-lto-objects under GCC
- Pass the equivalent flags to MSVC
- Enable LTO flags for via generator expressions (for non-debug builds
only), so that multi-config builds (like on Windows) still work
properly. This seems reasonable, however, even on single-config
builds (and simplifies the cmake code a bit).
- clang's lto linker plugins don't accept '-Os', so replace it with
'-O3' when doing a MINSIZEREL build
- Enable trying ThinLTO by default for test suite (only affects clang)
- Match Clang$ rather than ^Clang$ because, for cmake with 3.0+
policies in effect, the compiler ID will be AppleClang on macOS.
Use PROJECT_SOURCE_DIR instead of CMAKE_SOURCE_DIR as the base of the
path to libsize.py. This fixes an error if pybind11 is being built
directly within another project.
On a debian jessie machine, running 'python --version --noconftest' caused
pytest to try and run the test suite with the not-yet-compiled extension
module, thus failing the test. This commit chages the pytest detection
so that it only attempts to run an import statement.
Add a BUILD_INTERFACE and a pybind11::pybind11 alias for the interface
library to match the installed target.
Add new cmake tests for add_subdirectory and consolidates the
.cpp and .py files needed for the cmake build tests:
Before:
tests
|-- test_installed_module
| |-- CMakeLists.txt
| |-- main.cpp
| \-- test.py
\-- test_installed_target
|-- CMakeLists.txt
|-- main.cpp
\-- test.py
After:
tests
\-- test_cmake_build
|-- installed_module/CMakeLists.txt
|-- installed_target/CMakeLists.txt
|-- subdirectory_module/CMakeLists.txt
|-- subdirectory_target/CMakeLists.txt
|-- main.cpp
\-- test.py
When working on some particular feature, it's nice to be able to disable
all the tests except for the one I'm working on; this is currently
possible by editing tests/CMakeLists.txt, and commenting out the tests
you don't want.
This commit goes a step further by letting you give a list of tests you
do want when invoking cmake, e.g.:
cmake -DPYBIND11_TEST_OVERRIDE="test_issues.cpp;test_pickling.cpp" ..
changes the build to build just those two tests (and changes the `pytest`
target to invoke just the two associated tests).
This persists in the build directory until you disable it again by
running cmake with `-DPYBIND11_TEST_OVERRIDE=`. It also adds a message
after the pytest output to remind you that it is in effect:
Note: not all tests run: -DPYBIND11_TEST_OVERRIDE is in effect
* Add debugging info about so size to build output
This adds a small python script to tools that captures before-and-after
.so sizes between builds and outputs this in the build output via a
string such as:
------ pybind11_tests.cpython-35m-x86_64-linux-gnu.so file size: 924696 (decrease of 73680 bytes = 7.38%)
------ pybind11_tests.cpython-35m-x86_64-linux-gnu.so file size: 998376 (increase of 73680 bytes = 7.97%)
------ pybind11_tests.cpython-35m-x86_64-linux-gnu.so file size: 998376 (no change)
Or, if there was no .so during the build, just the .so size by itself:
------ pybind11_tests.cpython-35m-x86_64-linux-gnu.so file size: 998376
This allows you to, for example, build, checkout a different branch,
rebuild, and easily see exactly the change in the pybind11_tests.so
size.
It also allows looking at the travis and appveyor build logs to get an
idea of .so/.dll sizes across different build systems.
* Minor libsize.py script changes
- Use RAII open
- Remove unused libsize=-1
- Report change as [+-]xyz bytes = [+-]a.bc%
This commit adds support for forcing alias type initialization by
defining constructors with `py::init_alias<arg1, arg2>()` instead of
`py::init<arg1, arg2>()`. Currently py::init<> only results in Alias
initialization if the type is extended in python, or the given
arguments can't be used to construct the base type, but can be used to
construct the alias. py::init_alias<>, in contrast, always invokes the
constructor of the alias type.
It looks like this was already the intention of
`py::detail::init_alias`, which was forward-declared in
86d825f330, but was apparently never
finished: despite the existance of a .def method accepting it, the
`detail::init_alias` class isn't actually defined anywhere.
This commit completes the feature (or possibly repurposes it), allowing
declaration of classes that will always initialize the trampoline which
is (as I argued in #397) sometimes useful.
The current pybind11::class_<Type, Holder, Trampoline> fixed template
ordering results in a requirement to repeat the Holder with its default
value (std::unique_ptr<Type>) argument, which is a little bit annoying:
it needs to be specified not because we want to override the default,
but rather because we need to specify the third argument.
This commit removes this limitation by making the class_ template take
the type name plus a parameter pack of options. It then extracts the
first valid holder type and the first subclass type for holder_type and
trampoline type_alias, respectively. (If unfound, both fall back to
their current defaults, `std::unique_ptr<type>` and `type`,
respectively). If any unmatched template arguments are provided, a
static assertion fails.
What this means is that you can specify or omit the arguments in any
order:
py::class_<A, PyA> c1(m, "A");
py::class_<B, PyB, std::shared_ptr<B>> c2(m, "B");
py::class_<C, std::shared_ptr<C>, PyB> c3(m, "C");
It also allows future class attributes (such as base types in the next
commit) to be passed as class template types rather than needing to use
a py::base<> wrapper.
Adding or removing tests is a little bit cumbersome currently: the test
needs to be added to CMakeLists.txt, the init function needs to be
predeclared in pybind11_tests.cpp, then called in the plugin
initialization. While this isn't a big deal for tests that are being
committed, it's more of a hassle when working on some new feature or
test code for which I temporarily only care about building and linking
the test being worked on rather than the entire test suite.
This commit changes tests to self-register their initialization by
having each test initialize a local object (which stores the
initialization function in a static variable). This makes changing the
set of tests being build easy: one only needs to add or comment out
test names in tests/CMakeLists.txt.
A couple other minor changes that go along with this:
- test_eigen.cpp is now included in the test list, then removed if eigen
isn't available. This lets you disable the eigen tests by commenting
it out, just like all the other tests, but keeps the build working
without eigen eigen isn't available. (Also, if it's commented out, we
don't even bother looking for and reporting the building with/without
eigen status message).
- pytest is now invoked with all the built test names (with .cpp changed
to .py) so that it doesn't try to run tests that weren't built.
Installing something outside the project directory from a cmake
invocation is overly intrusive; this changes tests/CMakeLists.txt to
just fail with an informative message instead, and changes the
travis-ci builds to install pytest via pip or apt-get.
Use simple asserts and pytest's powerful introspection to make testing
simpler. This merges the old .py/.ref file pairs into simple .py files
where the expected values are right next to the code being tested.
This commit does not touch the C++ part of the code and replicates the
Python tests exactly like the old .ref-file-based approach.