[Checkins] SVN: lovely.session/tags/0.2.2/ release

Nikolay Kim fafhrd91 at gmail.com
Fri Aug 14 07:02:17 EDT 2009


Log message for revision 102763:
  release

Changed:
  A   lovely.session/tags/0.2.2/
  D   lovely.session/tags/0.2.2/CHANGES.txt
  A   lovely.session/tags/0.2.2/CHANGES.txt
  D   lovely.session/tags/0.2.2/setup.py
  A   lovely.session/tags/0.2.2/setup.py
  D   lovely.session/tags/0.2.2/src/lovely/session/memcached.py
  A   lovely.session/tags/0.2.2/src/lovely/session/memcached.py
  D   lovely.session/tags/0.2.2/src/lovely/session/tests.py
  A   lovely.session/tags/0.2.2/src/lovely/session/tests.py

-=-
Deleted: lovely.session/tags/0.2.2/CHANGES.txt
===================================================================
--- lovely.session/trunk/CHANGES.txt	2009-08-13 08:21:42 UTC (rev 102731)
+++ lovely.session/tags/0.2.2/CHANGES.txt	2009-08-14 11:02:17 UTC (rev 102763)
@@ -1,42 +0,0 @@
-=======
-CHANGES
-=======
-
-0.2.1 (unreleased)
-------------------
-
-- Correctly implemented timeout behavior of session data.
-
-
-0.2.0 (2008-09-25)
-------------------
-
-- Made the DataManager savepoint aware.
-
-
-0.1.4 (2008-07-31)
-------------------
-
-- Fixed ZCML to avoid deprecation warnings, since the session API was moved to
-  ``zope.session``. *Sigh*
-
-
-0.1.3 (2008-07-31)
-------------------
-
-- Fixed `setup.py` to be on par with the latest layout.
-
-- Fixed deprecation warnings, since the session API was moved to
-  ``zope.session``.
-
-
-0.1.2 (2007-08-13)
-------------------
-
-- Move source to svn.zope.org.
-
-
-0.1.1 (2007-08-13)
-------------------
-
-- Fixed dependency on `lovely.memcached`.

Copied: lovely.session/tags/0.2.2/CHANGES.txt (from rev 102762, lovely.session/trunk/CHANGES.txt)
===================================================================
--- lovely.session/tags/0.2.2/CHANGES.txt	                        (rev 0)
+++ lovely.session/tags/0.2.2/CHANGES.txt	2009-08-14 11:02:17 UTC (rev 102763)
@@ -0,0 +1,50 @@
+=======
+CHANGES
+=======
+
+0.2.2 (2009-08-14)
+------------------
+
+- Add 'lastAccessTime' class attribute (fix old instances)
+
+
+0.2.1 (2009-08-14)
+------------------
+
+- Correctly implemented timeout behavior of session data.
+
+- Remove duplicate extras_require (python2.4 compatibility)
+
+
+0.2.0 (2008-09-25)
+------------------
+
+- Made the DataManager savepoint aware.
+
+
+0.1.4 (2008-07-31)
+------------------
+
+- Fixed ZCML to avoid deprecation warnings, since the session API was moved to
+  ``zope.session``. *Sigh*
+
+
+0.1.3 (2008-07-31)
+------------------
+
+- Fixed `setup.py` to be on par with the latest layout.
+
+- Fixed deprecation warnings, since the session API was moved to
+  ``zope.session``.
+
+
+0.1.2 (2007-08-13)
+------------------
+
+- Move source to svn.zope.org.
+
+
+0.1.1 (2007-08-13)
+------------------
+
+- Fixed dependency on `lovely.memcached`.

