plone / Products.CMFPlone

The core of the Plone content management system
https://plone.org
GNU General Public License v2.0
249 stars 188 forks source link

Circular import for getToolByName patch #1950

Closed mauritsvanrees closed 1 year ago

mauritsvanrees commented 7 years ago

In coredev 5.1 this fails: bin/test -s plone.app.portlets:

  File "/Users/maurits/shared-eggs/cp27m/zope.configuration-3.7.4-py2.7.egg/zope/configuration/config.py", line 179, in resolve
    mod = __import__(mname, *_import_chickens)
  File "/Users/maurits/community/plone-coredev/5.1/src/plone.protect/plone/protect/auto.py", line 50, in <module>
    from plone.app.blob.content import ATBlob
  File "/Users/maurits/community/plone-coredev/5.1/src/plone.app.blob/src/plone/app/blob/content.py", line 10, in <module>
    from plone.app.blob.markings import markAs
  File "/Users/maurits/community/plone-coredev/5.1/src/plone.app.blob/src/plone/app/blob/markings.py", line 8, in <module>
    from Products.ATContentTypes.interface import file as atfile
ZopeXMLConfigurationError: File "/Users/maurits/community/plone-coredev/5.1/src/plonetheme.barceloneta/plonetheme/barceloneta/configure.zcml", line 11.2-11.41
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.theming-1.3.5-py2.7.egg/plone/app/theming/configure.zcml", line 19.4-19.44
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.registry-1.5-py2.7.egg/plone/app/registry/configure.zcml", line 12.4-12.34
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.registry-1.5-py2.7.egg/plone/app/registry/browser/configure.zcml", line 6.4-6.43
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.z3cform-2.2.1-py2.7.egg/plone/app/z3cform/configure.zcml", line 10.2-10.41
    ZopeXMLConfigurationError: File "/Users/maurits/community/plone-coredev/5.1/src/plone.app.widgets/plone/app/widgets/configure.zcml", line 12.2-12.41
    ZopeXMLConfigurationError: File "/Users/maurits/community/plone-coredev/5.1/src/Products.CMFPlone/Products/CMFPlone/configure.zcml", line 15.2-15.46
    ZopeXMLConfigurationError: File "/Users/maurits/community/plone-coredev/5.1/src/plone.app.contenttypes/plone/app/contenttypes/configure.zcml", line 10.2-10.37
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.event-3.0.4-py2.7.egg/plone/app/event/configure.zcml", line 21.2-21.27
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.event-3.0.4-py2.7.egg/plone/app/event/dx/configure.zcml", line 7.4-7.45
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.dexterity-2.4.0-py2.7.egg/plone/app/dexterity/configure.zcml", line 15.2-15.42
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.schemaeditor-2.0.15-py2.7.egg/plone/schemaeditor/configure.zcml", line 8.2-8.36
    ZopeXMLConfigurationError: File "/Users/maurits/community/plone-coredev/5.1/src/plone.protect/plone/protect/configure.zcml", line 33.4-36.10
    ImportError: cannot import name file

This is when plone.app.blob.markings imports from Products.ATContentTypes.interface. What markings.py does, seems strange, and it looks like it expects old Zope2 interfaces in places where there are currently Zope 3 interfaces. That may be a different issue. If I temporarily make markings.py almost empty, leaving only stubs for the two methods in there, then it goes wrong a bit further on.

  File "/Users/maurits/shared-eggs/cp27m/zope.configuration-3.7.4-py2.7.egg/zope/configuration/config.py", line 179, in resolve
    mod = __import__(mname, *_import_chickens)
  File "/Users/maurits/shared-eggs/cp27m/plone.app.collection-1.2.3-py2.7.egg/plone/app/collection/collection.py", line 7, in <module>
    from Products.ATContentTypes.content import document, schemata
ZopeXMLConfigurationError: File "/Users/maurits/community/plone-coredev/5.1/src/plonetheme.barceloneta/plonetheme/barceloneta/configure.zcml", line 11.2-11.41
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.theming-1.3.5-py2.7.egg/plone/app/theming/configure.zcml", line 19.4-19.44
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.registry-1.5-py2.7.egg/plone/app/registry/configure.zcml", line 12.4-12.34
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.registry-1.5-py2.7.egg/plone/app/registry/browser/configure.zcml", line 6.4-6.43
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.z3cform-2.2.1-py2.7.egg/plone/app/z3cform/configure.zcml", line 10.2-10.41
    ZopeXMLConfigurationError: File "/Users/maurits/community/plone-coredev/5.1/src/plone.app.widgets/plone/app/widgets/configure.zcml", line 12.2-12.41
    ZopeXMLConfigurationError: File "/Users/maurits/community/plone-coredev/5.1/src/Products.CMFPlone/Products/CMFPlone/configure.zcml", line 56.2-57.47
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/Products.ATContentTypes-2.3.3-py2.7.egg/Products/ATContentTypes/configure.zcml", line 18.2-18.44
    ZopeXMLConfigurationError: File "/Users/maurits/shared-eggs/cp27m/plone.app.collection-1.2.3-py2.7.egg/plone/app/collection/configure.zcml", line 45.2
    ImportError: cannot import name schemata

When I go in with a pdb, after I while I end up here:

  /Users/maurits/shared-eggs/cp27m/plone.app.portlets-4.2.3-py2.7.egg/plone/app/portlets/tests/test_configuration.py(35)<module>()
