This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: PyObject_CallObject - Not "reference-count-neutral"
Type: Stage:
Components: Documentation Versions: Python 2.6
process
Status: closed Resolution: works for me
Dependencies: Superseder:
Assigned To: georg.brandl Nosy List: Krauzi, amaury.forgeotdarc, georg.brandl, ysj.ray
Priority: normal Keywords:

Created on 2010-04-07 19:09 by Krauzi, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (7)
msg102557 - (view) Author: Krauzi (Krauzi) Date: 2010-04-07 19:09
In the docs there is written:
"PyObject_CallObject() is “reference-count-neutral” with respect to its arguments."
This is not correct. Its only reference-count neutral if the call was SUCCESSFUL otherwise the argument is INCREFED! 
Can anyone confirm this?

Cheers Krauzi.
msg102597 - (view) Author: ysj.ray (ysj.ray) Date: 2010-04-08 07:33
By looking into the source, I found PyObject_CallObject() is “reference-count-neutral” even the call is FAILED, because it will always call Py_DECREF(arg) in the end and in case of exception.
msg102599 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2010-04-08 07:46
Indeed, every function of the API is consistent in this aspect, success or failure should not make a difference in reference counts.  Do you have an evidence of the contrary?

Note that it's possible that because of the failure, some argument is stored in an exception (maybe indirectly, through the traceback which contains active frames and their local variables), which increases its reference count. Clearing the exception should release the reference.
msg102602 - (view) Author: ysj.ray (ysj.ray) Date: 2010-04-08 08:02
Yes. I think if the argument object's reference count is increased because of the exception traceback or other cases, it has nothing to do with the PyObject_CallObject itself. Both of the Py_INCREF(arg) and Py_DECREF(arg) will always run once through the PyObject_CallObject() call. 
The “reference-count-neutral” means the code of PyObject_CallObject() itself can guarantee the "reference-count-neutral", but not include the callable called by PyObject_CallObject().
msg102605 - (view) Author: Krauzi (Krauzi) Date: 2010-04-08 09:39
a i think i expressed the problem false. The problem is that the arg (which is a tuple here) is correctly decremented and thus the reference counts are OK. BUT: The objects INSIDE the tuple are NOT correctly decremented. This is the code i've used:
C++ Program: http://www.copypastecode.com/26047/
Python Script imported by it: http://www.copypastecode.com/26051/
Now the results:
With raise in python script:
http://img251.imageshack.us/img251/997/witherror.jpg
and with uncommented "raise":
http://img256.imageshack.us/img256/2818/noerror.jpg

Hope its now clear.

Krauzi
msg102610 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2010-04-08 09:57
Yes, I think what I wrote above applies here: the string is stored in the "args" variable. When the exception is raised, the traceback contains the *live* frame objects, with position in the bytecode and all local variables. This allows post-mortem debugging, for example.

Try calling PyErr_PrintEx(0) instead of PyErr_Print(), this should clear the exception state without storing it in sys.last_traceback, and the reference will decrease.
msg102611 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2010-04-08 10:04
I don't think this needs to be kept open.
History
Date User Action Args
2022-04-11 14:56:59adminsetgithub: 52583
2010-04-08 10:04:41georg.brandlsetstatus: open -> closed
resolution: works for me
messages: + msg102611
2010-04-08 09:57:09amaury.forgeotdarcsetmessages: + msg102610
2010-04-08 09:39:04Krauzisetmessages: + msg102605
2010-04-08 08:02:44ysj.raysetmessages: + msg102602
2010-04-08 07:46:38amaury.forgeotdarcsetnosy: + amaury.forgeotdarc
messages: + msg102599
2010-04-08 07:33:16ysj.raysetnosy: + ysj.ray
messages: + msg102597
2010-04-07 19:09:52Krauzicreate