Deleted: lovely.session/tags/0.2.2/setup.py
===================================================================
--- lovely.session/trunk/setup.py	2009-08-13 08:21:42 UTC (rev 102731)
+++ lovely.session/tags/0.2.2/setup.py	2009-08-14 11:02:17 UTC (rev 102763)
@@ -1,74 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Setup for localy.session package
-
-$Id$
-"""
-import os
-from setuptools import setup, find_packages
-
-def read(*rnames):
-    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-
-setup(name='lovely.session',
-    version = '0.2.1dev',
-    author = "Lovely Systems GmbH",
-    author_email = "office at lovelysystems.com",
-    description = "memcache-based session storage",
-    long_description=(
-        read('src', 'lovely', 'session', 'README.txt')
-        + '\n\n' +
-        read('CHANGES.txt')
-        + '\n\n' +
-        '========\n'
-        'Download\n'
-        '========\n'
-        ),
-    license='ZPL 2.1',
-    keywords = "zope3 session memcache",
-    classifiers = [
-        'Development Status :: 4 - Beta',
-        'Environment :: Web Environment',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: Zope Public License',
-        'Programming Language :: Python',
-        'Natural Language :: English',
-        'Operating System :: OS Independent',
-        'Topic :: Internet :: WWW/HTTP',
-        'Topic :: Software Development :: Libraries :: Python Modules',
-        'Framework :: Zope3'],
-    url='http://pypi.python.org/pypi/lovely.session',
-    packages=find_packages('src'),
-    package_dir = {'': 'src'},
-    namespace_packages=['lovely',],
-    extras_require = dict(
-        test = ['zope.app.testing',
-                'zope.interface',
-                'zope.security',
-                'zope.testing',]),
-    install_requires = [
-        'setuptools',
-        'lovely.memcached',
-        'zope.app.container',
-        'zope.session',
-        'zope.schema',
-        ],
-    extras_require = dict(
-        test=['zope.app.testing',
-              'zope.app.zptpage',
-              'zope.app.securitypolicy',
-              'zope.app.zcmlfiles']),
-    include_package_data = True,
-    zip_safe = False,
-    )

Copied: lovely.session/tags/0.2.2/setup.py (from rev 102756, lovely.session/trunk/setup.py)
===================================================================
--- lovely.session/tags/0.2.2/setup.py	                        (rev 0)
+++ lovely.session/tags/0.2.2/setup.py	2009-08-14 11:02:17 UTC (rev 102763)
@@ -0,0 +1,70 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Setup for localy.session package
+
+$Id$
+"""
+import os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+setup(name='lovely.session',
+    version = '0.2.2',
+    author = "Lovely Systems GmbH",
+    author_email = "office at lovelysystems.com",
+    description = "memcache-based session storage",
+    long_description=(
+        read('src', 'lovely', 'session', 'README.txt')
+        + '\n\n' +
+        read('CHANGES.txt')
+        + '\n\n' +
+        '========\n'
+        'Download\n'
+        '========\n'
+        ),
+    license='ZPL 2.1',
+    keywords = "zope3 session memcache",
+    classifiers = [
+        'Development Status :: 4 - Beta',
+        'Environment :: Web Environment',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: Zope Public License',
+        'Programming Language :: Python',
+        'Natural Language :: English',
+        'Operating System :: OS Independent',
+        'Topic :: Internet :: WWW/HTTP',
+        'Topic :: Software Development :: Libraries :: Python Modules',
+        'Framework :: Zope3'],
+      url='http://pypi.python.org/pypi/lovely.session',
+      packages=find_packages('src'),
+      package_dir = {'': 'src'},
+      namespace_packages=['lovely',],
+      install_requires = ['setuptools',
+                          'lovely.memcached',
+                          'zope.app.container',
+                          'zope.session',
+                          'zope.schema',
+                          'zope.interface',
+                          ],
+      extras_require = dict(test=['zope.app.testing',
+                                  'zope.app.zptpage',
+                                  'zope.app.securitypolicy',
+                                  'zope.app.zcmlfiles',
+                                  'zope.testing',
+                                  'zope.security']),
+      include_package_data = True,
+      zip_safe = False,
+      )

