Lineage recursion error

This is for whoever tried lineage on Plone5.2 + Python3.7 and ran into a recursion error.

We have a patch that makes the site usable:


but it is rather a quick fix than a solution.

To give you the context, I will go into technical details.
Using the collective.lineage Python 3 branch: https://github.com/collective/collective.lineage/pull/54/files

A recursion error like this happens:

...
  File "/srv/plone-dev/buildout.coredev/eggs/zope.component-4.5-py3.6.egg/zope/component/_api.py", line 157 in queryUtility
  File "/srv/plone-dev/buildout.coredev/eggs/plone.dexterity-2.7.0-py3.6.egg/plone/dexterity/schema.py", line 58 in decorator
  File "/srv/plone-dev/buildout.coredev/eggs/plone.synchronize-1.0.3-py3.6.egg/plone/synchronize/decorator.py", line 9 in synchronized_function
  File "/srv/plone-dev/buildout.coredev/eggs/plone.dexterity-2.7.0-py3.6.egg/plone/dexterity/content.py", line 119 in __get__
  File "/srv/plone-dev/buildout.coredev/eggs/five.localsitemanager-3.2.2-py3.6.egg/five/localsitemanager/utils.py", line 15 in get_parent
  File "/srv/plone-dev/buildout.coredev/eggs/five.localsitemanager-3.2.2-py3.6.egg/five/localsitemanager/registry.py", line 114 in _recurse_to_site
  File "/srv/plone-dev/buildout.coredev/eggs/five.localsitemanager-3.2.2-py3.6.egg/five/localsitemanager/registry.py", line 159 in _wrap
  File "/srv/plone-dev/buildout.coredev/eggs/five.localsitemanager-3.2.2-py3.6.egg/five/localsitemanager/registry.py", line 60 in _uncached_lookup
  File "/srv/plone-dev/buildout.coredev/eggs/zope.interface-4.6.0-py3.6-linux-x86_64.egg/zope/interface/registry.py", line 281 in queryUtility
  File "/srv/plone-dev/buildout.coredev/eggs/zope.component-4.5-py3.6.egg/zope/component/_api.py", line 157 in queryUtility
...

The issue is that whenever we get a utility in the lineage site, five.localsitemanager wants wo wrap with a proper parent.
To do that it checks is the current context is providing an interface.
This triggers the code that gets the interface of the current context instance including the one of the behaviors:

To do that it gets the FTI as an utility (which is used as a cache key), restarting the wrapping process and leading to a recursion error.

I do not see a trivial way to solve this.
Theoretically the recursion should be prevented by five.localsitemanager, which is a Zopefoundation package and it should stay agnostic from Plone, but this seems very complex to do.

We might want to change the cache key in plone.dexterity to not use the FTI but a tuple containing the (getSite(), portal_type). This will avoid the need to look for the FTI utility.

Or we could keep the same key but could cache the cache key on the request.

Opinions?

2 Likes

Plone Foundation Code of Conduct