The general rule is, sys.exit() exits the application immediately, it doesn’t call any destructors. So, you only see ‘delete’ if it gets called before you call sys.exit().
In the first case, it doesn’t get printed because you call sys.exit() from within the Tester method itself. So the Tester object still exists, and it still holds self.x, which is a reference to your Foo object. So your Foo object still exists at the time you called sys.exit().
In the second case, your Tester object has deleted self.x, and never added the task to the task manager, so the last reference to the Foo object is destroyed before you call sys.exit(). So the delete method gets called before you call sys.exit().
The third case is the same as the second, except that here you have added the task to the task manager and then removed it. The task would have been enough to keep a reference to Foo around, but you removed it, so the reference is done. Then you also delete self.x, so that’s the last reference, and Foo is deleted. Then you don’t call sys.exit(), but even if you did I don’t think it would matter, since Foo has already been deleted.
Thanks for your detailed explanation. However, there are questions remaining.
Well, it seems to matter. In fact, the only difference between #1 and #3 is the sys.exit() call. Both add and remove the task to the task manager, but in the former case I get ‘delete’, in the latter I do not.
I thought I got rid of these references by first calling taskMgr.remove and afterwards “del self.x”.
Ah, I see. You’re right, I overlooked the call to del self.x in case #1. Still, that just means that something is still holding the reference; I believe it is probably the task manager, which doesn’t dump all references to its tasks the same frame that you call remove() on them. Instead, it might hang onto a task object until the next frame, for bookkeeping purposes.
The lesson, though, is that in general you shouldn’t rely on del being called at any particular time, unless you very tightly control the references to a particular object. This is true of any reference-count based memory system (or a garbage-collection system too, for that matter).
It does? I don’t see how. The sequence is invoked by the interval manager task, not by the current task. That means it will happen either this frame or next frame, according to whether the interval manager task has already run this frame or not. In either case, it gives the task manager a chance to dump its reference to the task you just removed before the interval runs.