[PATCH rfc] rfc: call gc at exit of mercurial
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Tue Apr 5 03:10:17 EDT 2016
On 04/04/2016 11:37 PM, Maciej Fijalkowski wrote:
> On Tue, Apr 5, 2016 at 8:36 AM, Pierre-Yves David
> <pierre-yves.david at ens-lyon.org> wrote:
>>
>>
>> On 04/04/2016 10:31 PM, Maciej Fijalkowski wrote:
>>>
>>> class A(object):
>>> def __del__(self):
>>> print "del"
>>>
>>> class B(object):
>>> pass
>>>
>>> b = B()
>>> b.b = b
>>> b.a = A()
>>>
>>>
>>> This example does not call __del__ in CPython either.
>>>
>>> The __del__ is not guaranteed to be called - that's why there is a
>>> painful module finalization procedure where CPython is trying to call
>>> "as much as possible", but there are still no guarantees. If you add
>>> del b; gc.collect() you will see "del" printed. Of course this
>>> involves a cycle, but cycles can come in ways that you don't expect
>>> them and PyPy simply says "everything is GCed". I think it's very much
>>> in line with what python-dev thinks.
>>
>>
>> Which is why we have __del__ in very few object and we deploy massive effort
>> to ensure their don't get caught in cycle and mostly succeeding at this.
>> (Kind of the same we put a lot of effort into making sure __del__ are never
>> really called but keep them as double safety).
>>
>> So in the case we care about (no cycle) Cpython would call our __del__,
>> right?
>>
>> --
>> Pierre-Yves David
>
> Yes, but I would argue you can create cycles without knowing. E.g.
>
> def f():
> try:
> some_stuff
> except:
> x = sys.exc_info()
>
> creates a cycle. There are also ways to create cycles with passing
> global functions around etc.
<situation-summary>
Sure we can always makes more mistake (and we sometimes do). But in most
of the rare case where __del__ catch one of this mistake, we don't have
an extra mistake that prevent it from catching it! (Okay, I admit, I
make this sentence extra confusing on purpose).
Simpler version (with cpython):
1) The official way is not to call __del__, we don't rely on it for well
written code, (this kind of greg's point)
2) However, in rare case, the situation is extra buggy and __del__ is
useful, (this is kind of my point),
3) However, in rare² care, the situation is extra² buggy and a cycle
prevent __del__ to be called.
The bad new is that Pypy mostly remove (2), and make (3) replace most of
it occurrence.
</situation-summary>
However, the good news is that we don't corrupt or loose anything in
(2). We just leave the repo into an unrecovered state that people can
recover with `hg recover`, so buggy code/situation expose slightly more
anoying behavior. This is probably fine. (There might be some super old
third party extension that will need to update itself).
someone should have a look at the other __del__ behavior and see if they
have as "harmless" behavior (eg: lock.__del__ would leave the repository
locked, but next run will remove that lock at the process is dead)
Cheers,
--
Pierre-Yves David
More information about the Mercurial-devel
mailing list