feat: py::type::of<T>() and py::type::of(h) (#2364)

* feat: type<T>()

* refactor: using py::type as class

* refactor: py::object as base

* wip: tigher api

* refactor: fix conversion and limit API further

* docs: some added notes from @EricCousineau-TRI

* refactor: use py::type::of
This commit is contained in:
Henry Schreiner
2020-09-14 18:06:26 -04:00
committed by GitHub
parent 32bb9071aa
commit f12ec00d70
6 changed files with 108 additions and 0 deletions

View File

@@ -2204,6 +2204,18 @@ object object_api<Derived>::call(Args &&...args) const {
PYBIND11_NAMESPACE_END(detail)
template<typename T>
type type::of() {
static_assert(
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."
);
return type((PyObject*) detail::get_type_handle(typeid(T), true).ptr(), borrowed_t());
}
#define PYBIND11_MAKE_OPAQUE(...) \
namespace pybind11 { namespace detail { \
template<> class type_caster<__VA_ARGS__> : public type_caster_base<__VA_ARGS__> { }; \

View File

@@ -19,6 +19,7 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
/* A few forward declarations */
class handle; class object;
class str; class iterator;
class type;
struct arg; struct arg_v;
PYBIND11_NAMESPACE_BEGIN(detail)
@@ -890,6 +891,21 @@ private:
object value = {};
};
class type : public object {
public:
PYBIND11_OBJECT(type, object, PyType_Check)
static type of(handle h) { return type((PyObject*) Py_TYPE(h.ptr()), borrowed_t{}); }
/// Convert C++ type to py::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();
};
class iterable : public object {
public:
PYBIND11_OBJECT_DEFAULT(iterable, object, detail::PyIterable_Check)