diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index dc753d32c..e54941485 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -1038,12 +1038,12 @@ public: Name(const object &o) \ : Parent(check_(o) ? o.inc_ref().ptr() : ConvertFun(o.ptr()), stolen_t{}) { \ if (!m_ptr) \ - throw error_already_set(); \ + throw ::pybind11::error_already_set(); \ } \ /* NOLINTNEXTLINE(google-explicit-constructor) */ \ Name(object &&o) : Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) { \ if (!m_ptr) \ - throw error_already_set(); \ + throw ::pybind11::error_already_set(); \ } #define PYBIND11_OBJECT_CVT_DEFAULT(Name, Parent, CheckFun, ConvertFun) \ diff --git a/tests/test_pytypes.cpp b/tests/test_pytypes.cpp index 1ed237ea2..b859497b8 100644 --- a/tests/test_pytypes.cpp +++ b/tests/test_pytypes.cpp @@ -11,6 +11,34 @@ #include +namespace external { +namespace detail { +bool check(PyObject *o) { return PyFloat_Check(o) != 0; } + +PyObject *conv(PyObject *o) { + PyObject *ret = nullptr; + if (PyLong_Check(o)) { + double v = PyLong_AsDouble(o); + if (!(v == -1.0 && PyErr_Occurred())) { + ret = PyFloat_FromDouble(v); + } + } else { + PyErr_SetString(PyExc_TypeError, "Unexpected type"); + } + return ret; +} + +PyObject *default_constructed() { return PyFloat_FromDouble(0.0); } +} // namespace detail +class float_ : public py::object { + PYBIND11_OBJECT_CVT(float_, py::object, external::detail::check, external::detail::conv) + + float_() : py::object(external::detail::default_constructed(), stolen_t{}) {} + + double get_value() const { return PyFloat_AsDouble(this->ptr()); } +}; +} // namespace external + TEST_SUBMODULE(pytypes, m) { // test_bool m.def("get_bool", [] { return py::bool_(false); }); @@ -545,4 +573,9 @@ TEST_SUBMODULE(pytypes, m) { py::detail::accessor_policies::tuple_item::set(o, (py::size_t) 0, s0); return o; }); + + m.def("square_float_", [](const external::float_ &x) -> double { + double v = x.get_value(); + return v * v; + }); } diff --git a/tests/test_pytypes.py b/tests/test_pytypes.py index becd1cc8a..85afb9423 100644 --- a/tests/test_pytypes.py +++ b/tests/test_pytypes.py @@ -634,3 +634,8 @@ def test_implementation_details(): assert m.tuple_item_set_ssize_t() == ("emely", "edmond") assert m.tuple_item_get_size_t(tup) == 93 assert m.tuple_item_set_size_t() == ("candy", "cat") + + +def test_external_float_(): + r1 = m.square_float_(2.0) + assert r1 == 4.0