Closed tseaver closed 8 years ago
I just discovered another inconsistency in https://github.com/NextThought/ZODB/commit/5d38a086be4bcf20558d8bcec33cd95d065a7082.
It turns out that the cPickleCache implementation only enforces the 8-length byte constraint in the __setitem__
implementation. If you use new_ghost
, it accepts any arbitrary value for the oid. The Python implementation enforces it both places.
ZODB initially creates and populates the picklecache using new_ghost
(Connection.get), so in practice it might seem like if you're using the cPickleCache the restriction is easily bypassed. However, once you commit the transaction, if you modified any of those objects, then you'll find that it calls __setitem__
and things blow up with a TypeError simply because cPickleCache checks the type of the key before checking to see if the key already exists.
I'll note that when I use a non-bytes _p_oid, I do not use pickle at all. Whenever pickle is used, you might as well use the ZODB facilities, because it takes care of most things you would ever want.
For me I specifically went down to the persistent layer for pjpersist because it does not deal with serialization and only provides the messaging framework.
I'll close this with the note that the consensus answer is "No, OIDs do not have to be bytes of length 8" for implementations which use jars other than those supplied by ZODB.
The docstring for
IPersistent._p_oid
claims that it must be bytes. Historically, the C implementation has allowed any type (although values which are not length 8 bytes blow up if used with a standard pickle cache).See: https://github.com/zopefoundation/persistent/pull/20#discussion-diff-28083537 for pros and cons.