mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-11 08:03:55 +00:00
refactor: replace .get_type with type::handle_of (#2492)
* refactor: replace .get_type with type::handle_of * refactor: use impl for handle_of * fix: deprecate h.get_type()
This commit is contained in:
parent
a4cee36b6f
commit
41aa92601e
@ -17,10 +17,16 @@ See :ref:`upgrade-guide-2.6` for help upgrading to the new version.
|
|||||||
This reduces binary size quite substantially (~25%).
|
This reduces binary size quite substantially (~25%).
|
||||||
`#2463 <https://github.com/pybind/pybind11/pull/2463>`_
|
`#2463 <https://github.com/pybind/pybind11/pull/2463>`_
|
||||||
|
|
||||||
* Keyword-only argument supported in Python 2 or 3 with ``py::kw_only()``.
|
* Keyword-only arguments supported in Python 2 or 3 with ``py::kw_only()``.
|
||||||
`#2100 <https://github.com/pybind/pybind11/pull/2100>`_
|
`#2100 <https://github.com/pybind/pybind11/pull/2100>`_
|
||||||
|
|
||||||
* Positional-only argument supported in Python 2 or 3 with ``py::pos_only()``.
|
* Positional-only arguments supported in Python 2 or 3 with ``py::pos_only()``.
|
||||||
|
`#2459 <https://github.com/pybind/pybind11/pull/2459>`_
|
||||||
|
|
||||||
|
* Access to the type object now provided with ``py::type::of<T>()`` and
|
||||||
|
``py::type::of(h)``.
|
||||||
|
`#2364 <https://github.com/pybind/pybind11/pull/2364>`_
|
||||||
|
|
||||||
|
|
||||||
* Perfect forwarding support for methods.
|
* Perfect forwarding support for methods.
|
||||||
`#2048 <https://github.com/pybind/pybind11/pull/2048>`_
|
`#2048 <https://github.com/pybind/pybind11/pull/2048>`_
|
||||||
|
@ -17,6 +17,9 @@ An error is now thrown when ``__init__`` is forgotten on subclasses. This was
|
|||||||
incorrect before, but was not checked. Add a call to ``__init__`` if it is
|
incorrect before, but was not checked. Add a call to ``__init__`` if it is
|
||||||
missing.
|
missing.
|
||||||
|
|
||||||
|
The undocumented ``h.get_type()`` method has been deprecated and replaced by
|
||||||
|
``py::type::of(h)``.
|
||||||
|
|
||||||
If ``__eq__`` defined but not ``__hash__``, ``__hash__`` is now set to
|
If ``__eq__`` defined but not ``__hash__``, ``__hash__`` is now set to
|
||||||
``None``, as in normal CPython. You should add ``__hash__`` if you intended the
|
``None``, as in normal CPython. You should add ``__hash__`` if you intended the
|
||||||
class to be hashable, possibly using the new ``py::hash`` shortcut.
|
class to be hashable, possibly using the new ``py::hash`` shortcut.
|
||||||
|
@ -636,7 +636,7 @@ public:
|
|||||||
/// native typeinfo, or when the native one wasn't able to produce a value.
|
/// native typeinfo, or when the native one wasn't able to produce a value.
|
||||||
PYBIND11_NOINLINE bool try_load_foreign_module_local(handle src) {
|
PYBIND11_NOINLINE bool try_load_foreign_module_local(handle src) {
|
||||||
constexpr auto *local_key = PYBIND11_MODULE_LOCAL_ID;
|
constexpr auto *local_key = PYBIND11_MODULE_LOCAL_ID;
|
||||||
const auto pytype = src.get_type();
|
const auto pytype = type::handle_of(src);
|
||||||
if (!hasattr(pytype, local_key))
|
if (!hasattr(pytype, local_key))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1130,7 +1130,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if this is a C++ type */
|
/* Check if this is a C++ type */
|
||||||
auto &bases = all_type_info((PyTypeObject *) h.get_type().ptr());
|
auto &bases = all_type_info((PyTypeObject *) type::handle_of(h).ptr());
|
||||||
if (bases.size() == 1) { // Only allowing loading from a single-value type
|
if (bases.size() == 1) { // Only allowing loading from a single-value type
|
||||||
value = values_and_holders(reinterpret_cast<instance *>(h.ptr())).begin()->value_ptr();
|
value = values_and_holders(reinterpret_cast<instance *>(h.ptr())).begin()->value_ptr();
|
||||||
return true;
|
return true;
|
||||||
@ -1708,7 +1708,7 @@ template <typename T, typename SFINAE> type_caster<T, SFINAE> &load_type(type_ca
|
|||||||
throw cast_error("Unable to cast Python instance to C++ type (compile in debug mode for details)");
|
throw cast_error("Unable to cast Python instance to C++ type (compile in debug mode for details)");
|
||||||
#else
|
#else
|
||||||
throw cast_error("Unable to cast Python instance of type " +
|
throw cast_error("Unable to cast Python instance of type " +
|
||||||
(std::string) str(handle.get_type()) + " to C++ type '" + type_id<T>() + "'");
|
(std::string) str(type::handle_of(handle)) + " to C++ type '" + type_id<T>() + "'");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return conv;
|
return conv;
|
||||||
@ -1759,7 +1759,7 @@ detail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) {
|
|||||||
throw cast_error("Unable to cast Python instance to C++ rvalue: instance has multiple references"
|
throw cast_error("Unable to cast Python instance to C++ rvalue: instance has multiple references"
|
||||||
" (compile in debug mode for details)");
|
" (compile in debug mode for details)");
|
||||||
#else
|
#else
|
||||||
throw cast_error("Unable to move from Python " + (std::string) str(obj.get_type()) +
|
throw cast_error("Unable to move from Python " + (std::string) str(type::handle_of(obj)) +
|
||||||
" instance to C++ " + type_id<T>() + " instance: instance has multiple references");
|
" instance to C++ " + type_id<T>() + " instance: instance has multiple references");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2206,13 +2206,13 @@ PYBIND11_NAMESPACE_END(detail)
|
|||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
type type::of() {
|
handle type::handle_of() {
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_base_of<detail::type_caster_generic, detail::make_caster<T>>::value,
|
std::is_base_of<detail::type_caster_generic, detail::make_caster<T>>::value,
|
||||||
"py::type::of<T> only supports the case where T is a registered C++ types."
|
"py::type::of<T> only supports the case where T is a registered C++ types."
|
||||||
);
|
);
|
||||||
|
|
||||||
return type((PyObject*) detail::get_type_handle(typeid(T), true).ptr(), borrowed_t());
|
return detail::get_type_handle(typeid(T), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -553,7 +553,7 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
|
|||||||
object matrix_type = sparse_module.attr(
|
object matrix_type = sparse_module.attr(
|
||||||
rowMajor ? "csr_matrix" : "csc_matrix");
|
rowMajor ? "csr_matrix" : "csc_matrix");
|
||||||
|
|
||||||
if (!obj.get_type().is(matrix_type)) {
|
if (!type::handle_of(obj).is(matrix_type)) {
|
||||||
try {
|
try {
|
||||||
obj = matrix_type(obj);
|
obj = matrix_type(obj);
|
||||||
} catch (const error_already_set &) {
|
} catch (const error_already_set &) {
|
||||||
|
@ -1489,7 +1489,7 @@ struct enum_base {
|
|||||||
|
|
||||||
m_base.attr("__repr__") = cpp_function(
|
m_base.attr("__repr__") = cpp_function(
|
||||||
[](handle arg) -> str {
|
[](handle arg) -> str {
|
||||||
handle type = arg.get_type();
|
handle type = type::handle_of(arg);
|
||||||
object type_name = type.attr("__name__");
|
object type_name = type.attr("__name__");
|
||||||
dict entries = type.attr("__entries");
|
dict entries = type.attr("__entries");
|
||||||
for (const auto &kv : entries) {
|
for (const auto &kv : entries) {
|
||||||
@ -1503,7 +1503,7 @@ struct enum_base {
|
|||||||
|
|
||||||
m_base.attr("name") = property(cpp_function(
|
m_base.attr("name") = property(cpp_function(
|
||||||
[](handle arg) -> str {
|
[](handle arg) -> str {
|
||||||
dict entries = arg.get_type().attr("__entries");
|
dict entries = type::handle_of(arg).attr("__entries");
|
||||||
for (const auto &kv : entries) {
|
for (const auto &kv : entries) {
|
||||||
if (handle(kv.second[int_(0)]).equal(arg))
|
if (handle(kv.second[int_(0)]).equal(arg))
|
||||||
return pybind11::str(kv.first);
|
return pybind11::str(kv.first);
|
||||||
@ -1542,7 +1542,7 @@ struct enum_base {
|
|||||||
#define PYBIND11_ENUM_OP_STRICT(op, expr, strict_behavior) \
|
#define PYBIND11_ENUM_OP_STRICT(op, expr, strict_behavior) \
|
||||||
m_base.attr(op) = cpp_function( \
|
m_base.attr(op) = cpp_function( \
|
||||||
[](object a, object b) { \
|
[](object a, object b) { \
|
||||||
if (!a.get_type().is(b.get_type())) \
|
if (!type::handle_of(a).is(type::handle_of(b))) \
|
||||||
strict_behavior; \
|
strict_behavior; \
|
||||||
return expr; \
|
return expr; \
|
||||||
}, \
|
}, \
|
||||||
@ -2115,7 +2115,7 @@ inline function get_type_override(const void *this_ptr, const type_info *this_ty
|
|||||||
handle self = get_object_handle(this_ptr, this_type);
|
handle self = get_object_handle(this_ptr, this_type);
|
||||||
if (!self)
|
if (!self)
|
||||||
return function();
|
return function();
|
||||||
handle type = self.get_type();
|
handle type = type::handle_of(self);
|
||||||
auto key = std::make_pair(type.ptr(), name);
|
auto key = std::make_pair(type.ptr(), name);
|
||||||
|
|
||||||
/* Cache functions that aren't overridden in Python to avoid
|
/* Cache functions that aren't overridden in Python to avoid
|
||||||
|
@ -152,7 +152,8 @@ public:
|
|||||||
|
|
||||||
/// Return the object's current reference count
|
/// Return the object's current reference count
|
||||||
int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); }
|
int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); }
|
||||||
/// Return a handle to the Python type object underlying the instance
|
|
||||||
|
PYBIND11_DEPRECATED("Call py::type::handle_of(h) or py::type::of(h) instead of h.get_type()")
|
||||||
handle get_type() const;
|
handle get_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -897,13 +898,24 @@ class type : public object {
|
|||||||
public:
|
public:
|
||||||
PYBIND11_OBJECT(type, object, PyType_Check)
|
PYBIND11_OBJECT(type, object, PyType_Check)
|
||||||
|
|
||||||
static type of(handle h) { return type((PyObject*) Py_TYPE(h.ptr()), borrowed_t{}); }
|
/// Return a type handle from a handle or an object
|
||||||
|
static handle handle_of(handle h) { return handle((PyObject*) Py_TYPE(h.ptr())); }
|
||||||
|
|
||||||
/// Convert C++ type to py::type if previously registered. Does not convert
|
/// Return a type object from a handle or an object
|
||||||
// standard types, like int, float. etc. yet.
|
static type of(handle h) { return type(type::handle_of(h), borrowed_t{}); }
|
||||||
// See https://github.com/pybind/pybind11/issues/2486
|
|
||||||
|
// Defined in pybind11/cast.h
|
||||||
|
/// Convert C++ type to handle if previously registered. Does not convert
|
||||||
|
/// standard types, like int, float. etc. yet.
|
||||||
|
/// See https://github.com/pybind/pybind11/issues/2486
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static type of();
|
static handle handle_of();
|
||||||
|
|
||||||
|
/// Convert C++ type to type if previously registered. Does not convert
|
||||||
|
/// standard types, like int, float. etc. yet.
|
||||||
|
/// See https://github.com/pybind/pybind11/issues/2486
|
||||||
|
template<typename T>
|
||||||
|
static type of() {return type(type::handle_of<T>(), borrowed_t{}); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class iterable : public object {
|
class iterable : public object {
|
||||||
@ -1568,7 +1580,8 @@ template <typename D>
|
|||||||
str_attr_accessor object_api<D>::doc() const { return attr("__doc__"); }
|
str_attr_accessor object_api<D>::doc() const { return attr("__doc__"); }
|
||||||
|
|
||||||
template <typename D>
|
template <typename D>
|
||||||
handle object_api<D>::get_type() const { return (PyObject *) Py_TYPE(derived().ptr()); }
|
PYBIND11_DEPRECATED("Use py::type::of(h) instead of h.get_type()")
|
||||||
|
handle object_api<D>::get_type() const { return type::handle_of(*this); }
|
||||||
|
|
||||||
template <typename D>
|
template <typename D>
|
||||||
bool object_api<D>::rich_compare(object_api const &other, int value) const {
|
bool object_api<D>::rich_compare(object_api const &other, int value) const {
|
||||||
|
Loading…
Reference in New Issue
Block a user