Use std::unique_ptr with PyObject*
To ensure safely cleaning up PyObject*
references simply use std::unique_ptr
with a custom deleter:
# include <Python.h>
# include <memory>
auto py_deleter = [](PyObject* ptr) { Py_DECREF(ptr); };
using py_unique_ptr = std::unique_ptr<PyObject, decltype(py_deleter)>;
static PyObject* to_str(PyObject* self, PyObject* arg) {
py_unique_ptr pyStr { PyObject_Str(arg) };
if (/* some check */) {
return nullptr; // no Py_DECREF needed, since the py_deleter gets called when pyStr leaves the scope.
}
return pyStr.release();
}
As soon as the unique_ptr
leaves the scope it gets destroyed and py_deleter
gets called with the contained pointer.
The return pyStr.release();
at end of the function releases the contained object without calling the py_deleter
and returns it.
Since the deleter gets called only if the contained pointer isn’t null
, you can safely use Py_DECREF
instead of Py_XDECREF
.
This way your code will get much more cleaner and you don’t have to care about decreasing references.