Skip to content

Commit 1fc8696

Browse files
committed
Use reinterpret_borrow/steal everywhere
1 parent e4086ae commit 1fc8696

File tree

8 files changed

+113
-98
lines changed

8 files changed

+113
-98
lines changed

include/pybind11/cast.h

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ class type_caster_generic {
237237
/* Perform an implicit conversion */
238238
if (convert) {
239239
for (auto &converter : typeinfo->implicit_conversions) {
240-
temp = object(converter(src.ptr(), typeinfo->type), false);
240+
temp = reinterpret_steal<object>(converter(src.ptr(), typeinfo->type));
241241
if (load(temp, false))
242242
return true;
243243
}
@@ -284,7 +284,7 @@ class type_caster_generic {
284284
return handle((PyObject *) it_i->second).inc_ref();
285285
}
286286

287-
object inst(PyType_GenericAlloc(tinfo->type, 0), false);
287+
auto inst = reinterpret_steal<object>(PyType_GenericAlloc(tinfo->type, 0));
288288

289289
auto wrapper = (instance<void> *) inst.ptr();
290290

@@ -487,9 +487,9 @@ struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value>> {
487487
#endif
488488
PyErr_Clear();
489489
if (type_error && PyNumber_Check(src.ptr())) {
490-
object tmp(std::is_floating_point<T>::value
491-
? PyNumber_Float(src.ptr())
492-
: PyNumber_Long(src.ptr()), true);
490+
auto tmp = reinterpret_borrow<object>(std::is_floating_point<T>::value
491+
? PyNumber_Float(src.ptr())
492+
: PyNumber_Long(src.ptr()));
493493
PyErr_Clear();
494494
return load(tmp, false);
495495
}
@@ -544,7 +544,7 @@ template <> class type_caster<void> : public type_caster<void_type> {
544544

545545
/* Check if this is a capsule */
546546
if (isinstance<capsule>(h)) {
547-
value = capsule(h, true);
547+
value = reinterpret_borrow<capsule>(h);
548548
return true;
549549
}
550550

@@ -596,7 +596,7 @@ template <> class type_caster<std::string> {
596596
if (!src) {
597597
return false;
598598
} else if (PyUnicode_Check(load_src.ptr())) {
599-
temp = object(PyUnicode_AsUTF8String(load_src.ptr()), false);
599+
temp = reinterpret_steal<object>(PyUnicode_AsUTF8String(load_src.ptr()));
600600
if (!temp) { PyErr_Clear(); return false; } // UnicodeEncodeError
601601
load_src = temp;
602602
}
@@ -637,7 +637,7 @@ template <> class type_caster<std::wstring> {
637637
if (!src) {
638638
return false;
639639
} else if (!PyUnicode_Check(load_src.ptr())) {
640-
temp = object(PyUnicode_FromObject(load_src.ptr()), false);
640+
temp = reinterpret_steal<object>(PyUnicode_FromObject(load_src.ptr()));
641641
if (!temp) { PyErr_Clear(); return false; }
642642
load_src = temp;
643643
}
@@ -646,10 +646,10 @@ template <> class type_caster<std::wstring> {
646646
#if PY_MAJOR_VERSION >= 3
647647
buffer = PyUnicode_AsWideCharString(load_src.ptr(), &length);
648648
#else
649-
temp = object(
649+
temp = reinterpret_steal<object>(
650650
sizeof(wchar_t) == sizeof(short)
651651
? PyUnicode_AsUTF16String(load_src.ptr())
652-
: PyUnicode_AsUTF32String(load_src.ptr()), false);
652+
: PyUnicode_AsUTF32String(load_src.ptr()));
653653
if (temp) {
654654
int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), (char **) &buffer, &length);
655655
if (err == -1) { buffer = nullptr; } // TypeError
@@ -730,8 +730,8 @@ template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> {
730730
}
731731

732732
static handle cast(const type &src, return_value_policy policy, handle parent) {
733-
object o1 = object(make_caster<T1>::cast(src.first, policy, parent), false);
734-
object o2 = object(make_caster<T2>::cast(src.second, policy, parent), false);
733+
auto o1 = reinterpret_steal<object>(make_caster<T1>::cast(src.first, policy, parent));
734+
auto o2 = reinterpret_steal<object>(make_caster<T2>::cast(src.second, policy, parent));
735735
if (!o1 || !o2)
736736
return handle();
737737
tuple result(2);
@@ -846,7 +846,7 @@ template <typename... Tuple> class type_caster<std::tuple<Tuple...>> {
846846
/* Implementation: Convert a C++ tuple into a Python tuple */
847847
template <size_t ... Indices> static handle cast(const type &src, return_value_policy policy, handle parent, index_sequence<Indices...>) {
848848
std::array<object, size> entries {{
849-
object(make_caster<Tuple>::cast(std::get<Indices>(src), policy, parent), false)...
849+
reinterpret_steal<object>(make_caster<Tuple>::cast(std::get<Indices>(src), policy, parent))...
850850
}};
851851
for (const auto &entry: entries)
852852
if (!entry)
@@ -919,7 +919,7 @@ template <typename type, typename holder_type> class type_caster_holder : public
919919

920920
if (convert) {
921921
for (auto &converter : typeinfo->implicit_conversions) {
922-
temp = object(converter(src.ptr(), typeinfo->type), false);
922+
temp = reinterpret_steal<object>(converter(src.ptr(), typeinfo->type));
923923
if (load(temp, false))
924924
return true;
925925
}
@@ -1070,6 +1070,7 @@ template <typename T> make_caster<T> load_type(const handle &handle) {
10701070

10711071
NAMESPACE_END(detail)
10721072

1073+
// pytype -> C++ type
10731074
template <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>
10741075
T cast(const handle &handle) {
10751076
static_assert(!detail::cast_is_temporary_value_reference<T>::value,
@@ -1078,17 +1079,19 @@ T cast(const handle &handle) {
10781079
return detail::load_type<T>(handle).operator typename type_caster::template cast_op_type<T>();
10791080
}
10801081

1082+
// pytype -> pytype (calls converting constructor)
10811083
template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>
1082-
T cast(const handle &handle) { return {handle, true}; }
1084+
T cast(const handle &handle) { return T(reinterpret_borrow<object>(handle)); }
10831085

1086+
// C++ type -> py::object
10841087
template <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>
10851088
object cast(const T &value, return_value_policy policy = return_value_policy::automatic_reference,
10861089
handle parent = handle()) {
10871090
if (policy == return_value_policy::automatic)
10881091
policy = std::is_pointer<T>::value ? return_value_policy::take_ownership : return_value_policy::copy;
10891092
else if (policy == return_value_policy::automatic_reference)
10901093
policy = std::is_pointer<T>::value ? return_value_policy::reference : return_value_policy::copy;
1091-
return object(detail::make_caster<T>::cast(value, policy, parent), false);
1094+
return reinterpret_steal<object>(detail::make_caster<T>::cast(value, policy, parent));
10921095
}
10931096

10941097
template <typename T> T handle::cast() const { return pybind11::cast<T>(*this); }
@@ -1162,8 +1165,8 @@ template <return_value_policy policy = return_value_policy::automatic_reference,
11621165
typename... Args> tuple make_tuple(Args&&... args_) {
11631166
const size_t size = sizeof...(Args);
11641167
std::array<object, size> args {
1165-
{ object(detail::make_caster<Args>::cast(
1166-
std::forward<Args>(args_), policy, nullptr), false)... }
1168+
{ reinterpret_steal<object>(detail::make_caster<Args>::cast(
1169+
std::forward<Args>(args_), policy, nullptr))... }
11671170
};
11681171
for (auto &arg_value : args) {
11691172
if (!arg_value) {
@@ -1195,7 +1198,9 @@ struct arg_v : arg {
11951198
template <typename T>
11961199
arg_v(const char *name, T &&x, const char *descr = nullptr)
11971200
: arg(name),
1198-
value(detail::make_caster<T>::cast(x, return_value_policy::automatic, handle()), false),
1201+
value(reinterpret_steal<object>(
1202+
detail::make_caster<T>::cast(x, return_value_policy::automatic, {})
1203+
)),
11991204
descr(descr)
12001205
#if !defined(NDEBUG)
12011206
, type(type_id<T>())
@@ -1256,10 +1261,10 @@ class simple_collector {
12561261

12571262
/// Call a Python function and pass the collected arguments
12581263
object call(PyObject *ptr) const {
1259-
auto result = object(PyObject_CallObject(ptr, m_args.ptr()), false);
1264+
PyObject *result = PyObject_CallObject(ptr, m_args.ptr());
12601265
if (!result)
12611266
throw error_already_set();
1262-
return result;
1267+
return reinterpret_steal<object>(result);
12631268
}
12641269

12651270
private:
@@ -1289,16 +1294,16 @@ class unpacking_collector {
12891294

12901295
/// Call a Python function and pass the collected arguments
12911296
object call(PyObject *ptr) const {
1292-
auto result = object(PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr()), false);
1297+
PyObject *result = PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr());
12931298
if (!result)
12941299
throw error_already_set();
1295-
return result;
1300+
return reinterpret_steal<object>(result);
12961301
}
12971302

12981303
private:
12991304
template <typename T>
13001305
void process(list &args_list, T &&x) {
1301-
auto o = object(detail::make_caster<T>::cast(std::forward<T>(x), policy, nullptr), false);
1306+
auto o = reinterpret_steal<object>(detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));
13021307
if (!o) {
13031308
#if defined(NDEBUG)
13041309
argument_cast_error();

include/pybind11/eigen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
182182
if (!src)
183183
return false;
184184

185-
object obj(src, true);
185+
auto obj = reinterpret_borrow<object>(src);
186186
object sparse_module = module::import("scipy.sparse");
187187
object matrix_type = sparse_module.attr(
188188
rowMajor ? "csr_matrix" : "csc_matrix");

include/pybind11/eval.h

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ enum eval_mode {
3131
template <eval_mode mode = eval_expr>
3232
object eval(str expr, object global = object(), object local = object()) {
3333
if (!global) {
34-
global = object(PyEval_GetGlobals(), true);
34+
global = reinterpret_borrow<object>(PyEval_GetGlobals());
3535
if (!global)
3636
global = dict();
3737
}
@@ -50,17 +50,16 @@ object eval(str expr, object global = object(), object local = object()) {
5050
default: pybind11_fail("invalid evaluation mode");
5151
}
5252

53-
object result(PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr()), false);
54-
53+
PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
5554
if (!result)
5655
throw error_already_set();
57-
return result;
56+
return reinterpret_steal<object>(result);
5857
}
5958

6059
template <eval_mode mode = eval_statements>
6160
object eval_file(str fname, object global = object(), object local = object()) {
6261
if (!global) {
63-
global = object(PyEval_GetGlobals(), true);
62+
global = reinterpret_borrow<object>(PyEval_GetGlobals());
6463
if (!global)
6564
global = dict();
6665
}
@@ -83,9 +82,9 @@ object eval_file(str fname, object global = object(), object local = object()) {
8382
FILE *f = _Py_fopen(fname.ptr(), "r");
8483
#else
8584
/* No unicode support in open() :( */
86-
object fobj(PyFile_FromString(
85+
auto fobj = reinterpret_steal<object>(PyFile_FromString(
8786
const_cast<char *>(fname_str.c_str()),
88-
const_cast<char*>("r")), false);
87+
const_cast<char*>("r")));
8988
FILE *f = nullptr;
9089
if (fobj)
9190
f = PyFile_AsFile(fobj.ptr());
@@ -96,14 +95,11 @@ object eval_file(str fname, object global = object(), object local = object()) {
9695
pybind11_fail("File \"" + fname_str + "\" could not be opened!");
9796
}
9897

99-
object result(PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(),
100-
local.ptr(), closeFile),
101-
false);
102-
98+
PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(),
99+
local.ptr(), closeFile);
103100
if (!result)
104101
throw error_already_set();
105-
106-
return result;
102+
return reinterpret_steal<object>(result);
107103
}
108104

109105
NAMESPACE_END(pybind11)

include/pybind11/functional.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ template <typename Return, typename... Args> struct type_caster<std::function<Re
3636
captured variables), in which case the roundtrip can be avoided.
3737
*/
3838
if (PyCFunction_Check(src_.ptr())) {
39-
capsule c(PyCFunction_GetSelf(src_.ptr()), true);
39+
auto c = reinterpret_borrow<capsule>(PyCFunction_GetSelf(src_.ptr()));
4040
auto rec = (function_record *) c;
4141
using FunctionType = Return (*) (Args...);
4242

@@ -47,7 +47,7 @@ template <typename Return, typename... Args> struct type_caster<std::function<Re
4747
}
4848
}
4949

50-
object src(src_, true);
50+
auto src = reinterpret_borrow<object>(src_);
5151
value = [src](Args... args) -> Return {
5252
gil_scoped_acquire acq;
5353
object retval(src(std::move(args)...));

include/pybind11/numpy.h

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ class dtype : public object {
239239
PyObject *ptr = nullptr;
240240
if (!detail::npy_api::get().PyArray_DescrConverter_(args.release().ptr(), &ptr) || !ptr)
241241
throw error_already_set();
242-
return object(ptr, false);
242+
return reinterpret_steal<dtype>(ptr);
243243
}
244244

245245
/// Return dtype associated with a C++ type.
@@ -266,7 +266,7 @@ class dtype : public object {
266266
static object _dtype_from_pep3118() {
267267
static PyObject *obj = module::import("numpy.core._internal")
268268
.attr("_dtype_from_pep3118").cast<object>().release().ptr();
269-
return object(obj, true);
269+
return reinterpret_borrow<object>(obj);
270270
}
271271

272272
dtype strip_padding() {
@@ -279,7 +279,7 @@ class dtype : public object {
279279
std::vector<field_descr> field_descriptors;
280280

281281
for (auto field : attr("fields").attr("items")()) {
282-
auto spec = object(field, true).cast<tuple>();
282+
auto spec = field.cast<tuple>();
283283
auto name = spec[0].cast<pybind11::str>();
284284
auto format = spec[1].cast<tuple>()[0].cast<dtype>();
285285
auto offset = spec[1].cast<tuple>()[1].cast<pybind11::int_>();
@@ -326,22 +326,22 @@ class array : public buffer {
326326
if (base && ptr) {
327327
if (isinstance<array>(base))
328328
/* Copy flags from base (except baseship bit) */
329-
flags = array(base, true).flags() & ~detail::npy_api::NPY_ARRAY_OWNDATA_;
329+
flags = reinterpret_borrow<array>(base).flags() & ~detail::npy_api::NPY_ARRAY_OWNDATA_;
330330
else
331331
/* Writable by default, easy to downgrade later on if needed */
332332
flags = detail::npy_api::NPY_ARRAY_WRITEABLE_;
333333
}
334334

335-
object tmp(api.PyArray_NewFromDescr_(
335+
auto tmp = reinterpret_steal<object>(api.PyArray_NewFromDescr_(
336336
api.PyArray_Type_, descr.release().ptr(), (int) ndim, (Py_intptr_t *) shape.data(),
337-
(Py_intptr_t *) strides.data(), const_cast<void *>(ptr), flags, nullptr), false);
337+
(Py_intptr_t *) strides.data(), const_cast<void *>(ptr), flags, nullptr));
338338
if (!tmp)
339339
pybind11_fail("NumPy: unable to create array!");
340340
if (ptr) {
341341
if (base) {
342342
PyArray_GET_(tmp.ptr(), base) = base.inc_ref().ptr();
343343
} else {
344-
tmp = object(api.PyArray_NewCopy_(tmp.ptr(), -1 /* any order */), false);
344+
tmp = reinterpret_steal<object>(api.PyArray_NewCopy_(tmp.ptr(), -1 /* any order */));
345345
}
346346
}
347347
m_ptr = tmp.release().ptr();
@@ -374,7 +374,7 @@ class array : public buffer {
374374

375375
/// Array descriptor (dtype)
376376
pybind11::dtype dtype() const {
377-
return object(PyArray_GET_(m_ptr, descr), true);
377+
return reinterpret_borrow<pybind11::dtype>(PyArray_GET_(m_ptr, descr));
378378
}
379379

380380
/// Total number of elements
@@ -399,7 +399,7 @@ class array : public buffer {
399399

400400
/// Base object
401401
object base() const {
402-
return object(PyArray_GET_(m_ptr, base), true);
402+
return reinterpret_borrow<object>(PyArray_GET_(m_ptr, base));
403403
}
404404

405405
/// Dimensions of the array
@@ -474,14 +474,14 @@ class array : public buffer {
474474
/// Return a new view with all of the dimensions of length 1 removed
475475
array squeeze() {
476476
auto& api = detail::npy_api::get();
477-
return array(api.PyArray_Squeeze_(m_ptr), false);
477+
return reinterpret_steal<array>(api.PyArray_Squeeze_(m_ptr));
478478
}
479479

480480
/// Ensure that the argument is a NumPy array
481481
static array ensure(object input, int ExtraFlags = 0) {
482482
auto& api = detail::npy_api::get();
483-
return array(api.PyArray_FromAny_(
484-
input.release().ptr(), nullptr, 0, 0, detail::npy_api::NPY_ENSURE_ARRAY_ | ExtraFlags, nullptr), false);
483+
return reinterpret_steal<array>(api.PyArray_FromAny_(
484+
input.release().ptr(), nullptr, 0, 0, detail::npy_api::NPY_ENSURE_ARRAY_ | ExtraFlags, nullptr));
485485
}
486486

487487
protected:
@@ -668,7 +668,7 @@ template <typename T> struct npy_format_descriptor<T, enable_if_t<std::is_integr
668668
enum { value = values[detail::log2(sizeof(T)) * 2 + (std::is_unsigned<T>::value ? 1 : 0)] };
669669
static pybind11::dtype dtype() {
670670
if (auto ptr = npy_api::get().PyArray_DescrFromType_(value))
671-
return object(ptr, true);
671+
return reinterpret_borrow<pybind11::dtype>(ptr);
672672
pybind11_fail("Unsupported buffer format!");
673673
}
674674
template <typename T2 = T, enable_if_t<std::is_signed<T2>::value, int> = 0>
@@ -683,7 +683,7 @@ template <typename T> constexpr const int npy_format_descriptor<
683683
enum { value = npy_api::NumPyName }; \
684684
static pybind11::dtype dtype() { \
685685
if (auto ptr = npy_api::get().PyArray_DescrFromType_(value)) \
686-
return object(ptr, true); \
686+
return reinterpret_borrow<pybind11::dtype>(ptr); \
687687
pybind11_fail("Unsupported buffer format!"); \
688688
} \
689689
static PYBIND11_DESCR name() { return _(Name); } }
@@ -778,7 +778,7 @@ struct npy_format_descriptor<T, enable_if_t<is_pod_struct<T>::value>> {
778778
static PYBIND11_DESCR name() { return _("struct"); }
779779

780780
static pybind11::dtype dtype() {
781-
return object(dtype_ptr(), true);
781+
return reinterpret_borrow<pybind11::dtype>(dtype_ptr());
782782
}
783783

784784
static std::string format() {
@@ -801,7 +801,7 @@ struct npy_format_descriptor<T, enable_if_t<is_pod_struct<T>::value>> {
801801
auto& api = npy_api::get();
802802
if (!PyObject_TypeCheck(obj, api.PyVoidArrType_Type_))
803803
return false;
804-
if (auto descr = object(api.PyArray_DescrFromScalar_(obj), false)) {
804+
if (auto descr = reinterpret_steal<object>(api.PyArray_DescrFromScalar_(obj))) {
805805
if (api.PyArray_EquivTypes_(dtype_ptr(), descr.ptr())) {
806806
value = ((PyVoidScalarObject_Proxy *) obj)->obval;
807807
return true;

0 commit comments

Comments
 (0)