Deleted: lovely.session/tags/0.2.2/src/lovely/session/memcached.py
===================================================================
--- lovely.session/trunk/src/lovely/session/memcached.py	2009-08-13 08:21:42 UTC (rev 102731)
+++ lovely.session/tags/0.2.2/src/lovely/session/memcached.py	2009-08-14 11:02:17 UTC (rev 102763)
@@ -1,253 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Lovely Systems and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-import md5
-import cPickle
-import memcache
-import time
-from threading import local
-
-import persistent
-import transaction
-from transaction.interfaces import ISavepointDataManager
-from transaction.interfaces import IDataManagerSavepoint
-
-from zope import interface
-from zope import component
-
-from zope.schema.fieldproperty import FieldProperty
-
-from zope.app.container.contained import Contained
-from zope.session.interfaces import (
-    ISessionDataContainer,
-    ISessionData,
-    ISessionPkgData,
-    )
-from zope.session.session import PersistentSessionDataContainer
-
-from lovely.memcached.interfaces import IMemcachedClient
-from lovely.session.interfaces import IMemCachedSessionDataContainer
-
-
-class MemCachedSessionDataContainer(persistent.Persistent, Contained):
-    interface.implements(ISessionDataContainer, IMemCachedSessionDataContainer)
-
-    cacheName = FieldProperty(IMemCachedSessionDataContainer['cacheName'])
-
-    def __init__(self):
-        self.resolution = 5*60
-        self.timeout = 1 * 60 * 60
-        self.lastAccessTime = int(time.time())
-
-    def get(self, key, default=None):
-        return self[key]
-
-    def __contains__(self, key):
-        return key in self.dataManagers
-
-    def __getitem__(self, key):
-        # getitem never fails to make sure the session uses our own PkgData
-        # implementation.
-        if key in self.dataManagers:
-            if int(time.time()) - self.lastAccessTime < self.timeout:
-                dm = self.dataManagers[key]
-            else:
-                del self.dataManagers[key]
-                dm = DataManager(self, key)
-                txn = transaction.manager.get()
-                txn.join(dm)
-                self.dataManagers[key] = dm
-                item = self.client.query(self._buildKey(key))
-                if item is None:
-                    item = MemCacheSessionData()
-                dm.data = item
-        else:
-            dm = DataManager(self, key)
-            txn = transaction.manager.get()
-            txn.join(dm)
-            self.dataManagers[key] = dm
-            item = self.client.query(self._buildKey(key))
-            if item is None:
-                item = MemCacheSessionData()
-            dm.data = item
-
-        now = int(time.time())
-        if self.lastAccessTime + self.resolution < now:
-            self.lastAccessTime = now
-            
-        return dm.data
-
-    def __setitem__(self, key, value):
-        pass
-
-    def items(self):
-        return self.dataManagers.items()
-
-    def _commitManager(self, key):
-        if key in self.dataManagers:
-            dm = self.dataManagers[key]
-            if not dm.changed:
-                del self.dataManagers[key]
-                return
-            if self.client.set(dm.data,
-                               self._buildKey(key),
-                               self.timeout):
-                del self.dataManagers[key]
-
-    def _abortManager(self, key):
-        #TODO: ???
-        if key in self.dataManagers:
-            del self.dataManagers[key]
-
-    def _buildKey(self, key):
-        m = md5.new(key)
-        return 'lovely.session.memcached:%s/%s'%(
-                    self.__name__.encode('utf-8'),
-                    m.hexdigest())
-
-    @property
-    def dataManagers(self):
-        res = getattr(self.storage, 'dataManagers', None)
-        if res is None:
-            res = {}
-            self.storage.dataManagers = res
-        return res
-
-    @property
-    def client(self):
-        return component.getUtility(IMemcachedClient, self.cacheName)
-
-    @property
-    def storage(self):
-        # we use a thread local storage to have a memcache client for every
-        # thread.
-        if not hasattr(self, '_v_storage'):
-            self._v_storage = local()
-        return self._v_storage
-
-
-class MemCacheData(dict):
-    """See zope.session.interfaces.ISessionData
-    """
-    interface.implements(ISessionPkgData)
-
-
-class MemCacheSessionData(dict):
-    """See zope.session.interfaces.ISessionData"""
-    interface.implements(ISessionData)
-    lastAccessTime = 0
-
-    def __init__(self):
-        self.lastAccessTime = int(time.time())
-
-    def __getitem__(self, key):
-        try:
-            return super(MemCacheSessionData, self).__getitem__(key)
-        except KeyError:
-            data = MemCachePkgData()
-            self[key] = data
-            return data
-
-
-class MemCachePkgData(dict):
-    """"""
-    interface.implements(ISessionPkgData)
-
-
-class DataManager(object):
-    """A data manager for the transaction management of the session data"""
-    interface.implements(ISavepointDataManager)
-
-    def __init__(self, sessionData, key):
-        self.sessionData = sessionData
-        self._data = None
-        self.key = key
-
-    @apply
-    def data():
-        def get(self):
-            return self._data
-        def set(self, value):
-            self._data = value
-            self._oldData = cPickle.dumps(value)
-        return property(get, set)
-
-    @property
-    def changed(self):
-        return cPickle.dumps(self.data)!=self._oldData
-
-    def abort(self, trans):
-        self.sessionData._abortManager(self.key)
-
-    def tpc_begin(self, trans):
-        pass
-
-    def commit(self, trans):
-        pass
-
-    def tpc_vote(self, trans):
-        pass
-
-    def tpc_finish(self, trans):
-        self.sessionData._commitManager(self.key)
-
-    def tpc_abort(self, trans):
-        self.sessionData._abortManager(self.key)
-
-    def sortKey(self):
-        return str(id(self))
-
-    def savepoint(self):
-        # When we create the savepoint, we save the existing database state.
-        return Savepoint(self, cPickle.dumps(self._data))
-
-    def _rollback_savepoint(self, data):
-        # When we rollback the savepoint, we restore the saved data.
-        # Caution:  without the pickle, further changes to the database
-        # could reflect in savepoint.data, and then `savepoint` would no
-        # longer contain the originally saved data, and so `savepoint`
-        # couldn't restore the original state if a rollback to this
-        # savepoint was done again.  IOW, pickle is necessary.
-
-        # there is also a small dance around with the container and
-        # and data not to break referenced variables
-        # the MemCachedSessionDataContainer / MemCacheSessionData / MemCachePkgData
-        # seems to be stable so this seems to be reasonable
-
-        state = cPickle.loads(data)
-        self._data.lastAccessTime = state.lastAccessTime
-        for k,v in state.items():
-            self._data[k].update(v)
-            todel = [x for x in self._data[k].keys() if x not in v.keys()]
-            for x in todel:
-                del self._data[k][x]
-
-        todel = [x for x in self._data.keys() if x not in state.keys()]
-        for x in todel:
-            del self._data[x]
-
-
-class Savepoint(object):
-
-    interface.implements(IDataManagerSavepoint)
-
-    def __init__(self, data_manager, data):
-        self.data_manager = data_manager
-        self.data = data
-
-    def rollback(self):
-        self.data_manager._rollback_savepoint(self.data)

