Are you saying that a finalizer is guaranteed to run when the last reference is deleted? So you could actually rely on them to handle the resources, as long as you are careful not to use reference cycles?
In CPython 2.7, yes. In CPython in general, I believe it's currently still the case, but I don't think it's guaranteed for future versions.
For Python in general, no. For example, as far as I know Jython reuses the JVM's GC (and its unreliable finalizers with it).
It's also easy to introduce accidental cycles. For one, a traceback includes a reference to every frame on the call stack, so storing that somewhere on the stack would create an unintentional cycle!
The tracebacks were a lot of what made me cut back on using weakrefs and trying to make things manage their resources automatically.
Now I use close() methods for anything that needs to be closed. If I mess up and there's some obscure bug, hopefully GC will fix it, but it seems too brittle and easy to make mistakes with to rely on.
For Python in general, no. For example, as far as I know Jython reuses the JVM's GC (and its unreliable finalizers with it).
It's also easy to introduce accidental cycles. For one, a traceback includes a reference to every frame on the call stack, so storing that somewhere on the stack would create an unintentional cycle!