File tree Expand file tree Collapse file tree 4 files changed +38
-16
lines changed Expand file tree Collapse file tree 4 files changed +38
-16
lines changed Original file line number Diff line number Diff line change @@ -562,7 +562,7 @@ crucial that instances are deallocated on the C++ side to avoid memory leaks.
562
562
563
563
Destructors that call Python
564
564
============================
565
-
565
+ earch);45M
566
566
If a Python function is invoked from a C++ destructor, an exception may be thrown
567
567
of type :class: `error_already_set `. If this error is thrown out of a class destructor,
568
568
``std::terminate() `` will be called, terminating the process. Class destructors
@@ -1232,3 +1232,17 @@ appropriate derived-class pointer (e.g. using
1232
1232
more complete example, including a demonstration of how to provide
1233
1233
automatic downcasting for an entire class hierarchy without
1234
1234
writing one get() function for each class.
1235
+
1236
+ Accessing the type object
1237
+ =========================
1238
+
1239
+ You can get the type object from a C++ class that has already been registered using:
1240
+
1241
+ .. code-block :: python
1242
+
1243
+ auto T_py = py::type ::of< T> ();
1244
+
1245
+ You can directly use ``py::type(ob) `` to get the type object from any python
1246
+ object, just like ``type(ob) `` in Python.
1247
+
1248
+ .. versionadded :: 2.6
Original file line number Diff line number Diff line change @@ -2204,25 +2204,16 @@ object object_api<Derived>::call(Args &&...args) const {
2204
2204
PYBIND11_NAMESPACE_END (detail)
2205
2205
2206
2206
2207
- /* * \ingroup python_builtins
2208
- \rst
2209
- Return the registered type object for a C++ class, given as a template parameter.
2210
- py::type<T>() returns the Python type object previously registered for T.
2211
- \endrst */
2212
2207
template<typename T>
2213
- handle type() {
2214
- static_assert (
2208
+ type type::of () {
2209
+ static_assert (
2215
2210
std::is_base_of<detail::type_caster_generic, detail::make_caster<T>>::value,
2216
2211
" This currently only works for registered C++ types. The type here is most likely type converted (using type_caster)."
2217
2212
);
2218
2213
2219
- return detail::get_type_handle (typeid (T), true );
2214
+ return type ((PyTypeObject*) detail::get_type_handle (typeid (T), true ). ptr () );
2220
2215
}
2221
2216
2222
- inline handle type (handle h) {
2223
- PyObject* obj = (PyObject *) Py_TYPE (h.ptr ());
2224
- return handle (obj);
2225
- }
2226
2217
2227
2218
#define PYBIND11_MAKE_OPAQUE (...) \
2228
2219
namespace pybind11 { namespace detail { \
Original file line number Diff line number Diff line change @@ -19,6 +19,7 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
19
19
/* A few forward declarations */
20
20
class handle; class object ;
21
21
class str ; class iterator ;
22
+ class type ;
22
23
struct arg ; struct arg_v ;
23
24
24
25
PYBIND11_NAMESPACE_BEGIN (detail)
@@ -890,6 +891,22 @@ class iterator : public object {
890
891
object value = {};
891
892
};
892
893
894
+ class type : public handle {
895
+ public:
896
+ // Explicit omitted here since PyTypeObject required (rather than just PyObject)
897
+ type (PyTypeObject* type_ptr) : handle((PyObject*) type_ptr) {}
898
+
899
+ // / Giving a handle/object gets the type from it
900
+ explicit type (const handle& h) : handle((PyObject *) Py_TYPE(h.ptr())) {}
901
+
902
+ // / Convert C++ type to py::type if prevously registered. Does not convert standard types, like int, float. etc. yet.
903
+ template <typename T>
904
+ static type of ();
905
+
906
+ // / Custom check function that also ensures this is a type
907
+ bool check () const { return ptr () != nullptr && PyType_Check (ptr ());}
908
+ };
909
+
893
910
class iterable : public object {
894
911
public:
895
912
PYBIND11_OBJECT_DEFAULT (iterable, object, detail::PyIterable_Check)
Original file line number Diff line number Diff line change @@ -140,11 +140,11 @@ TEST_SUBMODULE(class_, m) {
140
140
m.def (" check_type" , [](int category) {
141
141
// Currently not supported (via a fail at compile time)
142
142
// if (category == 2)
143
- // return py::type<int>();
143
+ // return py::type::of <int>();
144
144
if (category == 1 )
145
- return py::type<DerivedClass1>();
145
+ return py::type::of <DerivedClass1>();
146
146
else
147
- return py::type<Invalid>();
147
+ return py::type::of <Invalid>();
148
148
});
149
149
150
150
m.def (" compute_type" , [](py::handle h) {
You can’t perform that action at this time.
0 commit comments