Skip to content
Snippets Groups Projects
Commit 8d74c432 authored by AlQuemist's avatar AlQuemist
Browse files

PyObjectPtr: add possibility for borrowed Python objects

Note that the check for Python initialization is moved to
'PyCore/Embed/PyInterpreter' module.
parent 9fde6624
No related branches found
No related tags found
1 merge request!2755Improve the construction of a 'Sample' from a Python script
......@@ -14,10 +14,10 @@
#include "PyObjectPtr.h"
#include "PyInterpreter.h"
#include <stdexcept> // runtime_error
PyObjectPtr::PyObjectPtr(PyObject* pyobject_ptr)
PyObjectPtr::PyObjectPtr(PyObject* pyobject_ptr, const bool borrowed)
: m_ptr{pyobject_ptr}
, m_borrowed{borrowed}
{
}
......@@ -44,10 +44,11 @@ void PyObjectPtr::reset()
void PyObjectPtr::discard()
{
if (!PyInterpreter::isInitialized())
throw(std::runtime_error("Decrementing Python reference-count without "
"Python initialized leads to memory access violation "
"(segmentation fault)"));
if (m_borrowed) {
// borrowed reference need no reference decrement
reset();
return;
}
PyInterpreter::DecRef(m_ptr);
reset();
......
......@@ -29,7 +29,7 @@
//! the life-time of a `PyObjectPtr` expires.
class PyObjectPtr {
public:
PyObjectPtr(PyObject* pyobject_ptr);
PyObjectPtr(PyObject* pyobject_ptr, const bool borrowed = false);
~PyObjectPtr();
PyObjectPtr(const PyObjectPtr&) = delete;
PyObjectPtr(PyObjectPtr&& other);
......@@ -50,6 +50,23 @@ public:
private:
//! Raw pointer to the PyObject
PyObject* m_ptr = nullptr;
//! Flag to determine if PyObject is a borrowed reference
// NOTE:
// The Python C-API uses two main types of object references:
// 1) 'Strong' reference (aka. 'new' reference) is a pointer that owns the reference.
// It increases the object's reference count and the caller is responsible for eventually
// calling `Py_DECREF` to release it.
//
// 2) 'Borrowed' reference is a pointer to an object that does _not_ own the reference.
// It does _not_ increase the object's reference count. The caller presumes that
// the referenced object already exists and has a positive refcount.
// The caller should not call `Py_DECREF` on the object (no need to release).
// It can become a dangling pointer if the object is destroyed.
//
// See section "Reference Count Details" in the Python/C API Reference Manual
// <https://docs.python.org/3/c-api/intro.html#reference-count-details>
bool m_borrowed = false;
};
#endif // BORNAGAIN_PYCORE_EMBED_PYOBJECTPTR_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment