Your test program performs no resurrection of x.

Interestingly, it does not change behavior if you write

class X(object):
    def __del__(self):
        X.x = self
        print ref()

(Thanks for making me aware of this! My test-case was already
initially the more complex one given below)

But if the resurrection occurs indirectly, the weakref persists:
(I refined it to old-style class, because Jython will support new-style
class finalizers only from 2.7. beta 4 onwards, i.e. the test would be
pointless with any current release)

import weakref, time, gc
class ReferentDummy():
    pass

class X():
    def __del__(self):
        X.y = self.z
        print "__del__: "+str(ref())

x = X()
x2 = ReferentDummy()
ref = weakref.ref(x2)
x.z = x2
del x2
del x #Everything is now deleted, isn't it?
gc.collect() #needed in Jython-case
time.sleep(0.2) #wait for Java's async gc to finnish
print ref()
print weakref.getweakrefs(X.y)


---------------CPython output:
__del__: <__main__.ReferentDummy instance at 0x7fd2603e1950>
<__main__.ReferentDummy instance at 0x7fd2603e1950>
[<weakref at 0x7fd2603d2c00; to 'instance' at 0x7fd2603e1950>]

---------------Jython 2.7 beta 3 output:
__del__: None
None
[]

One can surely argue x2 has never been dead, or see it as "it was killed along with x and then resurrected by x". Jython clearly takes the second point of view and also clears weakrefs to x.z, while CPython does not. Yes, these details probably hardly matter in practice (however could cause subtle bugs when porting complex stuff from CPython to Jython), but since I try to
bridge it, I have to look into this more carefully.

Best,

Stefan



On 10/26/2014 06:44 PM, Armin Rigo wrote:
Hi Stefan,

On 26 October 2014 02:50, Stefan Richthofer <stefan.richtho...@gmx.de> wrote:
It appears weakrefs are only cleared if this is done by gc (where no
resurrection can happen anyway). If a resurrection-performing-__del__ is
just called by ref-count-drop-to-0, weakrefs persist -
How do you reach this conclusion?  The following test program seems to
show the opposite, by printing None on Python 2.7.6:

     import weakref
    class X(object):
         def __del__(self):
             print ref()
     x = X()
     ref = weakref.ref(x)
     del x


A bientôt,

Armin.

_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to