zope.interface
zope.interface copied to clipboard
`Implements` should cache its calls (like `Provides` does)
https://github.com/plone/Products.CMFPlone/issues/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.