@@ -41,6 +41,9 @@ using sequence_accessor = accessor<accessor_policies::sequence_item>;
41
41
using list_accessor = accessor<accessor_policies::list_item>;
42
42
using tuple_accessor = accessor<accessor_policies::tuple_item>;
43
43
44
+ // / Tag for choosing the non-converting py::object constructor
45
+ struct noconvert { };
46
+
44
47
// / Tag and check to identify a class which implements the Python object API
45
48
class pyobject_tag { };
46
49
template <typename T> using is_pyobject = std::is_base_of<pyobject_tag, T>;
@@ -102,9 +105,11 @@ class handle : public detail::object_api<handle> {
102
105
class object : public handle {
103
106
public:
104
107
object () = default ;
108
+ // Derived classes may override this constructor for Python type conversions
109
+ object (handle h, bool borrowed) : handle(h) { if (borrowed) inc_ref (); }
110
+ // This one must be inherited as is -- it's always just a pure pointer assignment
111
+ object (handle h, bool borrowed, detail::noconvert) : object(h, borrowed) { }
105
112
object (const object &o) : handle(o) { inc_ref (); }
106
- object (const handle &h, bool borrowed) : handle(h) { if (borrowed) inc_ref (); }
107
- object (PyObject *ptr, bool borrowed) : handle(ptr) { if (borrowed) inc_ref (); }
108
113
object (object &&other) noexcept { m_ptr = other.m_ptr ; other.m_ptr = nullptr ; }
109
114
~object () { dec_ref (); }
110
115
@@ -137,6 +142,13 @@ class object : public handle {
137
142
template <typename T> T cast () &&;
138
143
};
139
144
145
+ /* * Python type casts of the form `obj.cast<pytype>()` and `pytype(obj)` are equivalent
146
+ and they do actual convertions, e.g. `list` -> `tuple`. In contrast, the following
147
+ functions don't do any kind of conversion, they simply declare that a PyObject is a
148
+ certain type and borrow or steal the reference. */
149
+ template <typename T> T reinterpret_borrow (handle h) { return T (h, true , detail::noconvert ()); }
150
+ template <typename T> T reinterpret_steal (handle h) { return T (h, false , detail::noconvert ()); }
151
+
140
152
// / Check if `obj` is an instance of type `T`
141
153
template <typename T, detail::enable_if_t <std::is_base_of<object, T>::value, int > = 0 >
142
154
bool isinstance (handle obj) { return T::_check (obj); }
@@ -392,6 +404,7 @@ NAMESPACE_END(detail)
392
404
393
405
#define PYBIND11_OBJECT_COMMON (Name, Parent, CheckFun ) \
394
406
public: \
407
+ using Parent::Parent; \
395
408
PYBIND11_DEPRECATED (" Use py::isinstance<py::python_type>(obj) instead" ) \
396
409
bool check() const { return m_ptr != nullptr && (bool ) CheckFun (m_ptr); } \
397
410
static bool _check (handle h) { return h.ptr () != nullptr && CheckFun (h.ptr ()); }
@@ -404,7 +417,6 @@ NAMESPACE_END(detail)
404
417
405
418
#define PYBIND11_OBJECT (Name, Parent, CheckFun ) \
406
419
PYBIND11_OBJECT_COMMON (Name, Parent, CheckFun) \
407
- Name(handle h, bool borrowed) : Parent(h, borrowed) { } \
408
420
/* This is deliberately not 'explicit' to allow implicit conversion from object: */ \
409
421
Name(const object &o) : Parent(o) { }
410
422
@@ -833,7 +845,7 @@ inline str repr(handle h) {
833
845
Py_XDECREF (str_value); str_value = unicode;
834
846
if (!str_value) throw error_already_set ();
835
847
#endif
836
- return { str_value, false } ;
848
+ return reinterpret_steal<str>( str_value) ;
837
849
}
838
850
839
851
NAMESPACE_BEGIN (detail)
0 commit comments