Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*
0002     tests/test_modules.cpp -- nested modules, importing modules, and
0003                             internal references
0004 
0005     Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
0006 
0007     All rights reserved. Use of this source code is governed by a
0008     BSD-style license that can be found in the LICENSE file.
0009 */
0010 
0011 #include "constructor_stats.h"
0012 #include "pybind11_tests.h"
0013 
0014 TEST_SUBMODULE(modules, m) {
0015     // test_nested_modules
0016     // This is intentionally "py::module" to verify it still can be used in place of "py::module_"
0017     py::module m_sub = m.def_submodule("subsubmodule");
0018     m_sub.def("submodule_func", []() { return "submodule_func()"; });
0019 
0020     // test_reference_internal
0021     class A {
0022     public:
0023         explicit A(int v) : v(v) { print_created(this, v); }
0024         ~A() { print_destroyed(this); }
0025         A(const A &) { print_copy_created(this); }
0026         A &operator=(const A &copy) {
0027             print_copy_assigned(this);
0028             v = copy.v;
0029             return *this;
0030         }
0031         std::string toString() const { return "A[" + std::to_string(v) + "]"; }
0032 
0033     private:
0034         int v;
0035     };
0036     py::class_<A>(m_sub, "A").def(py::init<int>()).def("__repr__", &A::toString);
0037 
0038     class B {
0039     public:
0040         B() { print_default_created(this); }
0041         ~B() { print_destroyed(this); }
0042         B(const B &) { print_copy_created(this); }
0043         B &operator=(const B &copy) {
0044             print_copy_assigned(this);
0045             a1 = copy.a1;
0046             a2 = copy.a2;
0047             return *this;
0048         }
0049         A &get_a1() { return a1; }
0050         A &get_a2() { return a2; }
0051 
0052         A a1{1};
0053         A a2{2};
0054     };
0055     py::class_<B>(m_sub, "B")
0056         .def(py::init<>())
0057         .def("get_a1",
0058              &B::get_a1,
0059              "Return the internal A 1",
0060              py::return_value_policy::reference_internal)
0061         .def("get_a2",
0062              &B::get_a2,
0063              "Return the internal A 2",
0064              py::return_value_policy::reference_internal)
0065         .def_readwrite("a1", &B::a1) // def_readonly uses an internal
0066                                      // reference return policy by default
0067         .def_readwrite("a2", &B::a2);
0068 
0069     // This is intentionally "py::module" to verify it still can be used in place of "py::module_"
0070     m.attr("OD") = py::module::import("collections").attr("OrderedDict");
0071 
0072     // test_duplicate_registration
0073     // Registering two things with the same name
0074     m.def("duplicate_registration", []() {
0075         class Dupe1 {};
0076         class Dupe2 {};
0077         class Dupe3 {};
0078         class DupeException {};
0079 
0080         // Go ahead and leak, until we have a non-leaking py::module_ constructor
0081         auto dm
0082             = py::module_::create_extension_module("dummy", nullptr, new py::module_::module_def);
0083         auto failures = py::list();
0084 
0085         py::class_<Dupe1>(dm, "Dupe1");
0086         py::class_<Dupe2>(dm, "Dupe2");
0087         dm.def("dupe1_factory", []() { return Dupe1(); });
0088         py::exception<DupeException>(dm, "DupeException");
0089 
0090         try {
0091             py::class_<Dupe1>(dm, "Dupe1");
0092             failures.append("Dupe1 class");
0093         } catch (std::runtime_error &) {
0094         }
0095         try {
0096             dm.def("Dupe1", []() { return Dupe1(); });
0097             failures.append("Dupe1 function");
0098         } catch (std::runtime_error &) {
0099         }
0100         try {
0101             py::class_<Dupe3>(dm, "dupe1_factory");
0102             failures.append("dupe1_factory");
0103         } catch (std::runtime_error &) {
0104         }
0105         try {
0106             py::exception<Dupe3>(dm, "Dupe2");
0107             failures.append("Dupe2");
0108         } catch (std::runtime_error &) {
0109         }
0110         try {
0111             dm.def("DupeException", []() { return 30; });
0112             failures.append("DupeException1");
0113         } catch (std::runtime_error &) {
0114         }
0115         try {
0116             py::class_<DupeException>(dm, "DupeException");
0117             failures.append("DupeException2");
0118         } catch (std::runtime_error &) {
0119         }
0120 
0121         return failures;
0122     });
0123 
0124     m.def("def_submodule", [](py::module_ m, const char *name) { return m.def_submodule(name); });
0125 }