plone/Products.CMFPlone#3829 describes a case where the adapter factory lookup cache of zope.interface grows without limit causing severe memory problems.
I found the cause: plone.dexterity uses Implements (instead of Provides) in its implementation of the providedBy logic. While Provides supports efficient caching, Implements does not as demonstrated by
>>> from zope.interface import Interface
>>> from zope.interface.declarations import Implements, Provides
>>> class I(Interface): pass
...
>>> I1 = Implements(I); I2 = Implements(I)
>>> P1 = Provides(I); P2 = Provides(I)
>>> I1 == I2
False
>>> P1 == P2
True
Provides achieves this by caching its calls (in a WeakValueDict); Implements does not use such a cache.
While I think that plone.dexterity uses the wrong declaration type (Implements instead of Provides), I believe that Implements should cache its calls like Provides does to improve its caching support.
plone/Products.CMFPlone#3829 describes a case where the adapter factory lookup cache of
zope.interfacegrows without limit causing severe memory problems.I found the cause:
plone.dexterityusesImplements(instead ofProvides) in its implementation of theprovidedBylogic. WhileProvidessupports efficient caching,Implementsdoes not as demonstrated byProvidesachieves this by caching its calls (in aWeakValueDict);Implementsdoes not use such a cache.While I think that
plone.dexterityuses the wrong declaration type (Implementsinstead ofProvides), I believe thatImplementsshould cache its calls likeProvidesdoes to improve its caching support.