I have a class (that I do not control) that doesn't implement its own cleanup. I thought that this is one of the cases that weakref.finalize
is for, but I can't get it working.
def cleanup(obj):
print('Cleanup obj')
if not obj.is_closed:
obj.close()
...
def make_obj():
obj = SomeClass()
# this creates an extra ref, so cleanup is never run
weakref.finalize(obj, cleanup, obj)
# this always results in ReferenceError; obj is already gone when cleanup is called
weakref.finalize(obj, cleanup, weakref.proxy(obj))
Am I doing something wrong? What have I misunderstood?
It is impossible to reference finalized object in weakref.finalize
. In "Note" section for weakref.finalize
it is stated:
It is important to ensure that func, args and kwargs do not own any references to obj, either directly or indirectly, since otherwise obj will never be garbage collected. In particular, func should not be a bound method of obj.
Thus, it is also impossible to orginize cleanup with bound method like weakref.finalize(obj, obj.close)
. In such case you need to call cleanup function yourself. Another option is to inherit from SomeClass
and make proper __del__
method.