mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 21:25:13 +00:00
Fix def_property and related functions
Making `cppfunction` explicit broke `def_property` and friends. The added tests would not compile without an implicit `cppfunction`.
This commit is contained in:
parent
77898af0f8
commit
5b7e190fa2
@ -44,12 +44,12 @@ public:
|
|||||||
|
|
||||||
/// Construct a cpp_function from a vanilla function pointer
|
/// Construct a cpp_function from a vanilla function pointer
|
||||||
template <typename Return, typename... Args, typename... Extra>
|
template <typename Return, typename... Args, typename... Extra>
|
||||||
explicit cpp_function(Return (*f)(Args...), const Extra&... extra) {
|
cpp_function(Return (*f)(Args...), const Extra&... extra) {
|
||||||
initialize(f, f, extra...);
|
initialize(f, f, extra...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a cpp_function from a lambda function (possibly with internal state)
|
/// Construct a cpp_function from a lambda function (possibly with internal state)
|
||||||
template <typename Func, typename... Extra> explicit cpp_function(Func &&f, const Extra&... extra) {
|
template <typename Func, typename... Extra> cpp_function(Func &&f, const Extra&... extra) {
|
||||||
initialize(std::forward<Func>(f),
|
initialize(std::forward<Func>(f),
|
||||||
(typename detail::remove_class<decltype(
|
(typename detail::remove_class<decltype(
|
||||||
&std::remove_reference<Func>::type::operator())>::type *) nullptr, extra...);
|
&std::remove_reference<Func>::type::operator())>::type *) nullptr, extra...);
|
||||||
@ -57,14 +57,14 @@ public:
|
|||||||
|
|
||||||
/// Construct a cpp_function from a class method (non-const)
|
/// Construct a cpp_function from a class method (non-const)
|
||||||
template <typename Return, typename Class, typename... Arg, typename... Extra>
|
template <typename Return, typename Class, typename... Arg, typename... Extra>
|
||||||
explicit cpp_function(Return (Class::*f)(Arg...), const Extra&... extra) {
|
cpp_function(Return (Class::*f)(Arg...), const Extra&... extra) {
|
||||||
initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(args...); },
|
initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(args...); },
|
||||||
(Return (*) (Class *, Arg...)) nullptr, extra...);
|
(Return (*) (Class *, Arg...)) nullptr, extra...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a cpp_function from a class method (const)
|
/// Construct a cpp_function from a class method (const)
|
||||||
template <typename Return, typename Class, typename... Arg, typename... Extra>
|
template <typename Return, typename Class, typename... Arg, typename... Extra>
|
||||||
explicit cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) {
|
cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) {
|
||||||
initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); },
|
initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); },
|
||||||
(Return (*)(const Class *, Arg ...)) nullptr, extra...);
|
(Return (*)(const Class *, Arg ...)) nullptr, extra...);
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,19 @@ public:
|
|||||||
int value = 0;
|
int value = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TestProperties {
|
||||||
|
int value = 1;
|
||||||
|
static int static_value;
|
||||||
|
|
||||||
|
int get() const { return value; }
|
||||||
|
void set(int v) { value = v; }
|
||||||
|
|
||||||
|
static int static_get() { return static_value; }
|
||||||
|
static void static_set(int v) { static_value = v; }
|
||||||
|
};
|
||||||
|
|
||||||
|
int TestProperties::static_value = 1;
|
||||||
|
|
||||||
class DynamicClass {
|
class DynamicClass {
|
||||||
public:
|
public:
|
||||||
DynamicClass() { print_default_created(this); }
|
DynamicClass() { print_default_created(this); }
|
||||||
@ -90,6 +103,20 @@ test_initializer methods_and_attributes([](py::module &m) {
|
|||||||
.def_readwrite("value", &ExampleMandA::value)
|
.def_readwrite("value", &ExampleMandA::value)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
py::class_<TestProperties>(m, "TestProperties")
|
||||||
|
.def(py::init<>())
|
||||||
|
.def_readonly("def_readonly", &TestProperties::value)
|
||||||
|
.def_readwrite("def_readwrite", &TestProperties::value)
|
||||||
|
.def_property_readonly("def_property_readonly", &TestProperties::get)
|
||||||
|
.def_property("def_property", &TestProperties::get, &TestProperties::set)
|
||||||
|
.def_readonly_static("def_readonly_static", &TestProperties::static_value)
|
||||||
|
.def_readwrite_static("def_readwrite_static", &TestProperties::static_value)
|
||||||
|
.def_property_readonly_static("def_property_readonly_static",
|
||||||
|
[](py::object) { return TestProperties::static_get(); })
|
||||||
|
.def_property_static("def_property_static",
|
||||||
|
[](py::object) { return TestProperties::static_get(); },
|
||||||
|
[](py::object, int v) { return TestProperties::static_set(v); });
|
||||||
|
|
||||||
py::class_<DynamicClass>(m, "DynamicClass", py::dynamic_attr())
|
py::class_<DynamicClass>(m, "DynamicClass", py::dynamic_attr())
|
||||||
.def(py::init());
|
.def(py::init());
|
||||||
|
|
||||||
|
@ -47,6 +47,44 @@ def test_methods_and_attributes():
|
|||||||
assert cstats.move_assignments == 0
|
assert cstats.move_assignments == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_properties():
|
||||||
|
from pybind11_tests import TestProperties
|
||||||
|
|
||||||
|
instance = TestProperties()
|
||||||
|
|
||||||
|
assert instance.def_readonly == 1
|
||||||
|
with pytest.raises(AttributeError):
|
||||||
|
instance.def_readonly = 2
|
||||||
|
|
||||||
|
instance.def_readwrite = 2
|
||||||
|
assert instance.def_readwrite == 2
|
||||||
|
|
||||||
|
assert instance.def_property_readonly == 2
|
||||||
|
with pytest.raises(AttributeError):
|
||||||
|
instance.def_property_readonly = 3
|
||||||
|
|
||||||
|
instance.def_property = 3
|
||||||
|
assert instance.def_property == 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_static_properties():
|
||||||
|
from pybind11_tests import TestProperties as Type
|
||||||
|
|
||||||
|
assert Type.def_readonly_static == 1
|
||||||
|
with pytest.raises(AttributeError):
|
||||||
|
Type.def_readonly_static = 2
|
||||||
|
|
||||||
|
Type.def_readwrite_static = 2
|
||||||
|
assert Type.def_readwrite_static == 2
|
||||||
|
|
||||||
|
assert Type.def_property_readonly_static == 2
|
||||||
|
with pytest.raises(AttributeError):
|
||||||
|
Type.def_property_readonly_static = 3
|
||||||
|
|
||||||
|
Type.def_property_static = 3
|
||||||
|
assert Type.def_property_static == 3
|
||||||
|
|
||||||
|
|
||||||
def test_dynamic_attributes():
|
def test_dynamic_attributes():
|
||||||
from pybind11_tests import DynamicClass, CppDerivedDynamicClass
|
from pybind11_tests import DynamicClass, CppDerivedDynamicClass
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user