-> from plone.app.portlets.utils import assignment_mapping_from_key
  /Users/maurits/shared-eggs/cp27m/plone.app.portlets-4.2.3-py2.7.egg/plone/app/portlets/utils.py(14)<module>()
-> from plone.app.portlets.portlets import news
  /Users/maurits/shared-eggs/cp27m/plone.app.portlets-4.2.3-py2.7.egg/plone/app/portlets/portlets/news.py(7)<module>()
-> from plone.app.z3cform.widget import SelectFieldWidget
  /Users/maurits/shared-eggs/cp27m/plone.app.z3cform-2.2.1-py2.7.egg/plone/app/z3cform/widget.py(4)<module>()
-> from plone.app.textfield.value import RichTextValue
  /Users/maurits/shared-eggs/cp27m/plone.app.textfield-1.2.8-py2.7.egg/plone/app/textfield/__init__.py(4)<module>()
-> from plone.app.textfield.value import RichTextValue
  /Users/maurits/shared-eggs/cp27m/plone.app.textfield-1.2.8-py2.7.egg/plone/app/textfield/value.py(5)<module>()
-> from Products.CMFPlone.utils import safe_unicode
  /Users/maurits/community/plone-coredev/5.1/src/Products.CMFPlone/Products/CMFPlone/__init__.py(229)<module>()
-> from Products.CMFPlone import earlypatches  # noqa
  /Users/maurits/community/plone-coredev/5.1/src/Products.CMFPlone/Products/CMFPlone/earlypatches/__init__.py(2)<module>()
-> import security  # noqa
  /Users/maurits/community/plone-coredev/5.1/src/Products.CMFPlone/Products/CMFPlone/earlypatches/security.py(87)<module>()
-> exec code in utils.getToolByName.func_globals
  <string>(5)<module>()
  /Users/maurits/shared-eggs/cp27m/Products.ATContentTypes-2.3.3-py2.7.egg/Products/ATContentTypes/__init__.py(33)<module>()
-> import Products.ATContentTypes.content  # noqa
  /Users/maurits/shared-eggs/cp27m/Products.ATContentTypes-2.3.3-py2.7.egg/Products/ATContentTypes/content/__init__.py(2)<module>()
-> import Products.ATContentTypes.content.link  # noqa
  /Users/maurits/shared-eggs/cp27m/Products.ATContentTypes-2.3.3-py2.7.egg/Products/ATContentTypes/content/link.py(8)<module>()
-> from Products.ATContentTypes.content.base import ATCTContent
> /Users/maurits/shared-eggs/cp27m/Products.ATContentTypes-2.3.3-py2.7.egg/Products/ATContentTypes/content/base.py(13)<module>()
-> from Products.ATContentTypes.interfaces import IATContentType
  /Users/maurits/shared-eggs/cp27m/Products.ATContentTypes-2.3.3-py2.7.egg/Products/ATContentTypes/interfaces/__init__.py(25)<module>()
-> from Products.ATContentTypes.interfaces.factories import IATCTFileFactory  # noqa
  /Users/maurits/shared-eggs/cp27m/Products.ATContentTypes-2.3.3-py2.7.egg/Products/ATContentTypes/interfaces/factories.py(2)<module>()
-> from plone.app.widgets.interfaces import IFileFactory
  /Users/maurits/community/plone-coredev/5.1/src/plone.app.widgets/plone/app/widgets/interfaces.py(2)<module>()
-> from plone.app.z3cform.interfaces import IPloneFormLayer
  /Users/maurits/shared-eggs/cp27m/plone.app.z3cform-2.2.1-py2.7.egg/plone/app/z3cform/interfaces.py(2)<module>()
-> from plone.app.textfield.widget import IRichTextWidget as patextfield_IRichTextWidget  # noqa
  /Users/maurits/shared-eggs/cp27m/plone.app.textfield-1.2.8-py2.7.egg/plone/app/textfield/widget.py(6)<module>()
-> from plone.app.textfield.value import RichTextValue

Near the beginning and at the end there is this line:

from plone.app.textfield.value import RichTextValue

This means there is a circular import, which leads to an import error.

My eye fell on the line with the earlypatches module and exec code in utils.getToolByName.func_globals, which imports from ATContentTypes, which might be a hint of danger, given the failure I found earlier.. This used to be in the patches module, but a while ago I had to move it to be loaded earlier.

I don't think the getToolByName security code really needs to be loaded this early. When I move that part back to the late patches, I can successfully run the plone.app.portlets tests again. I then can also undo my temporary change in plone.app.blob.markings.

I will make a pull request.

mauritsvanrees commented 7 years ago

@davisagli This might be related to the plone.app.discussion robot test problem. It could also be something totally different.

thet commented 7 years ago

IIRC, I ran into this problem too... I didn't dig this deep and didn't identify the getToolByName being the cause of that, but I started to correct old and deprecated imports. Now, I've created some PRs for that:

https://github.com/plone/Products.ATContentTypes/pull/42

... currently testing ...

Only, these fixes didn't solve the problem :/

jensens commented 1 year ago

I close the issue, because it addresses a Plone version that is no longer supported. If you think this is wrong please reopen the issue and assign a matching milestone.

mauritsvanrees commented 1 year ago

I tried for good measure in Plone 5.2 Py 2.7, and bin/test -s plone.app.portlets passes just fine. Solved.