While investigating why some PyObjects do not get deallocated when I think they should, I noticed that when a PyObject* is returned from a slot, PythonQt increments its refcount before passing it to Python in PythonQt.cpp at line 523 (in wrapPtr). This means that after typing the following in the console:
var = some_static_slot()
del var
The refcount on the var object is 1. My two part question is a) shouldn't it be 0?, and b) what is the correct way to ensure PyObjects returned from slots are properly deallocated in Python? In my case var is a potentially very large numpy nd-array, and I would like it to be deallocated as early as possible.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think you are right, but I have to play through all scenarios to see what the right solution would be. It should be possible to return a new PyObject from a slot, which would mean that the reference needs to be stolen, so it might even be required to decref the PyObject after passing it to Python.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
As far as I can tell, there's no need for PythonQt to incref the PyObject in the first place. Whoever created the PyObject has already incref'ed it, and the reference will ultimately be owned by the caller of the slot in Python-land. As far as PythonQt is concerned, the reference is just passing through, no need to alter its refcount.
Then again, I'm relatively new to Python's C API, so I may very well be wrong.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes, I think you are right. I just have to double check that there is not code that returns unrefed PyObjects (like returning a pointer to a member without extra incref before returning it.)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I fixed this on the SVN trunk and you were exactly right. Incidentally, all slots that I wrote that returned PyObject* already did an extra ref-count or created new objects, which already have their initial ref count.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
While investigating why some PyObjects do not get deallocated when I think they should, I noticed that when a PyObject* is returned from a slot, PythonQt increments its refcount before passing it to Python in PythonQt.cpp at line 523 (in wrapPtr). This means that after typing the following in the console:
The refcount on the var object is 1. My two part question is a) shouldn't it be 0?, and b) what is the correct way to ensure PyObjects returned from slots are properly deallocated in Python? In my case var is a potentially very large numpy nd-array, and I would like it to be deallocated as early as possible.
I think you are right, but I have to play through all scenarios to see what the right solution would be. It should be possible to return a new PyObject from a slot, which would mean that the reference needs to be stolen, so it might even be required to decref the PyObject after passing it to Python.
As far as I can tell, there's no need for PythonQt to incref the PyObject in the first place. Whoever created the PyObject has already incref'ed it, and the reference will ultimately be owned by the caller of the slot in Python-land. As far as PythonQt is concerned, the reference is just passing through, no need to alter its refcount.
Then again, I'm relatively new to Python's C API, so I may very well be wrong.
Yes, I think you are right. I just have to double check that there is not code that returns unrefed PyObjects (like returning a pointer to a member without extra incref before returning it.)
I fixed this on the SVN trunk and you were exactly right. Incidentally, all slots that I wrote that returned PyObject* already did an extra ref-count or created new objects, which already have their initial ref count.
Awesome! Thank you for your help.
Thanks for reporting!