[Zodb-checkins] SVN: ZODB/branches/tseaver-python_picklecache-2/src/persistent/ Add extra properties from the C implementation.
Tres Seaver
tseaver at palladion.com
Tue Feb 15 13:55:54 EST 2011
Log message for revision 120353:
Add extra properties from the C implementation.
These attributes are not defined in IPersistent.
Changed:
U ZODB/branches/tseaver-python_picklecache-2/src/persistent/pypersistent.py
U ZODB/branches/tseaver-python_picklecache-2/src/persistent/tests/test_pypersistent.py
-=-
Modified: ZODB/branches/tseaver-python_picklecache-2/src/persistent/pypersistent.py
===================================================================
--- ZODB/branches/tseaver-python_picklecache-2/src/persistent/pypersistent.py 2011-02-15 18:55:53 UTC (rev 120352)
+++ ZODB/branches/tseaver-python_picklecache-2/src/persistent/pypersistent.py 2011-02-15 18:55:54 UTC (rev 120353)
@@ -11,7 +11,10 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
+import datetime
+import struct
import sys
+import time
from zope.interface import implements
@@ -23,9 +26,34 @@
else:
OID_TYPE = SERIAL_TYPE = bytes
+# Bitwise flags
_CHANGED = 0x0001
_STICKY = 0x0002
+# Allowed values for _p_state
+GHOST = -1
+UPTODATE = 0
+CHANGED = 1
+STICKY = 2
+
+_SCONV = 60.0 / (1<<16) / (1<<16)
+
+def makeTimestamp(year, month, day, hour, minute, second):
+ a = (((year - 1900) * 12 + month - 1) * 31 + day - 1)
+ a = (a * 24 + hour) * 60 + minute
+ b = int(second / _SCONV)
+ return struct.pack('>II', a, b)
+
+def parseTimestamp(octets):
+ a, b = struct.unpack('>II', octets)
+ minute = a % 60
+ hour = a // 60 % 24
+ day = a // (60 * 24) % 31 + 1
+ month = a // (60 * 24 * 31) % 12 + 1
+ year = a // (60 * 24 * 31 * 12) + 1900
+ second = b * _SCONV
+ return (year, month, day, hour, minute, second)
+
class Persistent(object):
__slots__ = ('__jar', '__oid', '__serial', '__flags')
implements(IPersistent)
@@ -135,6 +163,41 @@
_p_status = property(_get_status)
+ # These attributes are defined by the C type, but not IPersistent.
+ def _get_mtime(self):
+ if self.__serial is not None:
+ when = datetime.datetime(*parseTimestamp(self.__serial))
+ return time.mktime(when.timetuple())
+ _p_mtime = property(_get_mtime)
+
+ # _p_state
+ def _get_state(self):
+ if self.__flags is None:
+ if self.__jar is None:
+ return UPTODATE
+ return GHOST
+ if self.__flags & _CHANGED:
+ if self.__jar is None:
+ return UPTODATE
+ result = CHANGED
+ else:
+ result = UPTODATE
+ if self.__flags & _STICKY:
+ return STICKY
+ return result
+
+ _p_state = property(_get_state)
+
+ # _p_estimated_size: XXX don't want to reserve the space?
+ def _get_estimated_size(self):
+ return 0
+
+ def _set_estimated_size(self, value):
+ pass
+
+ _p_estimated_size = property(_get_estimated_size, _set_estimated_size)
+
+ # Methods from IPersistent.
def __getstate__(self):
""" See IPersistent.
"""
Modified: ZODB/branches/tseaver-python_picklecache-2/src/persistent/tests/test_pypersistent.py
===================================================================
--- ZODB/branches/tseaver-python_picklecache-2/src/persistent/tests/test_pypersistent.py 2011-02-15 18:55:53 UTC (rev 120352)
+++ ZODB/branches/tseaver-python_picklecache-2/src/persistent/tests/test_pypersistent.py 2011-02-15 18:55:54 UTC (rev 120353)
@@ -358,6 +358,67 @@
inst._p_sticky = True
self.assertEqual(inst._p_status, 'saved (sticky)')
+ def test__p_mtime_no_serial(self):
+ inst = self._makeOne()
+ self.assertEqual(inst._p_mtime, None)
+
+ def test__p_mtime_w_serial(self):
+ import datetime
+ import time
+ from persistent.pypersistent import makeTimestamp
+ WHEN_TUPLE = (2011, 2, 15, 13, 33, 27.5)
+ WHEN = datetime.datetime(*WHEN_TUPLE)
+ inst, jar, OID = self._makeOneWithJar()
+ inst._p_serial = makeTimestamp(*WHEN_TUPLE)
+ self.assertEqual(inst._p_mtime, time.mktime(WHEN.timetuple()))
+
+ def test__p_state_new(self):
+ inst = self._makeOne()
+ self.assertEqual(inst._p_state, 0)
+
+ def test__p_state_unsaved(self):
+ inst = self._makeOne()
+ inst._p_changed = True
+ self.assertEqual(inst._p_state, 0)
+
+ def test__p_state_ghost(self):
+ inst, jar, OID = self._makeOneWithJar()
+ self.assertEqual(inst._p_state, -1)
+
+ def test__p_state_changed(self):
+ inst, jar, OID = self._makeOneWithJar()
+ inst._p_changed = True
+ self.assertEqual(inst._p_state, 1)
+
+ def test__p_state_changed_sticky(self):
+ # 'sticky' is not a state, but a separate flag.
+ inst, jar, OID = self._makeOneWithJar()
+ inst._p_changed = True
+ inst._p_sticky = True
+ self.assertEqual(inst._p_state, 2)
+
+ def test__p_state_saved(self):
+ inst, jar, OID = self._makeOneWithJar()
+ inst._p_changed = False
+ self.assertEqual(inst._p_state, 0)
+
+ def test__p_state_saved_sticky(self):
+ # 'sticky' is not a state, but a separate flag.
+ inst, jar, OID = self._makeOneWithJar()
+ inst._p_changed = False
+ inst._p_sticky = True
+ self.assertEqual(inst._p_state, 2)
+
+ def test_query_p_estimated_size(self):
+ inst = self._makeOne()
+ self.assertEqual(inst._p_estimated_size, 0)
+
+ def test_assign_p_estimated_size(self):
+ # XXX at the moment, we don't store this value.
+ inst = self._makeOne()
+ inst._p_estimated_size = 123
+ self.assertEqual(inst._p_estimated_size, 0)
+
def test___getstate__(self):
inst = self._makeOne()
self.assertEqual(inst.__getstate__(), {})
More information about the Zodb-checkins
mailing list