blob: 1e243501aaee488bab203b8644775f4fb7820afd [file] [log] [blame]
Wenzel Jakob38bd7112015-07-05 20:05:44 +02001/*
Dean Moldovana0c1ccf2016-08-12 13:50:00 +02002 tests/pybind11_tests.cpp -- pybind example plugin
Wenzel Jakob38bd7112015-07-05 20:05:44 +02003
Wenzel Jakob8cb6cb32016-04-17 20:21:41 +02004 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
Wenzel Jakob38bd7112015-07-05 20:05:44 +02005
6 All rights reserved. Use of this source code is governed by a
7 BSD-style license that can be found in the LICENSE file.
8*/
9
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020010#include "pybind11_tests.h"
11#include "constructor_stats.h"
Wenzel Jakob38bd7112015-07-05 20:05:44 +020012
Jason Rhinelander0558a9a2017-02-01 04:36:29 -050013/*
14For testing purposes, we define a static global variable here in a function that each individual
15test .cpp calls with its initialization lambda. It's convenient here because we can just not
16compile some test files to disable/ignore some of the test code.
17
18It is NOT recommended as a way to use pybind11 in practice, however: the initialization order will
19be essentially random, which is okay for our test scripts (there are no dependencies between the
20individual pybind11 test .cpp files), but most likely not what you want when using pybind11
21productively.
22
23Instead, see the "How can I reduce the build time?" question in the "Frequently asked questions"
24section of the documentation for good practice on splitting binding code over multiple files.
25*/
Jason Rhinelander52f4be82016-09-03 14:54:22 -040026std::list<std::function<void(py::module &)>> &initializers() {
27 static std::list<std::function<void(py::module &)>> inits;
28 return inits;
29}
Wenzel Jakob38bd7112015-07-05 20:05:44 +020030
Jason Rhinelander52f4be82016-09-03 14:54:22 -040031test_initializer::test_initializer(std::function<void(py::module &)> initializer) {
32 initializers().push_back(std::move(initializer));
33}
Wenzel Jakob9e0a0562016-05-05 20:33:54 +020034
Jason Rhinelander3f589372016-08-07 13:05:26 -040035void bind_ConstructorStats(py::module &m) {
36 py::class_<ConstructorStats>(m, "ConstructorStats")
37 .def("alive", &ConstructorStats::alive)
38 .def("values", &ConstructorStats::values)
39 .def_readwrite("default_constructions", &ConstructorStats::default_constructions)
40 .def_readwrite("copy_assignments", &ConstructorStats::copy_assignments)
41 .def_readwrite("move_assignments", &ConstructorStats::move_assignments)
42 .def_readwrite("copy_constructions", &ConstructorStats::copy_constructions)
43 .def_readwrite("move_constructions", &ConstructorStats::move_constructions)
Jason Rhinelander14e70652017-04-21 17:14:22 -040044 .def_static("get", (ConstructorStats &(*)(py::object)) &ConstructorStats::get, py::return_value_policy::reference_internal)
45
46 // Not exactly ConstructorStats, but related: expose the internal pybind number of registered instances
47 // to allow instance cleanup checks (invokes a GC first)
48 .def_static("detail_reg_inst", []() {
49 ConstructorStats::gc();
50 return py::detail::get_internals().registered_instances.size();
51 })
52 ;
Jason Rhinelander3f589372016-08-07 13:05:26 -040053}
54
Dean Moldovan443ab592017-04-24 01:51:44 +020055PYBIND11_MODULE(pybind11_tests, m) {
56 m.doc() = "pybind11 test module";
Wenzel Jakob38bd7112015-07-05 20:05:44 +020057
Jason Rhinelander3f589372016-08-07 13:05:26 -040058 bind_ConstructorStats(m);
59
Jason Rhinelander52f4be82016-09-03 14:54:22 -040060 for (const auto &initializer : initializers())
61 initializer(m);
Wenzel Jakob38bd7112015-07-05 20:05:44 +020062
Jason Rhinelander3f1ff3f2016-12-12 17:42:52 -050063 if (!py::hasattr(m, "have_eigen")) m.attr("have_eigen") = false;
Wenzel Jakob38bd7112015-07-05 20:05:44 +020064}