[ZODB-Dev] Persistent object has empty __dict__ for a little while

Martin Aspeli optilude+lists at gmail.com
Wed Jan 6 10:40:14 EST 2010


Hi,

This one is pretty high no the list of weirdest things to have happened 
to me in a while. Basically, I have a persistent object that has an 
empty __dict__() on the first request, until it suddenly decides to have 
data again.

I'm on ZODB 3.9.3, using Zope 2.12 and Plone 4. I have a persistent 
object, /plone/portal_registry:

   class Registry(registry.Registry, SimpleItem):
       pass

The base class is:

   class Registry(Persistent):
       def __init__(self):
           self._records = Records(self)

Records is:

     class Records(Persistent):

       __parent__ = None

       def __init__(self, parent):
           self.__parent__ = parent
           self.data = OOBTree()

       def __getitem__(self, name):
           return self.data.__getitem__(name)

The BTree contains string keys and Record objects as values. Record is:

     class Record(Persistent):
         __name__ = u""
         __parent__ = None

         field = None

__parent__ is set to records.__parent__, which is going to be the 
Registry object.

field is set to a special persistent field class inheriting from 
zope.schema's fields, but mixing in persistence. In this case, I have a 
list field:

   class PersistentField(persistent.Persistent):
       """Base class for persistent field definitions.
       """

   class PersistentCollectionField(PersistentField,
              zope.schema._field.AbstractCollection):

   class List(PersistentCollectionField, zope.schema.List):
       pass

I then have some code like this:

     def cloneField(self, field):
         clone = field.__class__.__new__(field.__class__)
         clone.__dict__.update(field.__dict__)
         for name, attr in field.__dict__.items():
             if IField.providedBy(attr):
                 clone.__dict__[name] = self.cloneField(attr)
         return clone

This is used like so:

     registry = getUtility(IRegistry) # persistent/local
     clone = self.cloneField(registry.records[recordName].field)

This seems to work always *except* on the first request immediately 
after starting up Zope. In this case, field.__dict__ is {}. If I poke at 
it long enough in pdb, it suddenly springs into life and contains values 
again.

Can anyone enlighten me as to:

  - why this may happen
  - how I can ensure it stops happening :-)

Martin


-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book



More information about the ZODB-Dev mailing list