1. ariovistus
  2. pyd
Issue #13 resolved

PydObject, Py_DECREF and borrowing

Ivan Smirnov
created an issue

In some cases, PydObject fails to release automatically upon scope exit (PydObject.~this() doesn't get called). Is one supposed to pass borrowed(py_object) and not py_object in the examples like the one below? It's not quite clear from the documentation.

module test;

import pyd.pyd;
import deimos.python.Python;

PyObject* f(PyObject* py_arg)
{
    auto arg = new PydObject(py_arg);
    /*
    in order to avoid the crash, one needs to add:
        scope(exit) clear(arg);
    or borrow the py_arg:
        auto arg = new PydObject(borrowed(py_arg));
    */
    return cast(PyObject *)Py_None();
}

extern(C) void PydMain()
{
    def!(f)();
    module_init();
}
import test
test.f({'hello': 1, 'world': 2})  # SIGSEGV
test.f([1, 2, 3])  # SIGSEGV
test.f(object())  # SIGSEGV
test.f('hello')  # ok
test.f(1)  # ok
print 'done'

If you run the python script, it completes, but then terminates with

'python pyd-test.py' terminated by signal SIGSEGV (Address boundary error)

Comments (4)

  1. ariovistus repo owner

    Yes, you should always be passing a borrowed reference to PydObject. The other constructor exists only for functions that return a new reference (e.g. PyObject_GetItem). This way, if you pass a result from a CApi function directly to PydObject, it automatically knows whether to increment the reference count.

  2. Log in to comment