[Zodb-checkins] SVN: ZODB/branches/3.6/src/persistent/ Merge from trunk.

Stephan Richter srichter at cosmos.phy.tufts.edu
Sat Nov 5 08:54:50 EST 2005


Log message for revision 39911:
  Merge from trunk.
  

Changed:
  U   ZODB/branches/3.6/src/persistent/README.txt
  U   ZODB/branches/3.6/src/persistent/tests/persistent.txt

-=-
Modified: ZODB/branches/3.6/src/persistent/README.txt
===================================================================
--- ZODB/branches/3.6/src/persistent/README.txt	2005-11-05 13:41:40 UTC (rev 39910)
+++ ZODB/branches/3.6/src/persistent/README.txt	2005-11-05 13:54:50 UTC (rev 39911)
@@ -2,18 +2,18 @@
 Persistence support
 ===================
 
-(This document is under construction. More basic documentation will
- eventually appear here.)
+(This document is under construction. More basic documentation will eventually
+appear here.)
 
 
-Overriding __getattr__, __getattribute__, __setattr__, and __delattr__
------------------------------------------------------------------------  
+Overriding `__getattr__`, `__getattribute__`, `__setattr__`, and `__delattr__`
+------------------------------------------------------------------------------
 
 Subclasses can override the attribute-management methods.  For the
-__getattr__ method, the behavior is like that for regular Python
+`__getattr__` method, the behavior is like that for regular Python
 classes and for earlier versions of ZODB 3.
 
