circular import references from zope schemas

好久不见. 提交于 2019-12-02 06:26:36

You're calling getBarChoices() at definition time, when defining the class IFoo. So from bar import IBar will be executed while parsing foo.py leading to the circular import.

As far as I see it, you have basically two choices:

1) Use a string as identifier for object_provides.

You're doing that already anyway by using IFoo.__identifier__, but if you make it static instead of dynamic that will eliminate your circular dependencies:

source = ObjPathSourceBinder(object_provides='ns.content.bar.IBar')
bar = Relation(source=source,required=False)

No need to import IBar in foo.py. This has the obvious disadvantage that the location of IBar is now hardcoded in your code, so whenever you change the name or location of IBar you'll need to update its dotted name in foo.py.

2) Marker interfaces

The other alternative would be to let IFoo and IBar implement marker interfaces that you keep in a third file, ns/content/interfaces.py for example. That way you could do something along the lines of

interfaces.py

from zope.interface import Interface

class IBarMarker(Interface):
    """Marker interface for IBar objects.
    """

class IFooMarker(Interface):
    """Marker interface for IFoo objects.
    """

foo.py

from zope.interface import directlyProvides
from plone.directives import form
from plone.formwidget.contenttree import ObjPathSourceBinder
from plone.formwidget.autocomplete import AutocompleteFieldWidget
from z3c.relationfield.schema import RelationChoice

from ns.content.interfaces import IBarMarker
from ns.content.interfaces import IFooMarker


class IFoo(form.Schema):
    directlyProvides(IFooMarker)

    form.widget(bar=AutocompleteFieldWidget)
    bar = RelationChoice(source=ObjPathSourceBinder(
                            object_provides=IBarMarker.__identifier__),
                         required=False)

bar.py

class IBar(form.Schema):
    directlyProvides(IBarMarker)

    form.widget(foo=AutocompleteFieldWidget)
    foo = RelationChoice(source=ObjPathSourceBinder(
                            object_provides=IFooMarker.__identifier__),
                         required=False)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!