Copied: lovely.session/tags/0.2.2/src/lovely/session/memcached.py (from rev 102762, lovely.session/trunk/src/lovely/session/memcached.py)
===================================================================
--- lovely.session/tags/0.2.2/src/lovely/session/memcached.py	                        (rev 0)
+++ lovely.session/tags/0.2.2/src/lovely/session/memcached.py	2009-08-14 11:02:17 UTC (rev 102763)
@@ -0,0 +1,255 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+import md5
+import cPickle
+import memcache
+import time
+from threading import local
+
+import persistent
+import transaction
+from transaction.interfaces import ISavepointDataManager
+from transaction.interfaces import IDataManagerSavepoint
+
+from zope import interface
+from zope import component
+
+from zope.schema.fieldproperty import FieldProperty
+
+from zope.app.container.contained import Contained
+from zope.session.interfaces import (
+    ISessionDataContainer,
+    ISessionData,
+    ISessionPkgData,
+    )
+from zope.session.session import PersistentSessionDataContainer
+
+from lovely.memcached.interfaces import IMemcachedClient
+from lovely.session.interfaces import IMemCachedSessionDataContainer
+
+
+class MemCachedSessionDataContainer(persistent.Persistent, Contained):
+    interface.implements(ISessionDataContainer, IMemCachedSessionDataContainer)
+
+    cacheName = FieldProperty(IMemCachedSessionDataContainer['cacheName'])
+
+    lastAccessTime = int(time.time())
+
+    def __init__(self):
+        self.resolution = 5*60
+        self.timeout = 1 * 60 * 60
+        self.lastAccessTime = int(time.time())
+
+    def get(self, key, default=None):
+        return self[key]
+
+    def __contains__(self, key):
+        return key in self.dataManagers
+
+    def __getitem__(self, key):
+        # getitem never fails to make sure the session uses our own PkgData
+        # implementation.
+        if key in self.dataManagers:
+            if int(time.time()) - self.lastAccessTime < self.timeout:
+                dm = self.dataManagers[key]
+            else:
+                del self.dataManagers[key]
+                dm = DataManager(self, key)
+                txn = transaction.manager.get()
+                txn.join(dm)
+                self.dataManagers[key] = dm
+                item = self.client.query(self._buildKey(key))
+                if item is None:
+                    item = MemCacheSessionData()
+                dm.data = item
+        else:
+            dm = DataManager(self, key)
+            txn = transaction.manager.get()
+            txn.join(dm)
+            self.dataManagers[key] = dm
+            item = self.client.query(self._buildKey(key))
+            if item is None:
+                item = MemCacheSessionData()
+            dm.data = item
+
+        now = int(time.time())
+        if self.lastAccessTime + self.resolution < now:
+            self.lastAccessTime = now
+            
+        return dm.data
+
+    def __setitem__(self, key, value):
+        pass
+
+    def items(self):
+        return self.dataManagers.items()
+
+    def _commitManager(self, key):
+        if key in self.dataManagers:
+            dm = self.dataManagers[key]
+            if not dm.changed:
+                del self.dataManagers[key]
+                return
+            if self.client.set(dm.data,
+                               self._buildKey(key),
+                               self.timeout):
+                del self.dataManagers[key]
+
+    def _abortManager(self, key):
+        #TODO: ???
+        if key in self.dataManagers:
+            del self.dataManagers[key]
+
+    def _buildKey(self, key):
+        m = md5.new(key)
+        return 'lovely.session.memcached:%s/%s'%(
+                    self.__name__.encode('utf-8'),
+                    m.hexdigest())
+
+    @property
+    def dataManagers(self):
+        res = getattr(self.storage, 'dataManagers', None)
+        if res is None:
+            res = {}
+            self.storage.dataManagers = res
+        return res
+
+    @property
+    def client(self):
+        return component.getUtility(IMemcachedClient, self.cacheName)
+
+    @property
+    def storage(self):
+        # we use a thread local storage to have a memcache client for every
+        # thread.
+        if not hasattr(self, '_v_storage'):
+            self._v_storage = local()
+        return self._v_storage
+
+
+class MemCacheData(dict):
+    """See zope.session.interfaces.ISessionData
+    """
+    interface.implements(ISessionPkgData)
+
+
+class MemCacheSessionData(dict):
+    """See zope.session.interfaces.ISessionData"""
+    interface.implements(ISessionData)
+    lastAccessTime = 0
+
+    def __init__(self):
+        self.lastAccessTime = int(time.time())
+
+    def __getitem__(self, key):
+        try:
+            return super(MemCacheSessionData, self).__getitem__(key)
+        except KeyError:
+            data = MemCachePkgData()
+            self[key] = data
+            return data
+
+
+class MemCachePkgData(dict):
+    """"""
+    interface.implements(ISessionPkgData)
+
+
+class DataManager(object):
+    """A data manager for the transaction management of the session data"""
+    interface.implements(ISavepointDataManager)
+
+    def __init__(self, sessionData, key):
+        self.sessionData = sessionData
+        self._data = None
+        self.key = key
+
+    @apply
+    def data():
+        def get(self):
+            return self._data
+        def set(self, value):
+            self._data = value
+            self._oldData = cPickle.dumps(value)
+        return property(get, set)
+
+    @property
+    def changed(self):
+        return cPickle.dumps(self.data)!=self._oldData
+
+    def abort(self, trans):
+        self.sessionData._abortManager(self.key)
+
+    def tpc_begin(self, trans):
+        pass
+
+    def commit(self, trans):
+        pass
+
+    def tpc_vote(self, trans):
+        pass
+
+    def tpc_finish(self, trans):
+        self.sessionData._commitManager(self.key)
+
+    def tpc_abort(self, trans):
+        self.sessionData._abortManager(self.key)
+
+    def sortKey(self):
+        return str(id(self))
+
+    def savepoint(self):
+        # When we create the savepoint, we save the existing database state.
+        return Savepoint(self, cPickle.dumps(self._data))
+
+    def _rollback_savepoint(self, data):
+        # When we rollback the savepoint, we restore the saved data.
+        # Caution:  without the pickle, further changes to the database
+        # could reflect in savepoint.data, and then `savepoint` would no
+        # longer contain the originally saved data, and so `savepoint`
+        # couldn't restore the original state if a rollback to this
+        # savepoint was done again.  IOW, pickle is necessary.
+
+        # there is also a small dance around with the container and
+        # and data not to break referenced variables
+        # the MemCachedSessionDataContainer / MemCacheSessionData / MemCachePkgData
+        # seems to be stable so this seems to be reasonable
+
+        state = cPickle.loads(data)
+        self._data.lastAccessTime = state.lastAccessTime
+        for k,v in state.items():
+            self._data[k].update(v)
+            todel = [x for x in self._data[k].keys() if x not in v.keys()]
+            for x in todel:
+                del self._data[k][x]
+
+        todel = [x for x in self._data.keys() if x not in state.keys()]
+        for x in todel:
+            del self._data[x]
+
+
+class Savepoint(object):
+
+    interface.implements(IDataManagerSavepoint)
+
+    def __init__(self, data_manager, data):
+        self.data_manager = data_manager
+        self.data = data
+
+    def rollback(self):
+        self.data_manager._rollback_savepoint(self.data)

