diff --git a/include/pybind11/eigen.h b/include/pybind11/eigen.h index b78045520..7698ae20f 100644 --- a/include/pybind11/eigen.h +++ b/include/pybind11/eigen.h @@ -551,7 +551,7 @@ struct type_caster::value>> { object matrix_type = sparse_module.attr( rowMajor ? "csr_matrix" : "csc_matrix"); - if (obj.get_type() != matrix_type.ptr()) { + if (!obj.get_type().is(matrix_type)) { try { obj = matrix_type(obj); } catch (const error_already_set &) { diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 62ee78624..79d02683b 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -278,7 +278,7 @@ protected: chain = (detail::function_record *) rec_capsule; /* Never append a method to an overload chain of a parent class; instead, hide the parent's overloads in this case */ - if (chain->scope != rec->scope) + if (!chain->scope.is(rec->scope)) chain = nullptr; } // Don't trigger for things like the default __init__, which are wrapper_descriptors that we are intentionally replacing @@ -1274,7 +1274,7 @@ template struct init { using Alias = typename Class::type_alias; handle cl_type = cl; cl.def("__init__", [cl_type](handle self_, Args... args) { - if (self_.get_type() == cl_type) + if (self_.get_type().is(cl_type)) new (self_.cast()) Base(args...); else new (self_.cast()) Alias(args...); @@ -1708,7 +1708,7 @@ inline function get_type_overload(const void *this_ptr, const detail::type_info Py_file_input, d.ptr(), d.ptr()); if (result == nullptr) throw error_already_set(); - if ((handle) d["self"] == Py_None) + if (d["self"].is_none()) return function(); Py_DECREF(result); #endif diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index f1763110e..8093eada7 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -110,6 +110,8 @@ public: PYBIND11_DEPRECATED("call(...) was deprecated in favor of operator()(...)") object call(Args&&... args) const; + /// Equivalent to ``obj is other`` in Python. + bool is(object_api const& other) const { return derived().ptr() == other.derived().ptr(); } /// Equivalent to ``obj is None`` in Python. bool is_none() const { return derived().ptr() == Py_None; } PYBIND11_DEPRECATED("Use py::str(obj) instead") @@ -167,10 +169,12 @@ public: /// Return ``true`` when the `handle` wraps a valid Python object explicit operator bool() const { return m_ptr != nullptr; } /** \rst - Check that the underlying pointers are the same. + Deprecated: Check that the underlying pointers are the same. Equivalent to ``obj1 is obj2`` in Python. \endrst */ + PYBIND11_DEPRECATED("Use obj1.is(obj2) instead") bool operator==(const handle &h) const { return m_ptr == h.m_ptr; } + PYBIND11_DEPRECATED("Use !obj1.is(obj2) instead") bool operator!=(const handle &h) const { return m_ptr != h.m_ptr; } PYBIND11_DEPRECATED("Use handle::operator bool() instead") bool check() const { return m_ptr != nullptr; } diff --git a/tests/test_eval.cpp b/tests/test_eval.cpp index 05cc7f06d..9a8ac216b 100644 --- a/tests/test_eval.cpp +++ b/tests/test_eval.cpp @@ -37,7 +37,7 @@ test_initializer eval([](py::module &m) { ); auto x = local["x"].cast(); - return result == py::none() && x == 42; + return result.is_none() && x == 42; }); m.def("test_eval", [global]() { @@ -55,7 +55,7 @@ test_initializer eval([](py::module &m) { auto result = py::eval("x = call_test()", py::dict(), local); auto x = local["x"].cast(); - return result == py::none() && x == 42; + return result.is_none() && x == 42; }); m.def("test_eval_file", [global](py::str filename) { @@ -66,7 +66,7 @@ test_initializer eval([](py::module &m) { local["call_test2"] = py::cpp_function([&](int value) { val_out = value; }); auto result = py::eval_file(filename, global, local); - return val_out == 43 && result == py::none(); + return val_out == 43 && result.is_none(); }); m.def("test_eval_failure", []() {