Tempfile.py destructor problem (python 1.4)
> I'm running python 1.4 on solaris. I wanted to create a Tempfile class
> which would act like a writable file, but which would automatically delete
> the temp file on disk when the object was destructed.
> The problem was that the tempfile was not always being deleted. Because...
> - the destructor was not always being called because...
> - the refcount on the last constructed Tempfile object was not dropping to
> zero because...
> - apparently 'self' for the constructor continues to exist even after the
> constructor method finishes. (Maybe???) This only seems to hapen when I
> call tempfile.mktemp() from the constructor.
> The workaround seems to be to set self to 0 (or somesuch) at the end of the
> - This is a bug, right?
> - Has it been fixed in python 1.5?
> - Is my fix safe?
Your problem is probably caused by a common pitfall with destructors
in Python -- some function you call does a try-except and as a side
effect, a reference to your stack frame remains accessible through the
traceback stored in sys.exc_traceback.
I'm not sure whether to call it a bug -- it's not a coding bug, it
could be called a design problem, or an unexpected interaction between
destructors and exception handling.
And yes, it has been fixed in 1.5 (by redesigning the exception
I've never seen your fix (setting self=0 before returning), but it is
cute and works, so I say, go for it. It shows you're a creative soul!
Note that in 1.5, you can use tempfile.TemporaryFile() which does what
your Tempfile class does.
In a followup, Pat continues:
> When I quit from an interactive session, the Gnuplot destructor gets called
> and the Tempfiles *try* to destruct, but an (undetailed) exception get's
> thrown, and the temporary files don't actually get removed. Aaargghh!
> Eventually, I find this magic fix: in the Gnuplot class module, change
> 'from Tempfile import Tempfile' to 'import Tempfile' (and change the
> instantiations accordingly, of course). Voila! It finally works, but for
> non-obvious reasons.
This one has to do with the order in which modules are destroyed. It
is an unfortunate problem that hasn't been solved completely in 1.5
either. The reason that your solution works is that it delays the
destruction of the Tempfile module until after the Gnuplot module is
destroyed. When your __del__ gets called after the Tempfile module
has been destroyed (actually, its __dict__ has been cleared), what
happens is that your call to "os.unlink" fails because the global
variable "os" is deleted.
--Guido van Rossum (home page: http://www.python.org/~guido/)