[PATCH rfc] rfc: call gc at exit of mercurial

Maciej Fijalkowski fijall at gmail.com
Tue Apr 5 03:24:07 EDT 2016


Right, that's a good summary. I was merely pointing out that from
python perspective this behavior is ok (not whether from mercurial
perspective it's ok  or not - it's up to you to decided :-)

On Tue, Apr 5, 2016 at 9:10 AM, Pierre-Yves David
<pierre-yves.david at ens-lyon.org> wrote:
>
>
> 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