Base class deleted before subclass during python __del__ processing

Posted by Oddthinking on Stack Overflow See other posts from Stack Overflow or by Oddthinking
Published on 2010-05-25T07:43:02Z Indexed on 2010/05/25 7:51 UTC
Read the original article Hit count: 364

Filed under:
|

Context

I am aware that if I ask a question about Python destructors, the standard argument will be to use contexts instead. Let me start by explaining why I am not doing that.

I am writing a subclass to logging.Handler. When an instance is closed, it posts a sentinel value to a Queue.Queue. If it doesn't, a second thread will be left running forever, waiting for Queue.Queue.get() to complete.

I am writing this with other developers in mind, so I don't want a failure to call close() on a handler object to cause the program to hang.

Therefore, I am adding a check in __del__() to ensure the object was closed properly.

I understand circular references may cause it to fail in some circumstances. There's not a lot I can do about that.

Problem

Here is some simple example code:

explicit_delete = True

class Base:
    def __del__(self):
        print "Base class cleaning up."

class Sub(Base):
    def __del__(self):
        print "Sub-class cleaning up."
        Base.__del__(self)

x = Sub()

if explicit_delete:
    del x

print "End of thread"

When I run this I get, as expected:

Sub-class cleaning up.
Base class cleaning up.
End of thread

If I set explicit_delete to False in the first line, I get:

End of thread
Sub-class cleaning up.
Exception AttributeError: "'NoneType' object has no attribute '__del__'" in <bound method Sub.__del__ of <__main__.Sub instance at 0x00F0B698>> ignored

It seems the definition of Base is removed before the x._del_() is called.

The Python Documentation on _del_() warns that the subclass needs to call the base-class to get a clean deletion, but here that appears to be impossible.

Can you see where I made a bad step?

© Stack Overflow or respective owner

Related posts about python

Related posts about destructors