1/* 2 tests/test_modules.cpp -- nested modules, importing modules, and 3 internal references 4 5 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch> 6 7 All rights reserved. Use of this source code is governed by a 8 BSD-style license that can be found in the LICENSE file. 9*/ 10 11#include "pybind11_tests.h" 12#include "constructor_stats.h" 13 14TEST_SUBMODULE(modules, m) { 15 // test_nested_modules 16 py::module m_sub = m.def_submodule("subsubmodule"); 17 m_sub.def("submodule_func", []() { return "submodule_func()"; }); 18 19 // test_reference_internal 20 class A { 21 public: 22 A(int v) : v(v) { print_created(this, v); } 23 ~A() { print_destroyed(this); } 24 A(const A&) { print_copy_created(this); } 25 A& operator=(const A ©) { print_copy_assigned(this); v = copy.v; return *this; } 26 std::string toString() { return "A[" + std::to_string(v) + "]"; } 27 private: 28 int v; 29 }; 30 py::class_<A>(m_sub, "A") 31 .def(py::init<int>()) 32 .def("__repr__", &A::toString); 33 34 class B { 35 public: 36 B() { print_default_created(this); } 37 ~B() { print_destroyed(this); } 38 B(const B&) { print_copy_created(this); } 39 B& operator=(const B ©) { print_copy_assigned(this); a1 = copy.a1; a2 = copy.a2; return *this; } 40 A &get_a1() { return a1; } 41 A &get_a2() { return a2; } 42 43 A a1{1}; 44 A a2{2}; 45 }; 46 py::class_<B>(m_sub, "B") 47 .def(py::init<>()) 48 .def("get_a1", &B::get_a1, "Return the internal A 1", py::return_value_policy::reference_internal) 49 .def("get_a2", &B::get_a2, "Return the internal A 2", py::return_value_policy::reference_internal) 50 .def_readwrite("a1", &B::a1) // def_readonly uses an internal reference return policy by default 51 .def_readwrite("a2", &B::a2); 52 53 m.attr("OD") = py::module::import("collections").attr("OrderedDict"); 54 55 // test_duplicate_registration 56 // Registering two things with the same name 57 m.def("duplicate_registration", []() { 58 class Dupe1 { }; 59 class Dupe2 { }; 60 class Dupe3 { }; 61 class DupeException { }; 62 63 auto dm = py::module("dummy"); 64 auto failures = py::list(); 65 66 py::class_<Dupe1>(dm, "Dupe1"); 67 py::class_<Dupe2>(dm, "Dupe2"); 68 dm.def("dupe1_factory", []() { return Dupe1(); }); 69 py::exception<DupeException>(dm, "DupeException"); 70 71 try { 72 py::class_<Dupe1>(dm, "Dupe1"); 73 failures.append("Dupe1 class"); 74 } catch (std::runtime_error &) {} 75 try { 76 dm.def("Dupe1", []() { return Dupe1(); }); 77 failures.append("Dupe1 function"); 78 } catch (std::runtime_error &) {} 79 try { 80 py::class_<Dupe3>(dm, "dupe1_factory"); 81 failures.append("dupe1_factory"); 82 } catch (std::runtime_error &) {} 83 try { 84 py::exception<Dupe3>(dm, "Dupe2"); 85 failures.append("Dupe2"); 86 } catch (std::runtime_error &) {} 87 try { 88 dm.def("DupeException", []() { return 30; }); 89 failures.append("DupeException1"); 90 } catch (std::runtime_error &) {} 91 try { 92 py::class_<DupeException>(dm, "DupeException"); 93 failures.append("DupeException2"); 94 } catch (std::runtime_error &) {} 95 96 return failures; 97 }); 98} 99