Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:51

0001 /*
0002     tests/pybind11_tests.cpp -- pybind example plugin
0003 
0004     Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
0005 
0006     All rights reserved. Use of this source code is governed by a
0007     BSD-style license that can be found in the LICENSE file.
0008 */
0009 
0010 #include "pybind11_tests.h"
0011 
0012 #include "constructor_stats.h"
0013 
0014 #include <functional>
0015 #include <list>
0016 
0017 /*
0018 For testing purposes, we define a static global variable here in a function that each individual
0019 test .cpp calls with its initialization lambda.  It's convenient here because we can just not
0020 compile some test files to disable/ignore some of the test code.
0021 
0022 It is NOT recommended as a way to use pybind11 in practice, however: the initialization order will
0023 be essentially random, which is okay for our test scripts (there are no dependencies between the
0024 individual pybind11 test .cpp files), but most likely not what you want when using pybind11
0025 productively.
0026 
0027 Instead, see the "How can I reduce the build time?" question in the "Frequently asked questions"
0028 section of the documentation for good practice on splitting binding code over multiple files.
0029 */
0030 std::list<std::function<void(py::module_ &)>> &initializers() {
0031     static std::list<std::function<void(py::module_ &)>> inits;
0032     return inits;
0033 }
0034 
0035 test_initializer::test_initializer(Initializer init) { initializers().emplace_back(init); }
0036 
0037 test_initializer::test_initializer(const char *submodule_name, Initializer init) {
0038     initializers().emplace_back([=](py::module_ &parent) {
0039         auto m = parent.def_submodule(submodule_name);
0040         init(m);
0041     });
0042 }
0043 
0044 void bind_ConstructorStats(py::module_ &m) {
0045     py::class_<ConstructorStats>(m, "ConstructorStats")
0046         .def("alive", &ConstructorStats::alive)
0047         .def("values", &ConstructorStats::values)
0048         .def_readwrite("default_constructions", &ConstructorStats::default_constructions)
0049         .def_readwrite("copy_assignments", &ConstructorStats::copy_assignments)
0050         .def_readwrite("move_assignments", &ConstructorStats::move_assignments)
0051         .def_readwrite("copy_constructions", &ConstructorStats::copy_constructions)
0052         .def_readwrite("move_constructions", &ConstructorStats::move_constructions)
0053         .def_static("get",
0054                     (ConstructorStats & (*) (py::object)) & ConstructorStats::get,
0055                     py::return_value_policy::reference_internal)
0056 
0057         // Not exactly ConstructorStats, but related: expose the internal pybind number of
0058         // registered instances to allow instance cleanup checks (invokes a GC first)
0059         .def_static("detail_reg_inst", []() {
0060             ConstructorStats::gc();
0061             return py::detail::get_internals().registered_instances.size();
0062         });
0063 }
0064 
0065 const char *cpp_std() {
0066     return
0067 #if defined(PYBIND11_CPP20)
0068         "C++20";
0069 #elif defined(PYBIND11_CPP17)
0070         "C++17";
0071 #elif defined(PYBIND11_CPP14)
0072         "C++14";
0073 #else
0074         "C++11";
0075 #endif
0076 }
0077 
0078 PYBIND11_MODULE(pybind11_tests, m) {
0079     m.doc() = "pybind11 test module";
0080 
0081     // Intentionally kept minimal to not create a maintenance chore
0082     // ("just enough" to be conclusive).
0083 #if defined(_MSC_FULL_VER)
0084     m.attr("compiler_info") = "MSVC " PYBIND11_TOSTRING(_MSC_FULL_VER);
0085 #elif defined(__VERSION__)
0086     m.attr("compiler_info") = __VERSION__;
0087 #else
0088     m.attr("compiler_info") = py::none();
0089 #endif
0090     m.attr("cpp_std") = cpp_std();
0091     m.attr("PYBIND11_INTERNALS_ID") = PYBIND11_INTERNALS_ID;
0092     m.attr("PYBIND11_SIMPLE_GIL_MANAGEMENT") =
0093 #if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
0094         true;
0095 #else
0096         false;
0097 #endif
0098 
0099     bind_ConstructorStats(m);
0100 
0101 #if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
0102     m.attr("detailed_error_messages_enabled") = true;
0103 #else
0104     m.attr("detailed_error_messages_enabled") = false;
0105 #endif
0106 
0107     py::class_<UserType>(m, "UserType", "A `py::class_` type for testing")
0108         .def(py::init<>())
0109         .def(py::init<int>())
0110         .def("get_value", &UserType::value, "Get value using a method")
0111         .def("set_value", &UserType::set, "Set value using a method")
0112         .def_property("value", &UserType::value, &UserType::set, "Get/set value using a property")
0113         .def("__repr__", [](const UserType &u) { return "UserType({})"_s.format(u.value()); });
0114 
0115     py::class_<IncType, UserType>(m, "IncType")
0116         .def(py::init<>())
0117         .def(py::init<int>())
0118         .def("__repr__", [](const IncType &u) { return "IncType({})"_s.format(u.value()); });
0119 
0120     for (const auto &initializer : initializers()) {
0121         initializer(m);
0122     }
0123 }