[Zope-dev] Re: [Z3d] 747/ 2 Comment "zope.app.interface
PersistentInterfaceClass dependents broken"
me at rpatterson.net
Fri Jan 12 17:16:37 EST 2007
I've submitted a patch for zope.app.interface.PersistentInterfaceClass
and it looks like I could use the approach of zodbcode ModuleManagers
and zope.app.interface.PersistentInterfaceClass instances for what I
Over the course of this work, however, I noticed
ZODB.persistentclass.PersistentMetaClass. Does anyone have any sense
of how one might decide to use persistent modules versus
PersistentMetaClass? Which cases are appropriate for which approach?
Is either body of code more of less active/up-to-date/well-maintained
than the other?
My specific case is that I want to allow site administrators to create
new marker interfaces to be used to mark content and to register
"Collector: Zope 3 ..." <jim at zope.com> writes:
> Issue #747 Update (Comment) "zope.app.interface PersistentInterfaceClass dependents broken"
> Status Pending, core/bug+solution medium
> To followup, visit:
> = Comment - Entry #2 by rossp on Jan 12, 2007 4:46 pm
> Uploaded: "persistent-interfaces-fix.diff"
> - http://www.zope.org/Collectors/Zope3-dev/747/persistent-interfaces-fix.diff/view
> a fix for all but the zope.interface.interface.InterfaceClass provides declaration weak reference bug
> = Request - Entry #1 by rossp on Jan 12, 2007 4:44 pm
> Uploaded: "persistent-interfaces-tests.diff"
> - http://www.zope.org/Collectors/Zope3-dev/747/persistent-interfaces-tests.diff/view
> zope.app.interface.PersistentInterfaceClass uses a PersistentDict for
> the dependents attribute instead of the WeakKeyDictionary used in
> zope.interface.interface.InterfaceClass. There are a number of bugs
> associated with this approach not exposed in any tests. Attached is a
> diff to the tests of zope.app.interface and zope.app.component to
> expose these bugs.
> Firstly, if IFoo is a zope.app.interface.PersistentInterfaceClass
> instance and zope.interface.directlyProvides(foo, IFoo), the
> declaraion can't be verified from a different ZODB connection with
> IFoo.providedBy(foo) due to the following. When the ZODB is trying to
> unpickle the dependents attribute of IFoo, it procedes down the
> serialization of IFoo to the ProvidesClass instance representing the
> declaration. It begins reconstituting the ProvidesClass instance,
> which calls IFoo.subscribe(provides) which accesses the dependents
> attribute of IFoo. Since the ProvidesClass instance isn't persistent,
> it has no oid the ZODB circular reference check doesn't catch this
> circle. As a result the fix is to make sure that the declarations
> instances in the dependents attribute are themselves persistent.
> Also attached is a diff to zope.app.interface that replaces
> PersistentInterfaceClass.dependents with a custom dict that converts
> non-persistent declarations being added to the dependents attribute
> into persistent versions of the same.
> This fixes the problem but is not optimal because there are then two
> instances for the same declaration, one in the ProvidesClass instance
> stored in the object's __provides__ attribute and the other in the
> dependents attribute of the PersistentInterfaceClass.
> It seems like the more appropriate solution would be to check for
> PersistentInterfaceClass instances in
> zope.interface.declarations.directlyProvides and use the persistent
> declaration classes for those declaraions. Since
> PersistentInterfaceClass is in zope.app.interface and zope.interface,
> I wasn't sure which was the lesser of the two evils, so I restrained
> my changes to zope.app. What might be a better solution? Give me
> some feedback and I'll change the implementation.
> There's another problem with the
> zope.app.interface.PersistentInterfaceClass.dependents attribute.
> zope.interface.InterfaceClass.dependents is a WeakKeyDictionary so
> that declarations don't keep objects from being freed if the object is
> removed. By using a PersistentDict for dependents, the declarations
> can keep an object from being freed from memory and/or the ZODB when
> the object is removed.
> My first patch also includes tests for this bug. These tests seem to
> have exposed another unrelated bug. An instance of a class that
> subclasses persistent.Persistent is declared that it
> zope.interface.directlyProvides a zope.interface.InterfaceClass
> instance and then the persistent object is added to the ZODB and
> committed. Then if the persistent instance is deleted from the ZODB,
> the transaction is committed, and the ZODB is packed, and gc.collect
> is run, the ProvidesClass instance in the InterfaceClass instance
> still remains. It does not, however, remain if the persistent
> interface was never added to the ZODB.
> I'm not sure if this represents a potential memory leak or not. What
> confuses me is that it all behaves properly unless the persistent
> instance is added to the ZODB. I noted the comment about weak
> referrences being added to the ZODB optomistically in ZODB.serialize.
> Could that be it? Unfortunately, my second patch doesn't include a
> fix for this. I'd be happy to investigate this further if given a
> little direction.
More information about the Zope-Dev