Closed jamadden closed 4 years ago
Thank you for the excellent overview of the current problem. I have no idea what the cause of the problem is, nor how to fix it. But I do know one thing. Often just discussing a problem with others helps.
Maybe you could you be so kind as to explain how you think how this works, and what you have checked so far. By explaining your mental model of the system, one of the erudite developers on this mailing list may be able to point out what you are missing.
Chris
IIRC classes with __slots__
don't support weakrefs unless you explicitly add a slot for __weakref__
. Would that be enough to fix this?
IIRC classes with
__slots__
don't support weakrefs unless you explicitly add a slot for__weakref__
.
Right. Except, it turns out, on PyPy. That's why the test passes there.
>>>> class Foo(object):
.... __slots__ = ()
....
>>>> import weakref
>>>> weakref.ref(Foo())
<weakref at 0x000000010ff79500; to 'Foo'>
Would that be enough to fix this?
I think so, yes, at the cost of (1) increased size for all instances and (2) introducing a different incompatibility: CPersistent objects cannot be weakly referenced. In practice that's probably not very important, and since the main production use of the pure-Python implementation should be on PyPy (CPython+pure-Python is best for debugging and testing) where they can already be weakly referenced one could argue that it's even slightly more consistent, if one squints at it just right.
At any rate, I haven't thought of any other solution yet either.
How come CPersistent objects do not get the "TypeError: cannot create weak reference to ..." error then, if they don't support weakrefs?
Because the C cache doesn’t use weakrefs. At least, not at the Python level. Internally it cheats the ref counting rules, and arranges for the C Persistent class to directly notify it when an instance is deallocated.
The C implementation lets you store basic
Persistent
instances in the cache:But the pure-Python implementation does not:
This creates a test failure in ZODB:
(Why don't we see this failure running ZODB with PyPy? I'm not sure, but I'd guess that we don't even try to run this test; for some reason, PyPy runs only 814 ZODB unit tests while CPython runs 1185. In total, PyPy runs 1313 tests while CPython runs 1684 tests.)