test_methods_and_attributes.cpp revision 12037
111986Sandreas.sandberg@arm.com/*
211986Sandreas.sandberg@arm.com    tests/test_methods_and_attributes.cpp -- constructors, deconstructors, attribute access,
311986Sandreas.sandberg@arm.com    __str__, argument and return value conventions
411986Sandreas.sandberg@arm.com
511986Sandreas.sandberg@arm.com    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
611986Sandreas.sandberg@arm.com
711986Sandreas.sandberg@arm.com    All rights reserved. Use of this source code is governed by a
811986Sandreas.sandberg@arm.com    BSD-style license that can be found in the LICENSE file.
911986Sandreas.sandberg@arm.com*/
1011986Sandreas.sandberg@arm.com
1111986Sandreas.sandberg@arm.com#include "pybind11_tests.h"
1211986Sandreas.sandberg@arm.com#include "constructor_stats.h"
1311986Sandreas.sandberg@arm.com
1411986Sandreas.sandberg@arm.comclass ExampleMandA {
1511986Sandreas.sandberg@arm.compublic:
1611986Sandreas.sandberg@arm.com    ExampleMandA() { print_default_created(this); }
1711986Sandreas.sandberg@arm.com    ExampleMandA(int value) : value(value) { print_created(this, value); }
1811986Sandreas.sandberg@arm.com    ExampleMandA(const ExampleMandA &e) : value(e.value) { print_copy_created(this); }
1911986Sandreas.sandberg@arm.com    ExampleMandA(ExampleMandA &&e) : value(e.value) { print_move_created(this); }
2011986Sandreas.sandberg@arm.com    ~ExampleMandA() { print_destroyed(this); }
2111986Sandreas.sandberg@arm.com
2211986Sandreas.sandberg@arm.com    std::string toString() {
2311986Sandreas.sandberg@arm.com        return "ExampleMandA[value=" + std::to_string(value) + "]";
2411986Sandreas.sandberg@arm.com    }
2511986Sandreas.sandberg@arm.com
2611986Sandreas.sandberg@arm.com    void operator=(const ExampleMandA &e) { print_copy_assigned(this); value = e.value; }
2711986Sandreas.sandberg@arm.com    void operator=(ExampleMandA &&e) { print_move_assigned(this); value = e.value; }
2811986Sandreas.sandberg@arm.com
2911986Sandreas.sandberg@arm.com    void add1(ExampleMandA other) { value += other.value; }           // passing by value
3011986Sandreas.sandberg@arm.com    void add2(ExampleMandA &other) { value += other.value; }          // passing by reference
3111986Sandreas.sandberg@arm.com    void add3(const ExampleMandA &other) { value += other.value; }    // passing by const reference
3211986Sandreas.sandberg@arm.com    void add4(ExampleMandA *other) { value += other->value; }         // passing by pointer
3311986Sandreas.sandberg@arm.com    void add5(const ExampleMandA *other) { value += other->value; }   // passing by const pointer
3411986Sandreas.sandberg@arm.com
3511986Sandreas.sandberg@arm.com    void add6(int other) { value += other; }                      // passing by value
3611986Sandreas.sandberg@arm.com    void add7(int &other) { value += other; }                     // passing by reference
3711986Sandreas.sandberg@arm.com    void add8(const int &other) { value += other; }               // passing by const reference
3811986Sandreas.sandberg@arm.com    void add9(int *other) { value += *other; }                    // passing by pointer
3911986Sandreas.sandberg@arm.com    void add10(const int *other) { value += *other; }             // passing by const pointer
4011986Sandreas.sandberg@arm.com
4111986Sandreas.sandberg@arm.com    ExampleMandA self1() { return *this; }                            // return by value
4211986Sandreas.sandberg@arm.com    ExampleMandA &self2() { return *this; }                           // return by reference
4311986Sandreas.sandberg@arm.com    const ExampleMandA &self3() { return *this; }                     // return by const reference
4411986Sandreas.sandberg@arm.com    ExampleMandA *self4() { return this; }                            // return by pointer
4511986Sandreas.sandberg@arm.com    const ExampleMandA *self5() { return this; }                      // return by const pointer
4611986Sandreas.sandberg@arm.com
4711986Sandreas.sandberg@arm.com    int internal1() { return value; }                             // return by value
4811986Sandreas.sandberg@arm.com    int &internal2() { return value; }                            // return by reference
4911986Sandreas.sandberg@arm.com    const int &internal3() { return value; }                      // return by const reference
5011986Sandreas.sandberg@arm.com    int *internal4() { return &value; }                           // return by pointer
5111986Sandreas.sandberg@arm.com    const int *internal5() { return &value; }                     // return by const pointer
5211986Sandreas.sandberg@arm.com
5312037Sandreas.sandberg@arm.com    py::str overloaded(int, float)   { return "(int, float)"; }
5412037Sandreas.sandberg@arm.com    py::str overloaded(float, int)   { return "(float, int)"; }
5512037Sandreas.sandberg@arm.com    py::str overloaded(int, int)     { return "(int, int)"; }
5612037Sandreas.sandberg@arm.com    py::str overloaded(float, float) { return "(float, float)"; }
5712037Sandreas.sandberg@arm.com    py::str overloaded(int, float)   const { return "(int, float) const"; }
5812037Sandreas.sandberg@arm.com    py::str overloaded(float, int)   const { return "(float, int) const"; }
5912037Sandreas.sandberg@arm.com    py::str overloaded(int, int)     const { return "(int, int) const"; }
6012037Sandreas.sandberg@arm.com    py::str overloaded(float, float) const { return "(float, float) const"; }
6111986Sandreas.sandberg@arm.com
6211986Sandreas.sandberg@arm.com    int value = 0;
6311986Sandreas.sandberg@arm.com};
6411986Sandreas.sandberg@arm.com
6511986Sandreas.sandberg@arm.comstruct TestProperties {
6611986Sandreas.sandberg@arm.com    int value = 1;
6711986Sandreas.sandberg@arm.com    static int static_value;
6811986Sandreas.sandberg@arm.com
6911986Sandreas.sandberg@arm.com    int get() const { return value; }
7011986Sandreas.sandberg@arm.com    void set(int v) { value = v; }
7111986Sandreas.sandberg@arm.com
7211986Sandreas.sandberg@arm.com    static int static_get() { return static_value; }
7311986Sandreas.sandberg@arm.com    static void static_set(int v) { static_value = v; }
7411986Sandreas.sandberg@arm.com};
7511986Sandreas.sandberg@arm.com
7611986Sandreas.sandberg@arm.comint TestProperties::static_value = 1;
7711986Sandreas.sandberg@arm.com
7811986Sandreas.sandberg@arm.comstruct SimpleValue { int value = 1; };
7911986Sandreas.sandberg@arm.com
8011986Sandreas.sandberg@arm.comstruct TestPropRVP {
8111986Sandreas.sandberg@arm.com    SimpleValue v1;
8211986Sandreas.sandberg@arm.com    SimpleValue v2;
8311986Sandreas.sandberg@arm.com    static SimpleValue sv1;
8411986Sandreas.sandberg@arm.com    static SimpleValue sv2;
8511986Sandreas.sandberg@arm.com
8611986Sandreas.sandberg@arm.com    const SimpleValue &get1() const { return v1; }
8711986Sandreas.sandberg@arm.com    const SimpleValue &get2() const { return v2; }
8811986Sandreas.sandberg@arm.com    SimpleValue get_rvalue() const { return v2; }
8911986Sandreas.sandberg@arm.com    void set1(int v) { v1.value = v; }
9011986Sandreas.sandberg@arm.com    void set2(int v) { v2.value = v; }
9111986Sandreas.sandberg@arm.com};
9211986Sandreas.sandberg@arm.com
9311986Sandreas.sandberg@arm.comSimpleValue TestPropRVP::sv1{};
9411986Sandreas.sandberg@arm.comSimpleValue TestPropRVP::sv2{};
9511986Sandreas.sandberg@arm.com
9611986Sandreas.sandberg@arm.comclass DynamicClass {
9711986Sandreas.sandberg@arm.compublic:
9811986Sandreas.sandberg@arm.com    DynamicClass() { print_default_created(this); }
9911986Sandreas.sandberg@arm.com    ~DynamicClass() { print_destroyed(this); }
10011986Sandreas.sandberg@arm.com};
10111986Sandreas.sandberg@arm.com
10211986Sandreas.sandberg@arm.comclass CppDerivedDynamicClass : public DynamicClass { };
10311986Sandreas.sandberg@arm.com
10412037Sandreas.sandberg@arm.com// py::arg/py::arg_v testing: these arguments just record their argument when invoked
10512037Sandreas.sandberg@arm.comclass ArgInspector1 { public: std::string arg = "(default arg inspector 1)"; };
10612037Sandreas.sandberg@arm.comclass ArgInspector2 { public: std::string arg = "(default arg inspector 2)"; };
10712037Sandreas.sandberg@arm.comclass ArgAlwaysConverts { };
10812037Sandreas.sandberg@arm.comnamespace pybind11 { namespace detail {
10912037Sandreas.sandberg@arm.comtemplate <> struct type_caster<ArgInspector1> {
11012037Sandreas.sandberg@arm.compublic:
11112037Sandreas.sandberg@arm.com    PYBIND11_TYPE_CASTER(ArgInspector1, _("ArgInspector1"));
11212037Sandreas.sandberg@arm.com
11312037Sandreas.sandberg@arm.com    bool load(handle src, bool convert) {
11412037Sandreas.sandberg@arm.com        value.arg = "loading ArgInspector1 argument " +
11512037Sandreas.sandberg@arm.com            std::string(convert ? "WITH" : "WITHOUT") + " conversion allowed.  "
11612037Sandreas.sandberg@arm.com            "Argument value = " + (std::string) str(src);
11712037Sandreas.sandberg@arm.com        return true;
11812037Sandreas.sandberg@arm.com    }
11912037Sandreas.sandberg@arm.com
12012037Sandreas.sandberg@arm.com    static handle cast(const ArgInspector1 &src, return_value_policy, handle) {
12112037Sandreas.sandberg@arm.com        return str(src.arg).release();
12212037Sandreas.sandberg@arm.com    }
12312037Sandreas.sandberg@arm.com};
12412037Sandreas.sandberg@arm.comtemplate <> struct type_caster<ArgInspector2> {
12512037Sandreas.sandberg@arm.compublic:
12612037Sandreas.sandberg@arm.com    PYBIND11_TYPE_CASTER(ArgInspector2, _("ArgInspector2"));
12712037Sandreas.sandberg@arm.com
12812037Sandreas.sandberg@arm.com    bool load(handle src, bool convert) {
12912037Sandreas.sandberg@arm.com        value.arg = "loading ArgInspector2 argument " +
13012037Sandreas.sandberg@arm.com            std::string(convert ? "WITH" : "WITHOUT") + " conversion allowed.  "
13112037Sandreas.sandberg@arm.com            "Argument value = " + (std::string) str(src);
13212037Sandreas.sandberg@arm.com        return true;
13312037Sandreas.sandberg@arm.com    }
13412037Sandreas.sandberg@arm.com
13512037Sandreas.sandberg@arm.com    static handle cast(const ArgInspector2 &src, return_value_policy, handle) {
13612037Sandreas.sandberg@arm.com        return str(src.arg).release();
13712037Sandreas.sandberg@arm.com    }
13812037Sandreas.sandberg@arm.com};
13912037Sandreas.sandberg@arm.comtemplate <> struct type_caster<ArgAlwaysConverts> {
14012037Sandreas.sandberg@arm.compublic:
14112037Sandreas.sandberg@arm.com    PYBIND11_TYPE_CASTER(ArgAlwaysConverts, _("ArgAlwaysConverts"));
14212037Sandreas.sandberg@arm.com
14312037Sandreas.sandberg@arm.com    bool load(handle, bool convert) {
14412037Sandreas.sandberg@arm.com        return convert;
14512037Sandreas.sandberg@arm.com    }
14612037Sandreas.sandberg@arm.com
14712037Sandreas.sandberg@arm.com    static handle cast(const ArgAlwaysConverts &, return_value_policy, handle) {
14812037Sandreas.sandberg@arm.com        return py::none();
14912037Sandreas.sandberg@arm.com    }
15012037Sandreas.sandberg@arm.com};
15112037Sandreas.sandberg@arm.com}}
15212037Sandreas.sandberg@arm.com
15312037Sandreas.sandberg@arm.com/// Issue/PR #648: bad arg default debugging output
15412037Sandreas.sandberg@arm.comclass NotRegistered {};
15512037Sandreas.sandberg@arm.com
15611986Sandreas.sandberg@arm.comtest_initializer methods_and_attributes([](py::module &m) {
15711986Sandreas.sandberg@arm.com    py::class_<ExampleMandA>(m, "ExampleMandA")
15811986Sandreas.sandberg@arm.com        .def(py::init<>())
15911986Sandreas.sandberg@arm.com        .def(py::init<int>())
16011986Sandreas.sandberg@arm.com        .def(py::init<const ExampleMandA&>())
16111986Sandreas.sandberg@arm.com        .def("add1", &ExampleMandA::add1)
16211986Sandreas.sandberg@arm.com        .def("add2", &ExampleMandA::add2)
16311986Sandreas.sandberg@arm.com        .def("add3", &ExampleMandA::add3)
16411986Sandreas.sandberg@arm.com        .def("add4", &ExampleMandA::add4)
16511986Sandreas.sandberg@arm.com        .def("add5", &ExampleMandA::add5)
16611986Sandreas.sandberg@arm.com        .def("add6", &ExampleMandA::add6)
16711986Sandreas.sandberg@arm.com        .def("add7", &ExampleMandA::add7)
16811986Sandreas.sandberg@arm.com        .def("add8", &ExampleMandA::add8)
16911986Sandreas.sandberg@arm.com        .def("add9", &ExampleMandA::add9)
17011986Sandreas.sandberg@arm.com        .def("add10", &ExampleMandA::add10)
17111986Sandreas.sandberg@arm.com        .def("self1", &ExampleMandA::self1)
17211986Sandreas.sandberg@arm.com        .def("self2", &ExampleMandA::self2)
17311986Sandreas.sandberg@arm.com        .def("self3", &ExampleMandA::self3)
17411986Sandreas.sandberg@arm.com        .def("self4", &ExampleMandA::self4)
17511986Sandreas.sandberg@arm.com        .def("self5", &ExampleMandA::self5)
17611986Sandreas.sandberg@arm.com        .def("internal1", &ExampleMandA::internal1)
17711986Sandreas.sandberg@arm.com        .def("internal2", &ExampleMandA::internal2)
17811986Sandreas.sandberg@arm.com        .def("internal3", &ExampleMandA::internal3)
17911986Sandreas.sandberg@arm.com        .def("internal4", &ExampleMandA::internal4)
18011986Sandreas.sandberg@arm.com        .def("internal5", &ExampleMandA::internal5)
18111986Sandreas.sandberg@arm.com#if defined(PYBIND11_OVERLOAD_CAST)
18212037Sandreas.sandberg@arm.com        .def("overloaded", py::overload_cast<int,   float>(&ExampleMandA::overloaded))
18312037Sandreas.sandberg@arm.com        .def("overloaded", py::overload_cast<float,   int>(&ExampleMandA::overloaded))
18412037Sandreas.sandberg@arm.com        .def("overloaded", py::overload_cast<int,     int>(&ExampleMandA::overloaded))
18512037Sandreas.sandberg@arm.com        .def("overloaded", py::overload_cast<float, float>(&ExampleMandA::overloaded))
18612037Sandreas.sandberg@arm.com        .def("overloaded_float", py::overload_cast<float, float>(&ExampleMandA::overloaded))
18712037Sandreas.sandberg@arm.com        .def("overloaded_const", py::overload_cast<int,   float>(&ExampleMandA::overloaded, py::const_))
18812037Sandreas.sandberg@arm.com        .def("overloaded_const", py::overload_cast<float,   int>(&ExampleMandA::overloaded, py::const_))
18912037Sandreas.sandberg@arm.com        .def("overloaded_const", py::overload_cast<int,     int>(&ExampleMandA::overloaded, py::const_))
19012037Sandreas.sandberg@arm.com        .def("overloaded_const", py::overload_cast<float, float>(&ExampleMandA::overloaded, py::const_))
19111986Sandreas.sandberg@arm.com#else
19212037Sandreas.sandberg@arm.com        .def("overloaded", static_cast<py::str (ExampleMandA::*)(int,   float)>(&ExampleMandA::overloaded))
19312037Sandreas.sandberg@arm.com        .def("overloaded", static_cast<py::str (ExampleMandA::*)(float,   int)>(&ExampleMandA::overloaded))
19412037Sandreas.sandberg@arm.com        .def("overloaded", static_cast<py::str (ExampleMandA::*)(int,     int)>(&ExampleMandA::overloaded))
19512037Sandreas.sandberg@arm.com        .def("overloaded", static_cast<py::str (ExampleMandA::*)(float, float)>(&ExampleMandA::overloaded))
19612037Sandreas.sandberg@arm.com        .def("overloaded_float", static_cast<py::str (ExampleMandA::*)(float, float)>(&ExampleMandA::overloaded))
19712037Sandreas.sandberg@arm.com        .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int,   float) const>(&ExampleMandA::overloaded))
19812037Sandreas.sandberg@arm.com        .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float,   int) const>(&ExampleMandA::overloaded))
19912037Sandreas.sandberg@arm.com        .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int,     int) const>(&ExampleMandA::overloaded))
20012037Sandreas.sandberg@arm.com        .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float, float) const>(&ExampleMandA::overloaded))
20111986Sandreas.sandberg@arm.com#endif
20211986Sandreas.sandberg@arm.com        .def("__str__", &ExampleMandA::toString)
20312037Sandreas.sandberg@arm.com        .def_readwrite("value", &ExampleMandA::value);
20411986Sandreas.sandberg@arm.com
20511986Sandreas.sandberg@arm.com    py::class_<TestProperties>(m, "TestProperties")
20611986Sandreas.sandberg@arm.com        .def(py::init<>())
20711986Sandreas.sandberg@arm.com        .def_readonly("def_readonly", &TestProperties::value)
20811986Sandreas.sandberg@arm.com        .def_readwrite("def_readwrite", &TestProperties::value)
20911986Sandreas.sandberg@arm.com        .def_property_readonly("def_property_readonly", &TestProperties::get)
21011986Sandreas.sandberg@arm.com        .def_property("def_property", &TestProperties::get, &TestProperties::set)
21111986Sandreas.sandberg@arm.com        .def_readonly_static("def_readonly_static", &TestProperties::static_value)
21211986Sandreas.sandberg@arm.com        .def_readwrite_static("def_readwrite_static", &TestProperties::static_value)
21311986Sandreas.sandberg@arm.com        .def_property_readonly_static("def_property_readonly_static",
21411986Sandreas.sandberg@arm.com                                      [](py::object) { return TestProperties::static_get(); })
21511986Sandreas.sandberg@arm.com        .def_property_static("def_property_static",
21611986Sandreas.sandberg@arm.com                             [](py::object) { return TestProperties::static_get(); },
21712037Sandreas.sandberg@arm.com                             [](py::object, int v) { TestProperties::static_set(v); })
21812037Sandreas.sandberg@arm.com        .def_property_static("static_cls",
21912037Sandreas.sandberg@arm.com                             [](py::object cls) { return cls; },
22012037Sandreas.sandberg@arm.com                             [](py::object cls, py::function f) { f(cls); });
22111986Sandreas.sandberg@arm.com
22211986Sandreas.sandberg@arm.com    py::class_<SimpleValue>(m, "SimpleValue")
22311986Sandreas.sandberg@arm.com        .def_readwrite("value", &SimpleValue::value);
22411986Sandreas.sandberg@arm.com
22511986Sandreas.sandberg@arm.com    auto static_get1 = [](py::object) -> const SimpleValue & { return TestPropRVP::sv1; };
22611986Sandreas.sandberg@arm.com    auto static_get2 = [](py::object) -> const SimpleValue & { return TestPropRVP::sv2; };
22711986Sandreas.sandberg@arm.com    auto static_set1 = [](py::object, int v) { TestPropRVP::sv1.value = v; };
22811986Sandreas.sandberg@arm.com    auto static_set2 = [](py::object, int v) { TestPropRVP::sv2.value = v; };
22911986Sandreas.sandberg@arm.com    auto rvp_copy = py::return_value_policy::copy;
23011986Sandreas.sandberg@arm.com
23111986Sandreas.sandberg@arm.com    py::class_<TestPropRVP>(m, "TestPropRVP")
23211986Sandreas.sandberg@arm.com        .def(py::init<>())
23311986Sandreas.sandberg@arm.com        .def_property_readonly("ro_ref", &TestPropRVP::get1)
23411986Sandreas.sandberg@arm.com        .def_property_readonly("ro_copy", &TestPropRVP::get2, rvp_copy)
23511986Sandreas.sandberg@arm.com        .def_property_readonly("ro_func", py::cpp_function(&TestPropRVP::get2, rvp_copy))
23611986Sandreas.sandberg@arm.com        .def_property("rw_ref", &TestPropRVP::get1, &TestPropRVP::set1)
23711986Sandreas.sandberg@arm.com        .def_property("rw_copy", &TestPropRVP::get2, &TestPropRVP::set2, rvp_copy)
23811986Sandreas.sandberg@arm.com        .def_property("rw_func", py::cpp_function(&TestPropRVP::get2, rvp_copy), &TestPropRVP::set2)
23911986Sandreas.sandberg@arm.com        .def_property_readonly_static("static_ro_ref", static_get1)
24011986Sandreas.sandberg@arm.com        .def_property_readonly_static("static_ro_copy", static_get2, rvp_copy)
24111986Sandreas.sandberg@arm.com        .def_property_readonly_static("static_ro_func", py::cpp_function(static_get2, rvp_copy))
24211986Sandreas.sandberg@arm.com        .def_property_static("static_rw_ref", static_get1, static_set1)
24311986Sandreas.sandberg@arm.com        .def_property_static("static_rw_copy", static_get2, static_set2, rvp_copy)
24411986Sandreas.sandberg@arm.com        .def_property_static("static_rw_func", py::cpp_function(static_get2, rvp_copy), static_set2)
24511986Sandreas.sandberg@arm.com        .def_property_readonly("rvalue", &TestPropRVP::get_rvalue)
24611986Sandreas.sandberg@arm.com        .def_property_readonly_static("static_rvalue", [](py::object) { return SimpleValue(); });
24711986Sandreas.sandberg@arm.com
24812037Sandreas.sandberg@arm.com    struct MetaclassOverride { };
24912037Sandreas.sandberg@arm.com    py::class_<MetaclassOverride>(m, "MetaclassOverride", py::metaclass((PyObject *) &PyType_Type))
25012037Sandreas.sandberg@arm.com        .def_property_readonly_static("readonly", [](py::object) { return 1; });
25112037Sandreas.sandberg@arm.com
25212037Sandreas.sandberg@arm.com#if !defined(PYPY_VERSION)
25311986Sandreas.sandberg@arm.com    py::class_<DynamicClass>(m, "DynamicClass", py::dynamic_attr())
25411986Sandreas.sandberg@arm.com        .def(py::init());
25511986Sandreas.sandberg@arm.com
25611986Sandreas.sandberg@arm.com    py::class_<CppDerivedDynamicClass, DynamicClass>(m, "CppDerivedDynamicClass")
25711986Sandreas.sandberg@arm.com        .def(py::init());
25812037Sandreas.sandberg@arm.com#endif
25912037Sandreas.sandberg@arm.com
26012037Sandreas.sandberg@arm.com    // Test converting.  The ArgAlwaysConverts is just there to make the first no-conversion pass
26112037Sandreas.sandberg@arm.com    // fail so that our call always ends up happening via the second dispatch (the one that allows
26212037Sandreas.sandberg@arm.com    // some conversion).
26312037Sandreas.sandberg@arm.com    class ArgInspector {
26412037Sandreas.sandberg@arm.com    public:
26512037Sandreas.sandberg@arm.com        ArgInspector1 f(ArgInspector1 a, ArgAlwaysConverts) { return a; }
26612037Sandreas.sandberg@arm.com        std::string g(ArgInspector1 a, const ArgInspector1 &b, int c, ArgInspector2 *d, ArgAlwaysConverts) {
26712037Sandreas.sandberg@arm.com            return a.arg + "\n" + b.arg + "\n" + std::to_string(c) + "\n" + d->arg;
26812037Sandreas.sandberg@arm.com        }
26912037Sandreas.sandberg@arm.com        static ArgInspector2 h(ArgInspector2 a, ArgAlwaysConverts) { return a; }
27012037Sandreas.sandberg@arm.com    };
27112037Sandreas.sandberg@arm.com    py::class_<ArgInspector>(m, "ArgInspector")
27212037Sandreas.sandberg@arm.com        .def(py::init<>())
27312037Sandreas.sandberg@arm.com        .def("f", &ArgInspector::f, py::arg(), py::arg() = ArgAlwaysConverts())
27412037Sandreas.sandberg@arm.com        .def("g", &ArgInspector::g, "a"_a.noconvert(), "b"_a, "c"_a.noconvert()=13, "d"_a=ArgInspector2(), py::arg() = ArgAlwaysConverts())
27512037Sandreas.sandberg@arm.com        .def_static("h", &ArgInspector::h, py::arg().noconvert(), py::arg() = ArgAlwaysConverts())
27612037Sandreas.sandberg@arm.com        ;
27712037Sandreas.sandberg@arm.com    m.def("arg_inspect_func", [](ArgInspector2 a, ArgInspector1 b, ArgAlwaysConverts) { return a.arg + "\n" + b.arg; },
27812037Sandreas.sandberg@arm.com            py::arg().noconvert(false), py::arg_v(nullptr, ArgInspector1()).noconvert(true), py::arg() = ArgAlwaysConverts());
27912037Sandreas.sandberg@arm.com
28012037Sandreas.sandberg@arm.com    m.def("floats_preferred", [](double f) { return 0.5 * f; }, py::arg("f"));
28112037Sandreas.sandberg@arm.com    m.def("floats_only", [](double f) { return 0.5 * f; }, py::arg("f").noconvert());
28212037Sandreas.sandberg@arm.com
28312037Sandreas.sandberg@arm.com    /// Issue/PR #648: bad arg default debugging output
28412037Sandreas.sandberg@arm.com#if !defined(NDEBUG)
28512037Sandreas.sandberg@arm.com    m.attr("debug_enabled") = true;
28612037Sandreas.sandberg@arm.com#else
28712037Sandreas.sandberg@arm.com    m.attr("debug_enabled") = false;
28812037Sandreas.sandberg@arm.com#endif
28912037Sandreas.sandberg@arm.com    m.def("bad_arg_def_named", []{
29012037Sandreas.sandberg@arm.com        auto m = py::module::import("pybind11_tests.issues");
29112037Sandreas.sandberg@arm.com        m.def("should_fail", [](int, NotRegistered) {}, py::arg(), py::arg("a") = NotRegistered());
29212037Sandreas.sandberg@arm.com    });
29312037Sandreas.sandberg@arm.com    m.def("bad_arg_def_unnamed", []{
29412037Sandreas.sandberg@arm.com        auto m = py::module::import("pybind11_tests.issues");
29512037Sandreas.sandberg@arm.com        m.def("should_fail", [](int, NotRegistered) {}, py::arg(), py::arg() = NotRegistered());
29612037Sandreas.sandberg@arm.com    });
29711986Sandreas.sandberg@arm.com});
298