[PyQt] sip: Accessing members results in incorrect/missing data
MatthijsBurgh
MatthijsBurgh at outlook.com
Wed Jan 22 13:57:38 GMT 2020
Phil Thompson-5 wrote
> On 21/01/2020 17:50, Phil Thompson wrote:
>> On 16/01/2020 20:52, MatthijsBurgh wrote:
>>> I have done some more investigating.
>>>
>>> As mentioned
>>> https://github.com/orocos/orocos_kinematics_dynamics/issues/41,
>>> problems where occuring in with SIP 4.13.2.
>>>
>>> Which is explainable as you fixed this issue in the commit:
>>> https://www.riverbankcomputing.com/hg/sip/rev/0dd3cb4eff0e. This makes
>>> sure
>>> the member variable contains a reference to the containing class. This
>>> prevents the class from being garbage collected while there are still
>>> references to the member variable.
>>>
>>> You apply a fix to this in commit
>>> https://www.riverbankcomputing.com/hg/sip/rev/fbb9cdbad791.
>>>
>>> The commit,
>>> https://www.riverbankcomputing.com/hg/sip/rev/11a92ebd4840,
>>> which I also mentioned in my first message, is the important one.
>>>
>>> In this commit you introduce a kind of caching for member variables.
>>> The
>>> python wrapper of the members of a class are stored in a dict in the
>>> python
>>> wrapper of the class. To add the member to the cache, you use
>>> "sipKeepReference(sipPySelf, %d, sipPy)". So the class contains a
>>> reference
>>> to the member variable.
>>>
>>> While previously "sipKeepReference(sipPy, -1, sipPySelf)", was used to
>>> store
>>> the reference to the class in the dict of the member variable. Focus
>>> here on
>>> the switch of "sipPy" and "sipPySelf". So by the last commit,
>>> 11a92ebd4840,
>>> you added a new feature, but you broke another one.
>>>
>>> I suggest to restore the feature which stores the reference to the
>>> class in
>>> the member variable dict.
>>>
>>> I did some testing in 4.19.20. I didn't experience a significant
>>> performance
>>> increase with the caching with my Frame object and its member p, a
>>> vector
>>> with 3 variables. (I tweaked the code,
>>> https://www.riverbankcomputing.com/hg/sip/file/7c54145e55b6/sipgen/gencode.c#l4904,
>>> to always get the caching.)
>>> Also I added manually the "sipKeepReference(sipPy, -1, sipPySelf)" to
>>> the
>>> generated cpp for the class reference. When both features were used at
>>> the
>>> same time, the "release" function of the class was not called. (I
>>> added a
>>> "printf" to it, which didn't show in that situation, but did if just
>>> of the
>>> two was used.)
>>
>> Thanks for the analysis, that was very helpful.
>>
>> This changeset is also a problem...
>>
>> https://www.riverbankcomputing.com/hg/sip/rev/6ec87337d5e2
>>
>> Can you try the latest version of the 4.19-maint branch, ie. including
>> this changeset...
>>
>> https://www.riverbankcomputing.com/hg/sip/rev/137b9be794a1
>>
>> ...and let me know how you get on.
>
> There is now a newer changeset...
>
> https://www.riverbankcomputing.com/hg/sip/rev/6a057b2d8537
>
> Phil
> _______________________________________________
> PyQt mailing list
> PyQt@
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
The first changeset already fixed the issue.
The newer changeset creates the situation as desribed in
http://python.6.x6.nabble.com/sip-Accessing-members-results-in-incorrect-missing-data-tp5266521p5266740.html,
it looks like the release function isn't called anymore. I thought Python GC
was able to break up circular references, but it looks like it isn't
happening.
By running the following code:
```
v = Vector(1,2,3)
R = Rotation()
F = Frame(R,v)
v2 = F.p
v3 = Frame(F).p
v3 = Vector(2,3,4)
```
The `release_Frame` is called(print shows up) after the second `v3`
assignment when using your first changeset, but the print doesn't show up
with your second changeset, today's one.
So to me it looks like this will cause a memory leak.
Side note: I would prefer the usage of a specific key for the member
reference to the containing class.
I don't think using the same key for both references will cause a problem
with overwriting. As a class can't contain a member of the same type, only a
member as a pointer to the same type. In which case, the reference isn't
kept, if I understand the code correct.
Matthijs
--
Sent from: http://python.6.x6.nabble.com/PyQt-f1792048.html
More information about the PyQt
mailing list