Однажды стало жутко интересно почему не хотел умирать один объект. Попалась такая конструкция:
for client in clients:
do_something()
Так вот оказалось что если клиент оставался последним и мы делали clients.remove(our_dead_client) то цикл, конечно, не запускался и переменная client(та что использовалась в цикле for) удерживала ссылку на наш объект. Итог: объект жил и метод def __del__: print(«I am dead») не вызывался. А я почему-то был уверен что for-statement создаёт новый scope.
Очевидный «фикс»:
for client in clients:
do_something()
client = None
Хотя можно и не фиксить, всё равно полагаться на __del__ очень дурная практика которая к тому же зависит от реализации языка. Например, в jython gc работает по-другому. Просто было интересно разобраться в вопросе. Ушёл читать pep-3104