Title: reference count discrepancy, PyErr_Print vs. PyErr_Clear
Type: Stage:
Components: Interpreter Core Versions: Python 2.5
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: georg.brandl, ggenellina, jonklein
Priority: normal Keywords:

Created on 2007-07-18 19:02 by jonklein, last changed 2007-08-23 18:13 by georg.brandl. This issue is now closed.

File name Uploaded Description Edit jonklein, 2007-07-18 19:20
Messages (4)
msg32527 - (view) Author: Jon Klein (jonklein) Date: 2007-07-18 19:02
Possible reference count leak in PyErr_Print?

When a call to PyObject_Call( someObject ) raises an exception, subsequently calling PyErr_Print and PyErr_Clear will result in different behaviors with respect to the reference count of "someObject".  The reference count of "someObject" will be 1 higher with PyErr_Print() than with PyErr_Clear().

Calling PyErr_Print followed by PyErr_Clear will still result in an extra reference count.

This may be the expected behavior, but it is not documented, and I cannot figure out how to "reclaim" the reference lost when using PyErr_Print.

Attached is a short C program which uses an embedded interpreter to illustrate the problem.  Below is the test of the simple Python module I use with the C program to demonstrate the problem.

- - - - 

class ExceptionTest:
        def RaiseException( self ):
                raise Exception()

msg32528 - (view) Author: Jon Klein (jonklein) Date: 2007-07-18 19:20
File Added:
msg32529 - (view) Author: Gabriel Genellina (ggenellina) Date: 2007-07-19 20:16
The extra reference is hold in the traceback, which itself is hold in sys.last_traceback
PyErr_Print calls PyErr_PrintEx with set_sys_last_vars=1, indicating that sys.last_type/last_value/last_traceback should be set. 

<> says: "These three variables are not always defined; they are set when an exception is not handled and the interpreter prints an error message and a stack traceback. [...] (Since there is only one interactive thread, thread-safety is not a concern for these variables, unlike for exc_type etc.)"

So there is no reference leak. The next exception printed will clear the extra reference. If that's not acceptable, you can: a) avoid calling PyErr_Print, or use PyErr_Print(0). b) explicitely set those three attributes to None. c) at least set sys.last_traceback to None.
msg55172 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2007-08-23 18:13
Closing as invalid.
Date User Action Args
2007-08-23 18:13:56georg.brandlsetstatus: open -> closed
resolution: not a bug
messages: + msg55172
nosy: + georg.brandl
2007-07-18 19:02:22jonkleincreate