Deleted: lovely.session/tags/0.2.2/src/lovely/session/tests.py
===================================================================
--- lovely.session/trunk/src/lovely/session/tests.py	2009-08-13 08:21:42 UTC (rev 102731)
+++ lovely.session/tags/0.2.2/src/lovely/session/tests.py	2009-08-14 11:02:17 UTC (rev 102763)
@@ -1,39 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Lovely Systems and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import unittest
-from zope import component
-import zope.interface
-import zope.security
-from zope.testing import doctest
-from zope.testing.doctestunit import DocTestSuite, DocFileSuite
-from zope.app.testing import setup
-
-
-def test_suite():
-    level2Suites = (
-        DocFileSuite('README.txt',
-             optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-             ),
-            )
-    for suite in level2Suites:
-        suite.level = 2
-    return unittest.TestSuite(level2Suites)
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')

Copied: lovely.session/tags/0.2.2/src/lovely/session/tests.py (from rev 102754, lovely.session/trunk/src/lovely/session/tests.py)
===================================================================
--- lovely.session/tags/0.2.2/src/lovely/session/tests.py	                        (rev 0)
+++ lovely.session/tags/0.2.2/src/lovely/session/tests.py	2009-08-14 11:02:17 UTC (rev 102763)
@@ -0,0 +1,32 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+from zope.testing import doctest
+
+
+def test_suite():
+    return unittest.TestSuite((
+            doctest.DocFileSuite(
+                'README.txt',
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            ),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')



More information about the Checkins mailing list