cleanup after exceptions
Peter Otten
__peter__ at web.de
Thu Dec 18 15:49:16 EST 2003
Jp Calderone wrote:
> On Thu, Dec 18, 2003 at 07:11:12PM +0000, Padraig at Linux.ie wrote:
>> Hi,
>>
>> I'm a little confused why objects
>> are not deleted after they go
>> out of scope due to an exception?
>
> Because objects don't go out of scope. Only variables do. Objects
> remain
> "alive" as long as there are any references to them.
>
>>
>> For e.g.
>>
>> >>> import time
>> >>>
>> >>> def f():
>> >>> myfile=open("file.test","w")
>> >>> myfile.write("not flushed\n")
>> >>> exception=throw
>> >>>
>> >>> f()
>> >>> time.sleep(10)
>>
>>
>> The file is not written/closed until
>> the python interpreter exits.
>> The same thing applies to other objects.
>
> In this case, the traceback still holds a reference to the frame from
> which the exception was raised, which itself holds a reference to all the
> locales from that function.
>
> Calling sys.exc_clear() (possibly followed by gc.collect()) should force
> the cleanup you expect.
I tried out your recipe, but with no luck:
Python 2.3.2 (#1, Oct 21 2003, 10:03:19)
[GCC 3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class T:
... def __del__(self):
... print "now i'm gone"
...
>>> def f():
... t = T()
... raise Exception
...
>>> import sys, gc
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in f
Exception
>>> sys.exc_clear()
>>> gc.collect()
0
The only way to clear the reference I've found so far is a bit unorthodox:
>>> raise Exception
now i'm gone
Traceback (most recent call last):
File "<stdin>", line 1, in ?
Exception
There seems to be some dark corner of the exception infrastructure that
exc_clear() doesn't touch.
However, I think it's about time to direct the OP to the solution of the
"real" problem, i. e. ensuring that a resource is released when an
exception occurs:
>>> def g():
... t = T()
... try:
... raise Exception
... finally:
... del t
...
>>> g()
now i'm gone
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 4, in g
Exception
>>>
Whether immediate garbage collection occurs, is an implementation detail.
The code will be more portable if try...finally is used in such cases.
Peter
More information about the Python-list
mailing list