On 02/01/2020 02:53, Yonatan Zunger wrote:
Oh, I'm absolutely thinking about clarity. ...

Could any revision also be clear what is *required of Python the language* vs. what is a CPython implementation detail? I always appreciate this care. There is good practice here and elsewhere in the existing documentation, but drift is easy for those steeped in CPython implementation. In the present case, it's a matter of avoiding an explicit requirement for a reference-counting approach to lifecycle management. Here the places in the proposal a change could achieve that.


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, ...

We should continue here "... immediately the object is no nonger referenced;"

(It might not be called immediately, but that's implied by your implementation-dependent "might be".)


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.

I realise that most of this paragraph is existing text rearranged, and currently it fails to make the distinction I'm looking for in the "note" part. But it is clear in the next paragraph. I think it better to say, closer to the current text:

"""Note:: ``del x`` does not call ``x.__del__()`` directly. After ``del x``, variable ``x`` is undefined (or unbound). If the object it referenced is now no longer referenced at all,  that object's ``__del__()`` might be called, immediately or later, subject to the caveats already given.

*CPython implementation detail:* ``del x`` decrements the reference count of the object by one, and if that makes it zero, ``x.__del__()`` will be called immediately. It is possible for a reference cycle to prevent the reference count of any object in it from going to zero. 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 detected later and its objects 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.

Possibly this thought belings with the "implementations of __del__(): * Must ..." paragraph.

But also, while I think there is scope for a better guidance, this is getting a bit long. Should there be a "HOW TO write a __del__ method (and how to avoid it)" to contain the advisory points being made? In-lining advice here, on how to survive the infernal circles of __del__, dilutes the scariness of the warning not to enter at all.

---

Jeff Allen

_______________________________________________
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/A32QEUP4R6XTY5LQW56LKWJ3XBUZCHOR/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to