title: Use cases for __del__
body: <p>What are use cases in python 3 of writing a custom <code>__del__</code> method or relying on one from stdlib<sup>1</sup>? That is, in what scenario is it reasonably safe, and can do something that's hard to do without it?</p>
  
  <p>For many good reasons (<a href="https://stackoverflow.com/a/6104568/336527">1</a> <a href="http://www.andy-pearce.com/blog/posts/2013/Apr/python-destructor-drawbacks/" rel="noreferrer">2</a> <a href="https://github.com/python-zk/kazoo/issues/384#issuecomment-196536319" rel="noreferrer">3</a> <a href="https://stackoverflow.com/a/35489349/336527">4</a> <a href="https://stackoverflow.com/a/10352514/336527">5</a> <a href="https://stackoverflow.com/a/7659862/336527">6</a>), the usual recommendation is to avoid <code>__del__</code> and instead use context managers or perform the cleanup manually:</p>
  
  <ol>
  <li><code>__del__</code> is not guaranteed to be called if objects are alive on intrepreter exit<sup>2</sup>.</li>
  <li>At the point one expects the object can be destroyed, the ref count may actually be non-zero (e.g., a reference may survive through a traceback frame held onto by a calling function). This makes the destruction time far more uncertain than the mere unpredictability of <code>gc</code> implies.</li>
  <li>Garbage collector cannot get rid of cycles if they include more than 1 object with <code>__del__</code></li>
  <li>The code inside <code>__del__</code> must be written super carefully:
  
  <ul>
  <li>object attributes set in <code>__init__</code> may not be present since <code>__init__</code> might have raised an exception;</li>
  <li>exceptions are ignored (only printed to <code>stderr</code>);</li>
  <li>globals may no longer be available.</li>
  </ul></li>
  </ol>
  
  <hr>
  
  <p>Update:</p>
  
  <p><a href="https://www.python.org/dev/peps/pep-0442/" rel="noreferrer">PEP 442</a> has made significant improvements in the behavior of <code>__del__</code>. It seems though that my points 1-4 are still valid?</p>
  
  <hr>
  
  <p>Update 2:</p>
  
  <p>Some of the top python libraries <a href="https://github.com/aio-libs/aiohttp/issues/537" rel="noreferrer">embrace the use of <code>__del__</code></a> in the post-PEP 442 python (i.e., python 3.4+). I guess my point 3 is no longer valid after PEP 442, and the other points are accepted as unavoidable complexity of object finalization. </p>
  
  <hr>
  
  <p><sup>1</sup>I expanded the question from just writing a custom <code>__del__</code> method to include relying on <code>__del__</code> from stdlib.</p>
  
  <p><sup>2</sup>It seems that <code>__del__</code> is always called on interpreter exit in the more recent versions of Cpython  (does anyone have a counter-example?). However, it doesn't matter for the purpose of <code>__del__</code>'s usablity: the docs explicitly <a href="https://docs.python.org/3/reference/datamodel.html#object.__del__" rel="noreferrer">provide no guarantee about this behavior</a>, so one cannot rely on it (it may change in future versions, and it may be different in non-CPython interpreters).</p>