diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 92316c38c..d7fa17775 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -431,8 +431,8 @@ class accessor : public object_api> { public: accessor(handle obj, key_type key) : obj(obj), key(std::move(key)) { } - accessor(const accessor &a) = default; - accessor(accessor &&a) = default; + accessor(const accessor &) = default; + accessor(accessor &&) = default; // accessor overload required to override default assignment operator (templates are not allowed // to replace default compiler-generated assignments). @@ -743,7 +743,9 @@ NAMESPACE_END(detail) { if (!m_ptr) throw error_already_set(); } \ Name(object &&o) \ : Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) \ - { if (!m_ptr) throw error_already_set(); } + { if (!m_ptr) throw error_already_set(); } \ + template \ + Name(const ::pybind11::detail::accessor &a) : Name(object(a)) { } #define PYBIND11_OBJECT(Name, Parent, CheckFun) \ PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \ diff --git a/tests/test_pytypes.cpp b/tests/test_pytypes.cpp index 474223674..a962f0ccc 100644 --- a/tests/test_pytypes.cpp +++ b/tests/test_pytypes.cpp @@ -128,6 +128,12 @@ TEST_SUBMODULE(pytypes, m) { d["operator()"] = o.attr("func")(1); d["operator*"] = o.attr("func")(*o.attr("begin_end")); + // Test implicit conversion + py::list implicit_list = o.attr("begin_end"); + d["implicit_list"] = implicit_list; + py::dict implicit_dict = o.attr("__dict__"); + d["implicit_dict"] = implicit_dict; + return d; }); diff --git a/tests/test_pytypes.py b/tests/test_pytypes.py index 2487cf666..94c90a909 100644 --- a/tests/test_pytypes.py +++ b/tests/test_pytypes.py @@ -144,6 +144,8 @@ def test_accessors(): assert d["is_none"] is False assert d["operator()"] == 2 assert d["operator*"] == 7 + assert d["implicit_list"] == [1, 2, 3] + assert all(x in TestObject.__dict__ for x in d["implicit_dict"]) assert m.tuple_accessor(tuple()) == (0, 1, 2)