Amaury Forgeot d'Arc, 18.02.2012 15:18:
2012/2/18 Stefan Behnel
I couldn't find the PyWeakref_LockObject() function anywhere. That's a PyPy-only thing, right? I aliased it to (NULL) when compiling for CPython.
Yes, this function is PyPy-only, to fix a flaw of PyWeakref_GetObject: it returns a borrowed reference, which is very dangerous because the object can disappear anytime: with a garbage collection, or another thread... Fortunately the GIL is here to protect you, but the only sane thing to do is to quickly INCREF the returned reference. PyWeakref_LockObject directly returns a new reference.
In PyPy, the behavior of PyWeakref_GetObject is even worse: to avoid returning a refcount of zero, the returned reference is attached to the weakref, effectively turning it into a strong reference! I now realize that this was written before we implemented the "temporary container" for borrowed references: PyWeakref_GetObject() could return a reference valid for the duration of the current C call.
Do you mean that you could actually fix this in PyPy so that lxml won't have to use that function? Or would it still have to use it, because the references are stored away and thus become long-living? (i.e. longer than the C call) Stefan