Point 1: __del__()
may not be called at process exit
The first thing to say is that
It is not guaranteed that __del__()
methods are called for objects that still exist when the interpreter exits.
From the python data model docs. Therefore you should not be relying on it to tidy up state that you need to tidy up at exit, and at the highest level, that's why your __del__()
may not be being called. That's what atexit
is for.
Point 2: predictable object lifetimes is an implementation detail in python
The next thing to say is that while CPython uses reference counting to enable it to detect that an object can be released without having to use the garbage collector (leading to more predictable CPU impact and potentially more efficient applications), it only takes one circular reference, one uncleared exception, one forgotten closure or one different python implementation to break, and so you should think really really hard about whether you want to rely on __del__()
being called at a particular point.
Point 3: Singleton implementations generally maintain a global reference to the singleton instance
By the sound of it, I would guess your singleton metaclass (itself a singleton...) is retaining your singleton instance the first time __call__()
is called. Since the metaclass is not released since it belongs to the module, which is itself retained by sys.modules
, that reference is not going to go away by the time the program terminates, so even given a guaranteed prompt tidy up of all external references to the singleton being freed, your __del__()
is not going to get called.
What you could try
- Add an
atexit
handler when you create your singleton instance to do your necessary tidy up at process exit.
- Also do that tidy up in the
__del__()
method if you want. E.g, you may decide for neatness / future extensibility (e.g. pluralizing the singleton) that you would like the singleton instance to tidy up after itself when it is no longer being used.
- And if you implement a
__del__()
method expecting to want tidy up to be done during normal program execution, you will probably want to remove the atexit
handler too.
- If you would like your singleton to be cleaned up when no one is using it anymore, consider storing it on your metaclass using
weakref
so that you don't retain it yourself.