Oh, I'm absolutely thinking about clarity. Something like:

----

This method is called when the instance is about to be destroyed. Because
it may be called by either the ordinary Python execution flow or by the
garbage collector, it has very unusual semantics, and must be treated with
great care. In almost all cases, you should instead use either
weakref.finalize (if you want logic to be called when an object is no
longer in use) or atexit.register (if you want to clean up before the
interpreter exits).

The precise semantics of when __del__ is called on an object are
implementation-dependent. For example:
* It might be invoked during the normal interpreter flow at a moment like
function return, if the reference count for an object has dropped to zero;
* It might be invoked by the garbage collector, which happens during the
normal interpreter flow but is called from an arbitrary thread;
* It might be invoked during interpreter shutdown, after various global
variables (including modules!) have already been deleted, or other threads'
interpreters have already stopped.
* It may not be invoked at all; it is *not guaranteed* that __del__()
methods are called for objects that still exist when the interpreter exits.

In particular, this means that, unless your program is structured so that
you can deterministically control when an object will be destroyed,
implementations of __del__():
* Must not assume that any variables outside self exist, including modules
or global variables;
* Must not attempt to acquire locks or otherwise block, since they may
(e.g.) be invoked inside a thread which already holds those resources;
* Must not rely on being able to signal other threads and wait for their
responses (even thread joins), since those threads' interpreters may have
exited;
* Must not cause failures (e.g. leaving external devices in an invalid
state) if they are *never* invoked.

Note that del x doesn’t directly call x.__del__() — the former decrements
the reference count for x by one, and the latter is only called when x’s
reference count reaches zero. Depending on the implementation, it is
possible for a reference cycle to prevent the reference count of an object
from going to zero. (e.g., in CPython, a common cause of reference cycles
is when an exception is caught and stored in a local variable; the
exception contains a reference to the traceback, which in turn references
the locals of all frames caught in the traceback.) In this case, the cycle
will be later detected and deleted by the cyclic garbage collector.

If a base class has a __del__() method, the derived class’s __del__()
method, if any, must explicitly call it to ensure proper deletion of the
base class part of the instance.

It is possible (though not recommended!) for the __del__() method to
postpone destruction of the instance by creating a new reference to it.
This is called object resurrection. It is implementation-dependent whether
__del__() is called a second time when a resurrected object is about to be
destroyed; the current CPython implementation only calls it once.



On Wed, Jan 1, 2020 at 12:57 PM Andrew Svetlov <andrew.svet...@gmail.com>
wrote:

> If the warning text tells about the delayed execution -- I'm +1.
> -1 for something like "just don't use __del__, it is dangerous".
>
> On Wed, Jan 1, 2020, 21:51 Gregory P. Smith <g...@krypto.org> wrote:
>
>>
>>
>> On Wed, Jan 1, 2020 at 6:40 AM Andrew Svetlov <andrew.svet...@gmail.com>
>> wrote:
>>
>>> __del__ is very useful not for interpreter shutdown but as a regular
>>> destructor in object's lifecycle.
>>>
>>
>> The reason we should warn people against ever implementing __del__ is
>> that people rarely actually understand object lifecycle.  Its presence
>> guarantees delayed garbage collection and that its code will code execute
>> in a context way outside of normal control flow that all other methods are
>> invoked from.
>>
>> -gps
>>
>>
>>>
>>> Action on the shutdown is another beast.
>>> Personally, I prefer to do all finalization works by explicit calls
>>> instead.
>>>
>>> On Wed, Jan 1, 2020 at 2:39 AM Yonatan Zunger <zun...@humu.com> wrote:
>>> >
>>> > Hey everyone,
>>> >
>>> > I just encountered yet another reason to beware of __del__: when it's
>>> called during interpreter shutdown, for reasons which are kind of obvious
>>> in retrospect, if it calls notify() on a threading.Condition, the waiting
>>> thread may or may not ever actually receive it, and so if it does that and
>>> then tries to join() the thread the interpreter may hang in a hard-to-debug
>>> way.
>>> >
>>> > This isn't something that can reasonably be fixed, and (like in most
>>> cases involving __del__) there's a very simple fix of using
>>> weakref.finalize instead. My question for the dev list: How would people
>>> feel about changing the documentation for the method to more bluntly warn
>>> people against using it, and refer them to weakref.finalize and/or
>>> atexit.register as an alternative? The text already has an undertone of
>>> "lasciate ogni speranza, voi ch'entrate" but it may be helpful to be more
>>> explicit to avoid people getting caught in unexpected pitfalls.
>>> >
>>> > Yonatan
>>> > _______________________________________________
>>> > Python-Dev mailing list -- python-dev@python.org
>>> > To unsubscribe send an email to python-dev-le...@python.org
>>> > https://mail.python.org/mailman3/lists/python-dev.python.org/
>>> > Message archived at
>>> https://mail.python.org/archives/list/python-dev@python.org/message/AAZQBWD6PHC4PVNCCPX4A2745SS7B3LS/
>>> > Code of Conduct: http://python.org/psf/codeofconduct/
>>>
>>>
>>>
>>> --
>>> Thanks,
>>> Andrew Svetlov
>>> _______________________________________________
>>> Python-Dev mailing list -- python-dev@python.org
>>> To unsubscribe send an email to python-dev-le...@python.org
>>> https://mail.python.org/mailman3/lists/python-dev.python.org/
>>> Message archived at
>>> https://mail.python.org/archives/list/python-dev@python.org/message/57CDW4NIYEQ3JEVX2JVCJDA5TXTC5MBR/
>>> Code of Conduct: http://python.org/psf/codeofconduct/
>>>
>>
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/NKWOXME256DT53PRLU3IMWORT2DZTRHO/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to