mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-11 08:03:55 +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
|
||||
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...);
|
||||
}
|
||||
|
||||
/// 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),
|
||||
(typename detail::remove_class<decltype(
|
||||
&std::remove_reference<Func>::type::operator())>::type *) nullptr, extra...);
|
||||
@ -57,14 +57,14 @@ public:
|
||||
|
||||
/// Construct a cpp_function from a class method (non-const)
|
||||
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...); },
|
||||
(Return (*) (Class *, Arg...)) nullptr, extra...);
|
||||
}
|
||||
|
||||
/// Construct a cpp_function from a class method (const)
|
||||
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...); },
|
||||
(Return (*)(const Class *, Arg ...)) nullptr, extra...);
|
||||
}
|
||||
|
@ -53,6 +53,19 @@ public:
|
||||
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 {
|
||||
public:
|
||||
DynamicClass() { print_default_created(this); }
|
||||
@ -90,6 +103,20 @@ test_initializer methods_and_attributes([](py::module &m) {
|
||||
.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())
|
||||
.def(py::init());
|
||||
|
||||
|
@ -47,6 +47,44 @@ def test_methods_and_attributes():
|
||||
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():
|
||||
from pybind11_tests import DynamicClass, CppDerivedDynamicClass
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user