Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reference finalized object in weakref.finalize?

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?

like image 978
OrangeDog Avatar asked Aug 05 '26 11:08

OrangeDog


1 Answers

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.

like image 118
sanyassh Avatar answered Aug 08 '26 01:08

sanyassh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!