New issue 2030: Circular weakref callbacks never called (self._x = 
weakref.ref(self, callback))
https://bitbucket.org/pypy/pypy/issue/2030/circular-weakref-callbacks-never-called

Jason Madden:

It appears that if an object holds a weak reference to itself, the callback for 
that reference is never called. It's as if when both the object and the 
reference to it become garbage at the same time, the callback isn't called. 

I ran into this testing ZODB under PyPy (it used this pattern in 
ZODB.blob.Blob).

Here's an example of what happens under CPython:

```
$ /opt/local/bin/python2.7
Python 2.7.9 (default, Dec 13 2014, 15:13:49)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import weakref, sys
>>> class X(object):
...     pass
...
>>> x = X()
>>> x._ref = weakref.ref(x, lambda r: sys.stderr.write('callback\n'))
>>> del x
callback
>>>
```

Now, under PyPy (both 2.5.1 and a relatively recent nightly), the callback 
doesn't get called when the reference is deleted (but we expect that):

```
$ pypy
Python 2.7.9 (9c4588d731b7, Mar 23 2015, 16:20:40)
[PyPy 2.5.1 with GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>> import weakref, sys
>>>> class X(object):
....     pass
....
>>>> x = X()
>>>> x._ref = weakref.ref(x, lambda r: sys.stderr.write('callback\n'))
>>>> del x
>>>>
```

No problem, we need to ask GC to do a collection. We've seen this before.
```
>>>> import gc
>>>> gc.collect()
0
```

Hmm, maybe a few collections?
```
>>>> for _ in range(100): _ = gc.collect()
>>>>
```

Nothing.

If we use a separate reference object with a different lifetime, then it is 
called immediately after the first GC:
```
>>>> x = X()
>>>> ref = weakref.ref(x, lambda r: sys.stderr.write('direct callback\n'))
>>>> del x
>>>> gc.collect()
direct callback
0
>>>>
```



_______________________________________________
pypy-issue mailing list
pypy-issue@python.org
https://mail.python.org/mailman/listinfo/pypy-issue

Reply via email to