mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-30 08:57:11 +00:00
Merge branch 'pybind:master' into master
This commit is contained in:
commit
940d9dc335
@ -190,6 +190,11 @@ private:
|
|||||||
bool rich_compare(object_api const &other, int value) const;
|
bool rich_compare(object_api const &other, int value) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using is_pyobj_ptr_or_nullptr_t = detail::any_of<std::is_same<T, PyObject *>,
|
||||||
|
std::is_same<T, PyObject *const>,
|
||||||
|
std::is_same<T, std::nullptr_t>>;
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(detail)
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
|
|
||||||
#if !defined(PYBIND11_HANDLE_REF_DEBUG) && !defined(NDEBUG)
|
#if !defined(PYBIND11_HANDLE_REF_DEBUG) && !defined(NDEBUG)
|
||||||
@ -211,9 +216,23 @@ class handle : public detail::object_api<handle> {
|
|||||||
public:
|
public:
|
||||||
/// The default constructor creates a handle with a ``nullptr``-valued pointer
|
/// The default constructor creates a handle with a ``nullptr``-valued pointer
|
||||||
handle() = default;
|
handle() = default;
|
||||||
/// Creates a ``handle`` from the given raw Python object pointer
|
|
||||||
|
/// Enable implicit conversion from ``PyObject *`` and ``nullptr``.
|
||||||
|
/// Not using ``handle(PyObject *ptr)`` to avoid implicit conversion from ``0``.
|
||||||
|
template <typename T,
|
||||||
|
detail::enable_if_t<detail::is_pyobj_ptr_or_nullptr_t<T>::value, int> = 0>
|
||||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
handle(PyObject *ptr) : m_ptr(ptr) {} // Allow implicit conversion from PyObject*
|
handle(T ptr) : m_ptr(ptr) {}
|
||||||
|
|
||||||
|
/// Enable implicit conversion through ``T::operator PyObject *()``.
|
||||||
|
template <
|
||||||
|
typename T,
|
||||||
|
detail::enable_if_t<detail::all_of<detail::none_of<std::is_base_of<handle, T>,
|
||||||
|
detail::is_pyobj_ptr_or_nullptr_t<T>>,
|
||||||
|
std::is_convertible<T, PyObject *>>::value,
|
||||||
|
int> = 0>
|
||||||
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
|
handle(T &obj) : m_ptr(obj) {}
|
||||||
|
|
||||||
/// Return the underlying ``PyObject *`` pointer
|
/// Return the underlying ``PyObject *`` pointer
|
||||||
PyObject *ptr() const { return m_ptr; }
|
PyObject *ptr() const { return m_ptr; }
|
||||||
|
@ -39,7 +39,68 @@ class float_ : public py::object {
|
|||||||
};
|
};
|
||||||
} // namespace external
|
} // namespace external
|
||||||
|
|
||||||
|
namespace implicit_conversion_from_0_to_handle {
|
||||||
|
// Uncomment to trigger compiler error. Note: Before PR #4008 this used to compile successfully.
|
||||||
|
// void expected_to_trigger_compiler_error() { py::handle(0); }
|
||||||
|
} // namespace implicit_conversion_from_0_to_handle
|
||||||
|
|
||||||
|
// Used to validate systematically that PR #4008 does/did NOT change the behavior.
|
||||||
|
void pure_compile_tests_for_handle_from_PyObject_pointers() {
|
||||||
|
{
|
||||||
|
PyObject *ptr = Py_None;
|
||||||
|
py::handle{ptr};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
PyObject *const ptr = Py_None;
|
||||||
|
py::handle{ptr};
|
||||||
|
}
|
||||||
|
// Uncomment to trigger compiler errors.
|
||||||
|
// PyObject const * ptr = Py_None; py::handle{ptr};
|
||||||
|
// PyObject const *const ptr = Py_None; py::handle{ptr};
|
||||||
|
// PyObject volatile * ptr = Py_None; py::handle{ptr};
|
||||||
|
// PyObject volatile *const ptr = Py_None; py::handle{ptr};
|
||||||
|
// PyObject const volatile * ptr = Py_None; py::handle{ptr};
|
||||||
|
// PyObject const volatile *const ptr = Py_None; py::handle{ptr};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace handle_from_move_only_type_with_operator_PyObject {
|
||||||
|
|
||||||
|
// Reduced from
|
||||||
|
// https://github.com/pytorch/pytorch/blob/279634f384662b7c3a9f8bf7ccc3a6afd2f05657/torch/csrc/utils/object_ptr.h
|
||||||
|
struct operator_ncnst {
|
||||||
|
operator_ncnst() = default;
|
||||||
|
operator_ncnst(operator_ncnst &&) = default;
|
||||||
|
operator PyObject *() /* */ { return Py_None; } // NOLINT(google-explicit-constructor)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct operator_const {
|
||||||
|
operator_const() = default;
|
||||||
|
operator_const(operator_const &&) = default;
|
||||||
|
operator PyObject *() const { return Py_None; } // NOLINT(google-explicit-constructor)
|
||||||
|
};
|
||||||
|
|
||||||
|
bool from_ncnst() {
|
||||||
|
operator_ncnst obj;
|
||||||
|
auto h = py::handle(obj); // Critical part of test: does this compile?
|
||||||
|
return h.ptr() == Py_None; // Just something.
|
||||||
|
}
|
||||||
|
|
||||||
|
bool from_const() {
|
||||||
|
operator_const obj;
|
||||||
|
auto h = py::handle(obj); // Critical part of test: does this compile?
|
||||||
|
return h.ptr() == Py_None; // Just something.
|
||||||
|
}
|
||||||
|
|
||||||
|
void m_defs(py::module_ &m) {
|
||||||
|
m.def("handle_from_move_only_type_with_operator_PyObject_ncnst", from_ncnst);
|
||||||
|
m.def("handle_from_move_only_type_with_operator_PyObject_const", from_const);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace handle_from_move_only_type_with_operator_PyObject
|
||||||
|
|
||||||
TEST_SUBMODULE(pytypes, m) {
|
TEST_SUBMODULE(pytypes, m) {
|
||||||
|
handle_from_move_only_type_with_operator_PyObject::m_defs(m);
|
||||||
|
|
||||||
// test_bool
|
// test_bool
|
||||||
m.def("get_bool", [] { return py::bool_(false); });
|
m.def("get_bool", [] { return py::bool_(false); });
|
||||||
// test_int
|
// test_int
|
||||||
|
@ -9,6 +9,11 @@ from pybind11_tests import detailed_error_messages_enabled
|
|||||||
from pybind11_tests import pytypes as m
|
from pybind11_tests import pytypes as m
|
||||||
|
|
||||||
|
|
||||||
|
def test_handle_from_move_only_type_with_operator_PyObject(): # noqa: N802
|
||||||
|
assert m.handle_from_move_only_type_with_operator_PyObject_ncnst()
|
||||||
|
assert m.handle_from_move_only_type_with_operator_PyObject_const()
|
||||||
|
|
||||||
|
|
||||||
def test_bool(doc):
|
def test_bool(doc):
|
||||||
assert doc(m.get_bool) == "get_bool() -> bool"
|
assert doc(m.get_bool) == "get_bool() -> bool"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user