zopefoundation / persistent

automatic persistence for Python objects
https://pypi.org/project/persistent/
Other
46 stars 28 forks source link

Python _p_activate can corrupt non-ghost objects and lead to POSKeyErrors for unsaved objects #9

Closed jamadden closed 10 years ago

jamadden commented 10 years ago

Previously, _p_activate in the pure-python Persistent object didn't check what the object's state was, only whether it had a jar and OID. It unconditionally called setstate on the jar if it had those two things. The C version, in contrast, checks it's state and only unghostifies itself if it is known to be a ghost.

There were two consequences to this behaviour difference. First, if _p_activate was ever called more than once on an object that had changes, those changes would get overwritten. Second, if _p_activate was called on an object that was newly added to a ZODB connection but not yet committed, ZODB's storage would throw a POSKeyError because the OID has only been assigned, it hasn't yet been saved.

It's subtle to see in the diff because it's an indentation difference, but this change makes the Python version also check its state and only unghostify true ghosts.

tseaver commented 10 years ago

Thanks for the analysis, and the patch!