Skip to content

Commit e41484a

Browse files
committed
Use reinterpret_borrow/steal everywhere
1 parent 779bfe1 commit e41484a

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

@@ -474,9 +474,9 @@ struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value>> {
474474
#endif
475475
PyErr_Clear();
476476
if (type_error && PyNumber_Check(src.ptr())) {
477-
object tmp(std::is_floating_point<T>::value
478-
? PyNumber_Float(src.ptr())
479-
: PyNumber_Long(src.ptr()), true);
477+
auto tmp = reinterpret_borrow<object>(std::is_floating_point<T>::value
478+
? PyNumber_Float(src.ptr())
479+
: PyNumber_Long(src.ptr()));
480480
PyErr_Clear();
481481
return load(tmp, false);
482482
}
@@ -529,7 +529,7 @@ template <> class type_caster<void> : public type_caster<void_type> {
529529

530530
/* Check if this is a capsule */
531531
if (isinstance<capsule>(h)) {
532-
value = capsule(h, true);
532+
value = reinterpret_borrow<capsule>(h);
533533
return true;
534534
}
535535

@@ -581,7 +581,7 @@ template <> class type_caster<std::string> {
581581
if (!src) {
582582
return false;
583583
} else if (PyUnicode_Check(load_src.ptr())) {
584-
temp = object(PyUnicode_AsUTF8String(load_src.ptr()), false);
584+
temp = reinterpret_steal<object>(PyUnicode_AsUTF8String(load_src.ptr()));
585585
if (!temp) { PyErr_Clear(); return false; } // UnicodeEncodeError
586586
load_src = temp;
587587
}
@@ -622,7 +622,7 @@ template <> class type_caster<std::wstring> {
622622
if (!src) {
623623
return false;
624624
} else if (!PyUnicode_Check(load_src.ptr())) {
625-
temp = object(PyUnicode_FromObject(load_src.ptr()), false);
625+
temp = reinterpret_steal<object>(PyUnicode_FromObject(load_src.ptr()));
626626
if (!temp) { PyErr_Clear(); return false; }
627627
load_src = temp;
628628
}
@@ -631,10 +631,10 @@ template <> class type_caster<std::wstring> {
631631
#if PY_MAJOR_VERSION >= 3
632632
buffer = PyUnicode_AsWideCharString(load_src.ptr(), &length);
633633
#else
634-
temp = object(
634+
temp = reinterpret_steal<object>(
635635
sizeof(wchar_t) == sizeof(short)
636636
? PyUnicode_AsUTF16String(load_src.ptr())
637-
: PyUnicode_AsUTF32String(load_src.ptr()), false);
637+
: PyUnicode_AsUTF32String(load_src.ptr()));
638638
if (temp) {
639639
int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), (char **) &buffer, &length);
640640
if (err == -1) { buffer = nullptr; } // TypeError
@@ -715,8 +715,8 @@ template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> {
715715
}
716716

717717
static handle cast(const type &src, return_value_policy policy, handle parent) {
718-
object o1 = object(make_caster<T1>::cast(src.first, policy, parent), false);
719-
object o2 = object(make_caster<T2>::cast(src.second, policy, parent), false);
718+
auto o1 = reinterpret_steal<object>(make_caster<T1>::cast(src.first, policy, parent));
719+
auto o2 = reinterpret_steal<object>(make_caster<T2>::cast(src.second, policy, parent));
720720
if (!o1 || !o2)
721721
return handle();
722722
tuple result(2);
@@ -831,7 +831,7 @@ template <typename... Tuple> class type_caster<std::tuple<Tuple...>> {
831831
/* Implementation: Convert a C++ tuple into a Python tuple */
832832
template <size_t ... Indices> static handle cast(const type &src, return_value_policy policy, handle parent, index_sequence<Indices...>) {
833833
std::array<object, size> entries {{
834-
object(make_caster<Tuple>::cast(std::get<Indices>(src), policy, parent), false)...
834+
reinterpret_steal<object>(make_caster<Tuple>::cast(std::get<Indices>(src), policy, parent))...
835835
}};
836836
for (const auto &entry: entries)
837837
if (!entry)
@@ -904,7 +904,7 @@ template <typename type, typename holder_type> class type_caster_holder : public
904904

905905
if (convert) {
906906
for (auto &converter : typeinfo->implicit_conversions) {
907-
temp = object(converter(src.ptr(), typeinfo->type), false);
907+
temp = reinterpret_steal<object>(converter(src.ptr(), typeinfo->type));
908908
if (load(temp, false))
909909
return true;
910910
}
@@ -1055,6 +1055,7 @@ template <typename T> make_caster<T> load_type(const handle &handle) {
10551055

10561056
NAMESPACE_END(detail)
10571057

1058+
// pytype -> C++ type
10581059
template <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>
10591060
T cast(const handle &handle) {
10601061
static_assert(!detail::cast_is_temporary_value_reference<T>::value,
@@ -1063,17 +1064,19 @@ T cast(const handle &handle) {
10631064
return detail::load_type<T>(handle).operator typename type_caster::template cast_op_type<T>();
10641065
}
10651066

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

1071+
// C++ type -> py::object
10691072
template <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>
10701073
object cast(const T &value, return_value_policy policy = return_value_policy::automatic_reference,
10711074
handle parent = handle()) {
10721075
if (policy == return_value_policy::automatic)
10731076
policy = std::is_pointer<T>::value ? return_value_policy::take_ownership : return_value_policy::copy;
10741077
else if (policy == return_value_policy::automatic_reference)
10751078
policy = std::is_pointer<T>::value ? return_value_policy::reference : return_value_policy::copy;
1076-
return object(detail::make_caster<T>::cast(value, policy, parent), false);
1079+
return reinterpret_steal<object>(detail::make_caster<T>::cast(value, policy, parent));
10771080
}
10781081

10791082
template <typename T> T handle::cast() const { return pybind11::cast<T>(*this); }
@@ -1147,8 +1150,8 @@ template <return_value_policy policy = return_value_policy::automatic_reference,
11471150
typename... Args> tuple make_tuple(Args&&... args_) {
11481151
const size_t size = sizeof...(Args);
11491152
std::array<object, size> args {
1150-
{ object(detail::make_caster<Args>::cast(
1151-
std::forward<Args>(args_), policy, nullptr), false)... }
1153+
{ reinterpret_steal<object>(detail::make_caster<Args>::cast(
1154+
std::forward<Args>(args_), policy, nullptr))... }
11521155
};
11531156
for (auto &arg_value : args) {
11541157
if (!arg_value) {
@@ -1180,7 +1183,9 @@ struct arg_v : arg {
11801183
template <typename T>
11811184
arg_v(const char *name, T &&x, const char *descr = nullptr)
11821185
: arg(name),
1183-
value(detail::make_caster<T>::cast(x, return_value_policy::automatic, handle()), false),
1186+
value(reinterpret_steal<object>(
1187+
detail::make_caster<T>::cast(x, return_value_policy::automatic, {})
1188+
)),
11841189
descr(descr)
11851190
#if !defined(NDEBUG)
11861191
, type(type_id<T>())
@@ -1241,10 +1246,10 @@ class simple_collector {
12411246

12421247
/// Call a Python function and pass the collected arguments
12431248
object call(PyObject *ptr) const {
1244-
auto result = object(PyObject_CallObject(ptr, m_args.ptr()), false);
1249+
PyObject *result = PyObject_CallObject(ptr, m_args.ptr());
12451250
if (!result)
12461251
throw error_already_set();
1247-
return result;
1252+
return reinterpret_steal<object>(result);
12481253
}
12491254

12501255
private:
@@ -1274,16 +1279,16 @@ class unpacking_collector {
12741279

12751280
/// Call a Python function and pass the collected arguments
12761281
object call(PyObject *ptr) const {
1277-
auto result = object(PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr()), false);
1282+
PyObject *result = PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr());
12781283
if (!result)
12791284
throw error_already_set();
1280-
return result;
1285+
return reinterpret_steal<object>(result);
12811286
}
12821287

12831288
private:
12841289
template <typename T>
12851290
void process(list &args_list, T &&x) {
1286-
auto o = object(detail::make_caster<T>::cast(std::forward<T>(x), policy, nullptr), false);
1291+
auto o = reinterpret_steal<object>(detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));
12871292
if (!o) {
12881293
#if defined(NDEBUG)
12891294
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:
@@ -655,7 +655,7 @@ template <typename T> struct npy_format_descriptor<T, enable_if_t<std::is_integr
655655
enum { value = values[detail::log2(sizeof(T)) * 2 + (std::is_unsigned<T>::value ? 1 : 0)] };
656656
static pybind11::dtype dtype() {
657657
if (auto ptr = npy_api::get().PyArray_DescrFromType_(value))
658-
return object(ptr, true);
658+
return reinterpret_borrow<pybind11::dtype>(ptr);
659659
pybind11_fail("Unsupported buffer format!");
660660
}
661661
template <typename T2 = T, enable_if_t<std::is_signed<T2>::value, int> = 0>
@@ -670,7 +670,7 @@ template <typename T> constexpr const int npy_format_descriptor<
670670
enum { value = npy_api::NumPyName }; \
671671
static pybind11::dtype dtype() { \
672672
if (auto ptr = npy_api::get().PyArray_DescrFromType_(value)) \
673-
return object(ptr, true); \
673+
return reinterpret_borrow<pybind11::dtype>(ptr); \
674674
pybind11_fail("Unsupported buffer format!"); \
675675
} \
676676
static PYBIND11_DESCR name() { return _(Name); } }
@@ -765,7 +765,7 @@ struct npy_format_descriptor<T, enable_if_t<is_pod_struct<T>::value>> {
765765
static PYBIND11_DESCR name() { return _("struct"); }
766766

767767
static pybind11::dtype dtype() {
768-
return object(dtype_ptr(), true);
768+
return reinterpret_borrow<pybind11::dtype>(dtype_ptr());
769769
}
770770

771771
static std::string format() {
@@ -788,7 +788,7 @@ struct npy_format_descriptor<T, enable_if_t<is_pod_struct<T>::value>> {
788788
auto& api = npy_api::get();
789789
if (!PyObject_TypeCheck(obj, api.PyVoidArrType_Type_))
790790
return false;
791-
if (auto descr = object(api.PyArray_DescrFromScalar_(obj), false)) {
791+
if (auto descr = reinterpret_steal<object>(api.PyArray_DescrFromScalar_(obj))) {
792792
if (api.PyArray_EquivTypes_(dtype_ptr(), descr.ptr())) {
793793
value = ((PyVoidScalarObject_Proxy *) obj)->obval;
794794
return true;

0 commit comments

Comments
 (0)