-For __getattribute__, __setattr__, and __delattr__, it is necessary to
-call certain methods defined by persistent.Persistent.  Detailed
+For `__getattribute__`, __setattr__`, and `__delattr__`, it is necessary
+to call certain methods defined by `persistent.Persistent`.  Detailed
 examples and documentation is provided in the test module,
-persistent.tests.test_overriding_attrs.
+`persistent.tests.test_overriding_attrs`.

Modified: ZODB/branches/3.6/src/persistent/tests/persistent.txt
===================================================================
--- ZODB/branches/3.6/src/persistent/tests/persistent.txt	2005-11-05 13:41:40 UTC (rev 39910)
+++ ZODB/branches/3.6/src/persistent/tests/persistent.txt	2005-11-05 13:54:50 UTC (rev 39911)
@@ -1,452 +1,458 @@
-Tests for persistent.Persistent
-===============================
+Tests for `persistent.Persistent`
+=================================
 
 This document is an extended doc test that covers the basics of the
-Persistent base class.  The test expects a class named 'P' to be
-provided in its globals.  The P class implements the Persistent
+Persistent base class.  The test expects a class named `P` to be
+provided in its globals.  The `P` class implements the `Persistent`
 interface.
 
 Test framework
 --------------
 
-The class P needs to behave like ExampleP.  (Note that the code below
+The class `P` needs to behave like `ExampleP`.  (Note that the code below
 is *not* part of the tests.)
 
-class ExampleP(Persistent):
-    def __init__(self):
-        self.x = 0
-    def inc(self):
-        self.x += 1
+::
 
+  class ExampleP(Persistent):
+      def __init__(self):
+          self.x = 0
+      def inc(self):
+          self.x += 1
+
 The tests use stub data managers.  A data manager is responsible for
 loading and storing the state of a persistent object.  It's stored in
-the _p_jar attribute of a persistent object.
+the ``_p_jar`` attribute of a persistent object.
 
->>> class DM:
-...     def __init__(self):
-...         self.called = 0
-...     def register(self, ob):
-...         self.called += 1
-...     def setstate(self, ob):
-...         ob.__setstate__({'x': 42})
+  >>> class DM:
+  ...     def __init__(self):
+  ...         self.called = 0
+  ...     def register(self, ob):
+  ...         self.called += 1
+  ...     def setstate(self, ob):
+  ...         ob.__setstate__({'x': 42})
 
->>> class BrokenDM(DM):
-...     def register(self,ob):
-...         self.called += 1
-...         raise NotImplementedError
-...     def setstate(self,ob):
-...         raise NotImplementedError
+  >>> class BrokenDM(DM):
+  ...     def register(self,ob):
+  ...         self.called += 1
+  ...         raise NotImplementedError
+  ...     def setstate(self,ob):
+  ...         raise NotImplementedError
 
->>> from persistent import Persistent
+  >>> from persistent import Persistent
 
+
 Test Persistent without Data Manager
 ------------------------------------
 
 First do some simple tests of a Persistent instance that does not have
-a data manager (_p_jar).
+a data manager (``_p_jar``).
 
->>> p = P()
->>> p.x
-0
->>> p._p_changed
-False
->>> p._p_state
-0
->>> p._p_jar
->>> p._p_oid
+  >>> p = P()
+  >>> p.x
+  0
+  >>> p._p_changed
+  False
+  >>> p._p_state
+  0
+  >>> p._p_jar
+  >>> p._p_oid
 
-Verify that modifications have no effect on _p_state of _p_changed.
+Verify that modifications have no effect on ``_p_state`` of ``_p_changed``.
 
->>> p.inc()
->>> p.inc()
->>> p.x
-2
->>> p._p_changed
-False
->>> p._p_state
-0
+  >>> p.inc()
+  >>> p.inc()
+  >>> p.x
+  2
+  >>> p._p_changed
+  False
+  >>> p._p_state
+  0
 
 Try all sorts of different ways to change the object's state.
 
->>> p._p_deactivate()
->>> p._p_state
-0
->>> p._p_changed = True
->>> p._p_state
-0
->>> del p._p_changed
->>> p._p_changed
-False
->>> p._p_state
-0
->>> p.x
-2
+  >>> p._p_deactivate()
+  >>> p._p_state
+  0
+  >>> p._p_changed = True
+  >>> p._p_state
+  0
+  >>> del p._p_changed
+  >>> p._p_changed
+  False
+  >>> p._p_state
+  0
+  >>> p.x
+  2
 
+
 Test Persistent with Data Manager
 ---------------------------------
 
-Next try some tests of an object with a data manager.  The DM class is
+Next try some tests of an object with a data manager.  The `DM` class is
 a simple testing stub.
 
->>> p = P()
->>> dm = DM()
->>> p._p_oid = "00000012"
->>> p._p_jar = dm
->>> p._p_changed
-0
->>> dm.called
-0
+  >>> p = P()
+  >>> dm = DM()
+  >>> p._p_oid = "00000012"
+  >>> p._p_jar = dm
+  >>> p._p_changed
+  0
+  >>> dm.called
+  0
 
-Modifying the object marks it as changed and registers it with the
-data manager.  Subsequent modifications don't have additional
-side-effects.
+Modifying the object marks it as changed and registers it with the data
+manager.  Subsequent modifications don't have additional side-effects.
 
->>> p.inc()
->>> p._p_changed
-1
->>> dm.called
-1
->>> p.inc()
->>> p._p_changed
-1
->>> dm.called
-1
+  >>> p.inc()
+  >>> p._p_changed
+  1
+  >>> dm.called
+  1
+  >>> p.inc()
+  >>> p._p_changed
+  1
+  >>> dm.called
+  1
 
 It's not possible to deactivate a modified object.
 
->>> p._p_deactivate()
->>> p._p_changed
-1
+  >>> p._p_deactivate()
+  >>> p._p_changed
+  1
 
-It is possible to invalidate it.  That's the key difference
-between deactivation and invalidation.
+It is possible to invalidate it.  That's the key difference between
+deactivation and invalidation.
 
->>> p._p_invalidate()
->>> p._p_state
--1
+  >>> p._p_invalidate()
+  >>> p._p_state
+  -1
 
-Now that the object is a ghost, any attempt to modify it will
-require that it be unghosted first.  The test data manager
-has the odd property that it sets the object's 'x' attribute
-to 42 when it is unghosted.
+Now that the object is a ghost, any attempt to modify it will require that it
+be unghosted first.  The test data manager has the odd property that it sets
+the object's ``x`` attribute to ``42`` when it is unghosted.
 
->>> p.inc()
->>> p.x
-43
->>> dm.called
-2
+  >>> p.inc()
+  >>> p.x
+  43
+  >>> dm.called
+  2
 
-You can manually reset the changed field to False, although
-it's not clear why you would want to do that.  The object
-changes to the UPTODATE state but retains its modifications.
+You can manually reset the changed field to ``False``, although it's not clear
+why you would want to do that.  The object changes to the ``UPTODATE`` state
+but retains its modifications.
 
->>> p._p_changed = False
->>> p._p_state
-0
->>> p._p_changed
-False
->>> p.x
-43
+  >>> p._p_changed = False
+  >>> p._p_state
+  0
+  >>> p._p_changed
+  False
+  >>> p.x
+  43
 
->>> p.inc()
->>> p._p_changed
-True
->>> dm.called
-3
+  >>> p.inc()
+  >>> p._p_changed
+  True
+  >>> dm.called
+  3
 
-__getstate__() and __setstate__()
----------------------------------
+``__getstate__()`` and ``__setstate__()``
+-----------------------------------------
 
-The next several tests cover the __getstate__() and __setstate__()
+The next several tests cover the ``__getstate__()`` and ``__setstate__()``
 implementations.
 
->>> p = P()
->>> state = p.__getstate__()
->>> isinstance(state, dict)
-True
->>> state['x']
-0
->>> p._p_state
-0
+  >>> p = P()
+  >>> state = p.__getstate__()
+  >>> isinstance(state, dict)
+  True
+  >>> state['x']
+  0
+  >>> p._p_state
+  0
 
 Calling setstate always leaves the object in the uptodate state?
 (I'm not entirely clear on this one.)
 
->>> p.__setstate__({'x': 5})
->>> p._p_state
-0
+  >>> p.__setstate__({'x': 5})
+  >>> p._p_state
+  0
 
 Assigning to a volatile attribute has no effect on the object state.
 
->>> p._v_foo = 2
->>> p.__getstate__()
-{'x': 5}
->>> p._p_state
-0
+  >>> p._v_foo = 2
+  >>> p.__getstate__()
+  {'x': 5}
+  >>> p._p_state
+  0
 
-The _p_serial attribute is not affected by calling setstate.
+The ``_p_serial`` attribute is not affected by calling setstate.
 
->>> p._p_serial = "00000012"
->>> p.__setstate__(p.__getstate__())
->>> p._p_serial
-'00000012'
+  >>> p._p_serial = "00000012"
+  >>> p.__setstate__(p.__getstate__())
+  >>> p._p_serial
+  '00000012'
 
+
 Change Ghost test
 -----------------
 
-If an object is a ghost and its _p_changed is set to True (any true value),
-it should activate (unghostify) the object.  This behavior is new in ZODB
-3.6; before then, an attempt to do "ghost._p_changed = True" was ignored.
+If an object is a ghost and its ``_p_changed`` is set to ``True`` (any true
+value), it should activate (unghostify) the object.  This behavior is new in
+ZODB 3.6; before then, an attempt to do ``ghost._p_changed = True`` was
+ignored.
 
->>> p = P()
->>> p._p_jar = DM()
->>> p._p_oid = 1
->>> p._p_deactivate()
->>> p._p_changed # None
->>> p._p_state # ghost state
--1
->>> p._p_changed = True
->>> p._p_changed
-1
->>> p._p_state # changed state
-1
->>> p.x
-42
+  >>> p = P()
+  >>> p._p_jar = DM()
+  >>> p._p_oid = 1
+  >>> p._p_deactivate()
+  >>> p._p_changed # None
+  >>> p._p_state # ghost state
+  -1
+  >>> p._p_changed = True
+  >>> p._p_changed
+  1
+  >>> p._p_state # changed state
+  1
+  >>> p.x
+  42
 
+
 Activate, deactivate, and invalidate
 ------------------------------------
 
 Some of these tests are redundant, but are included to make sure there
-are explicit and simple tests of _p_activate(), _p_deactivate(), and
-_p_invalidate().
+are explicit and simple tests of ``_p_activate()``, ``_p_deactivate()``, and
+``_p_invalidate()``.
 
->>> p = P()
->>> p._p_oid = 1
->>> p._p_jar = DM()
->>> p._p_deactivate()
->>> p._p_state
--1
->>> p._p_activate()
->>> p._p_state
-0
->>> p.x
-42
->>> p.inc()
->>> p.x
-43
->>> p._p_state
-1
->>> p._p_invalidate()
->>> p._p_state
--1
->>> p.x
-42
+  >>> p = P()
+  >>> p._p_oid = 1
+  >>> p._p_jar = DM()
+  >>> p._p_deactivate()
+  >>> p._p_state
+  -1
+  >>> p._p_activate()
+  >>> p._p_state
+  0
+  >>> p.x
+  42
+  >>> p.inc()
+  >>> p.x
+  43
+  >>> p._p_state
+  1
+  >>> p._p_invalidate()
+  >>> p._p_state
+  -1
+  >>> p.x
+  42
 
+
 Test failures
 -------------
 
 The following tests cover various errors cases.
 
-When an object is modified, it registers with its data manager.  If
-that registration fails, the exception is propagated and the object
-stays in the up-to-date state.  It shouldn't change to the modified
-state, because it won't be saved when the transaction commits.
+When an object is modified, it registers with its data manager.  If that
+registration fails, the exception is propagated and the object stays in the
+up-to-date state.  It shouldn't change to the modified state, because it won't
+be saved when the transaction commits.
 
->>> p = P()
->>> p._p_oid = 1
->>> p._p_jar = BrokenDM()
->>> p._p_state
-0
->>> p._p_jar.called
-0
->>> p._p_changed = 1
-Traceback (most recent call last):
-  ...
-NotImplementedError
->>> p._p_jar.called
-1
->>> p._p_state
-0
+  >>> p = P()
+  >>> p._p_oid = 1
+  >>> p._p_jar = BrokenDM()
+  >>> p._p_state
+  0
+  >>> p._p_jar.called
+  0
+  >>> p._p_changed = 1
+  Traceback (most recent call last):
+    ...
+  NotImplementedError
+  >>> p._p_jar.called
+  1
+  >>> p._p_state
+  0
 
-Make sure that exceptions that occur inside the data manager's
-setstate() method propagate out to the caller.
+Make sure that exceptions that occur inside the data manager's ``setstate()``
+method propagate out to the caller.
 
->>> p = P()
->>> p._p_oid = 1
->>> p._p_jar = BrokenDM()
->>> p._p_deactivate()
->>> p._p_state
--1
->>> p._p_activate()
-Traceback (most recent call last):
-  ...
-NotImplementedError
->>> p._p_state
--1
+  >>> p = P()
+  >>> p._p_oid = 1
+  >>> p._p_jar = BrokenDM()
+  >>> p._p_deactivate()
+  >>> p._p_state
+  -1
+  >>> p._p_activate()
+  Traceback (most recent call last):
+    ...
+  NotImplementedError
+  >>> p._p_state
+  -1
 
 
-Special test to cover layout of __dict__
-----------------------------------------
+Special test to cover layout of ``__dict__``
+--------------------------------------------
 
-We once had a bug in the Persistent class that calculated an incorrect
-offset for the __dict__ attribute.  It assigned __dict__ and _p_jar to
-the same location in memory.  This is a simple test to make sure they
-have different locations.
+We once had a bug in the `Persistent` class that calculated an incorrect
+offset for the ``__dict__`` attribute.  It assigned ``__dict__`` and
+``_p_jar`` to the same location in memory.  This is a simple test to make sure
+they have different locations.
 
->>> p = P()
->>> p.inc()
->>> p.inc()
->>> 'x' in p.__dict__
-True
->>> p._p_jar
+  >>> p = P()
+  >>> p.inc()
+  >>> p.inc()
+  >>> 'x' in p.__dict__
+  True
+  >>> p._p_jar
 
 
 Inheritance and metaclasses
 ---------------------------
 
-Simple tests to make sure it's possible to inherit from the Persistent
-base class multiple times.  There used to be metaclasses involved in
-Persistent that probably made this a more interesting test.
+Simple tests to make sure it's possible to inherit from the `Persistent` base
+class multiple times.  There used to be metaclasses involved in `Persistent`
+that probably made this a more interesting test.
 
->>> class A(Persistent):
-...     pass
->>> class B(Persistent):
-...     pass
->>> class C(A, B):
-...     pass
->>> class D(object):
-...     pass
->>> class E(D, B):
-...     pass
->>> a = A()
->>> b = B()
->>> c = C()
->>> d = D()
->>> e = E()
+  >>> class A(Persistent):
+  ...     pass
+  >>> class B(Persistent):
+  ...     pass
+  >>> class C(A, B):
+  ...     pass
+  >>> class D(object):
+  ...     pass
+  >>> class E(D, B):
+  ...     pass
+  >>> a = A()
+  >>> b = B()
+  >>> c = C()
+  >>> d = D()
+  >>> e = E()
 
-Also make sure that it's possible to define Persistent classes that
-have a custom metaclass.
+Also make sure that it's possible to define `Persistent` classes that have a
+custom metaclass.
 
->>> class alternateMeta(type):
-...     type
->>> class alternate(object):
-...     __metaclass__ = alternateMeta
->>> class mixedMeta(alternateMeta, type):
-...     pass
->>> class mixed(alternate, Persistent):
-...     pass
->>> class mixed(Persistent, alternate):
-...     pass
+  >>> class alternateMeta(type):
+  ...     type
+  >>> class alternate(object):
+  ...     __metaclass__ = alternateMeta
+  >>> class mixedMeta(alternateMeta, type):
+  ...     pass
+  >>> class mixed(alternate, Persistent):
+  ...     pass
+  >>> class mixed(Persistent, alternate):
+  ...     pass
 
 
 Basic type structure
 --------------------
 
->>> Persistent.__dictoffset__
-0
->>> Persistent.__weakrefoffset__
-0
->>> Persistent.__basicsize__ > object.__basicsize__
-True
->>> P.__dictoffset__ > 0
-True
->>> P.__weakrefoffset__ > 0
-True
->>> P.__dictoffset__ < P.__weakrefoffset__
-True
->>> P.__basicsize__ > Persistent.__basicsize__
-True
+  >>> Persistent.__dictoffset__
+  0
+  >>> Persistent.__weakrefoffset__
+  0
+  >>> Persistent.__basicsize__ > object.__basicsize__
+  True
+  >>> P.__dictoffset__ > 0
+  True
+  >>> P.__weakrefoffset__ > 0
+  True
+  >>> P.__dictoffset__ < P.__weakrefoffset__
+  True
+  >>> P.__basicsize__ > Persistent.__basicsize__
+  True
 
 
 Slots
 -----
 
-These are some simple tests of classes that have an __slots__
+These are some simple tests of classes that have an ``__slots__``
 attribute.  Some of the classes should have slots, others shouldn't.
 
->>> class noDict(object):
-...     __slots__ = ['foo']
->>> class p_noDict(Persistent):
-...     __slots__ = ['foo']
->>> class p_shouldHaveDict(p_noDict):
-...     pass
+  >>> class noDict(object):
+  ...     __slots__ = ['foo']
+  >>> class p_noDict(Persistent):
+  ...     __slots__ = ['foo']
+  >>> class p_shouldHaveDict(p_noDict):
+  ...     pass
 
->>> p_noDict.__dictoffset__
-0
->>> x = p_noDict()
->>> x.foo = 1
->>> x.foo
-1
->>> x.bar = 1
-Traceback (most recent call last):
-  ...
-AttributeError: 'p_noDict' object has no attribute 'bar'
->>> x._v_bar = 1
-Traceback (most recent call last):
-  ...
-AttributeError: 'p_noDict' object has no attribute '_v_bar'
->>> x.__dict__
-Traceback (most recent call last):
-  ...
-AttributeError: 'p_noDict' object has no attribute '__dict__'
+  >>> p_noDict.__dictoffset__
+  0
+  >>> x = p_noDict()
+  >>> x.foo = 1
+  >>> x.foo
+  1
+  >>> x.bar = 1
+  Traceback (most recent call last):
+    ...
+  AttributeError: 'p_noDict' object has no attribute 'bar'
+  >>> x._v_bar = 1
+  Traceback (most recent call last):
+    ...
+  AttributeError: 'p_noDict' object has no attribute '_v_bar'
+  >>> x.__dict__
+  Traceback (most recent call last):
+    ...
+  AttributeError: 'p_noDict' object has no attribute '__dict__'
 
-The various _p_ attributes are unaffected by slots.
->>> p._p_oid
->>> p._p_jar
->>> p._p_state
-0
+  The various _p_ attributes are unaffected by slots.
+  >>> p._p_oid
+  >>> p._p_jar
+  >>> p._p_state
+  0
 
 If the most-derived class does not specify
 
->>> p_shouldHaveDict.__dictoffset__ > 0
-True
->>> x = p_shouldHaveDict()
->>> isinstance(x.__dict__, dict)
-True
+  >>> p_shouldHaveDict.__dictoffset__ > 0
+  True
+  >>> x = p_shouldHaveDict()
+  >>> isinstance(x.__dict__, dict)
+  True
 
 
 Pickling
 --------
 
 There's actually a substantial effort involved in making subclasses of
-Persistent work with plain-old pickle.  The ZODB serialization layer
-never calls pickle on an object; it pickles the object's class
-description and its state as two separate pickles.
+`Persistent` work with plain-old pickle.  The ZODB serialization layer never
+calls pickle on an object; it pickles the object's class description and its
+state as two separate pickles.
 
->>> import pickle
->>> p = P()
->>> p.inc()
->>> p2 = pickle.loads(pickle.dumps(p))
->>> p2.__class__ is P
-True
->>> p2.x == p.x
-True
+  >>> import pickle
+  >>> p = P()
+  >>> p.inc()
+  >>> p2 = pickle.loads(pickle.dumps(p))
+  >>> p2.__class__ is P
+  True
+  >>> p2.x == p.x
+  True
 
-We should also test that pickle works with custom getstate and
-setstate.  Perhaps even reduce.  The problem is that pickling depends
-on finding the class in a particular module, and classes defined here
-won't appear in any module.  We could require each user of the tests
-to define a base class, but that might be tedious.
+We should also test that pickle works with custom getstate and setstate.
+Perhaps even reduce.  The problem is that pickling depends on finding the
+class in a particular module, and classes defined here won't appear in any
+module.  We could require each user of the tests to define a base class, but
+that might be tedious.
 
+
 Interfaces
 ----------
 
-Some versions of Zope and ZODB have the zope.interfaces package
-available.  If it is available, then persistent will be associated
-with several interfaces.  It's hard to write a doctest test that runs
-the tests only if zope.interface is available, so this test looks a
-little unusual.  One problem is that the assert statements won't do
-anything if you run with -O.
+Some versions of Zope and ZODB have the `zope.interfaces` package available.
+If it is available, then persistent will be associated with several
+interfaces.  It's hard to write a doctest test that runs the tests only if
+`zope.interface` is available, so this test looks a little unusual.  One
+problem is that the assert statements won't do anything if you run with `-O`.
 
->>> try:
-...     import zope.interface
-... except ImportError:
-...     pass
-... else:
-...     from persistent.interfaces import IPersistent
-...     assert IPersistent.implementedBy(Persistent)
-...     p = Persistent()
-...     assert IPersistent.providedBy(p)
-...     assert IPersistent.implementedBy(P)
-...     p = P()
-...     assert IPersistent.providedBy(p)
+  >>> try:
+  ...     import zope.interface
+  ... except ImportError:
+  ...     pass
+  ... else:
+  ...     from persistent.interfaces import IPersistent
+  ...     assert IPersistent.implementedBy(Persistent)
+  ...     p = Persistent()
+  ...     assert IPersistent.providedBy(p)
+  ...     assert IPersistent.implementedBy(P)
+  ...     p = P()
+  ...     assert IPersistent.providedBy(p)



More information about the Zodb-checkins mailing list