Re: [ZODB-Dev] Persistent object has empty __dict__ for a little while
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Martin Aspeli wrote: 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 :-) You have a ghost, likely: try getting it to unghostify by accessing an attribute, or calling '_p_activate' (accessing '__dict__' doesn't provoke the auto-activation). Tres. - -- === Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software Excellence by Designhttp://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.9 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAktE7UUACgkQ+gerLs4ltQ68YwCeOywUw4a/c7UXap6uxyIzMCx7 9VcAoII4X56V7LConhNSYCWvFMWMooBD =XvFD -END PGP SIGNATURE- ___ For more information about ZODB, see the ZODB Wiki: http://www.zope.org/Wikis/ZODB/ ZODB-Dev mailing list - ZODB-Dev@zope.org https://mail.zope.org/mailman/listinfo/zodb-dev
Re: [ZODB-Dev] Persistent object has empty __dict__ for a little while
On Wed, Jan 6, 2010 at 10:40 AM, Martin Aspeli optilude+li...@gmail.com wrote: 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 :-) __dict__ is a special variable. Accessing it doesn't cause an object to be activated. Rather than doing: clone.__dict__.update(field.__dict__) I would do: clone.__setstate__(field.__getstate__) Alternatively, you can assure that field is acticated first, using _p_activate or by accessing an attribute. Jim -- Jim Fulton ___ For more information about ZODB, see the ZODB Wiki: http://www.zope.org/Wikis/ZODB/ ZODB-Dev mailing list - ZODB-Dev@zope.org https://mail.zope.org/mailman/listinfo/zodb-dev