Possible bug with Transfer annotation?

Arthur Gordon-Wright agordonwright at gmail.com
Mon Dec 12 00:35:30 GMT 2022


Hi,

The reproducing code for this issue involves several files, so I've created
a gist:

https://gist.github.com/ArthurGW/a3e906e2d1247adc140f988d06c883f3

It seems like between SIP 6.0.3 and SIP 6.1.0 (and up to the current
version) the /Transfer/ annotation is no longer working for function (i.e.
not method) arguments. Previously if I had a structure something like this:

    %Module(name=test_transfer)

    class Test {};

    void test_install(Test *obj /Transfer/);

with the wrapped C++ function `test_install` assigning the `Test` object
`obj` to a `std::unique_ptr` that is not cleared while the program is
running, and I called this from python as:

    import test_transfer
    test_transfer.test_install(test_transfer.Test())

then the associated C++ and Python `Test` objects were kept alive. However,
since SIP 6.1, the destructor on the `Test` object is called immediately
when `test_install` finishes, so the `std::unique_ptr` ends up pointing to
freed memory.

There are two fixes I can do for this myself: either make `test_install` a
method on a `Holder` object (see files named "METHOD..." in the gist), or
write the transfer code myself (WORKING.sip) as:

    void test_install(PyObject *obj /TypeHintIn = "Test"/);
    %MethodCode

    Test *tobj{reinterpret_cast<Test*>(sipConvertToType(a0, sipType_Test,
NULL, SIP_NOT_NONE, 0, &sipIsErr))};
    sipTransferTo(a0, Py_None);

    test_install(tobj);
    %End

It feels like this second fix is how that annotation is supposed to work,
so I shouldn't need to do this?

(Setup: python 3.8.8, on windows.)

Cheers,
Arthur
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20221212/49d99e79/attachment.htm>


More information about the PyQt mailing list