[Zope-dev] Ordering of fields with schema interface subclassing

Martin Aspeli optilude at gmx.net
Sun Jul 20 13:22:41 EDT 2008


Hi,

Suppose I have an interface IDerived that's derived from an interface 
IBase, overriding a field from it.

 >>> from zope.interface import Interface
 >>> from zope.schema import TextLine

 >>> class IBase(Interface):
...     a = TextLine(title=u"a")
...     b = TextLine(title=u"b")
...     c = TextLine(title=u"c")

 >>> class IDerived(IBase):
...     b = TextLine(title=u"b", default=u"B")

In this case, the field ordering of zope.schema means that I'll get 
something like this:

 >>> from zope.schema import getFieldNamesInOrder
 >>> getFieldNamesInOrder(IDerived)
['a', 'c', 'b']

I had rather expected the order to be ['a', 'b', 'c']. That is, I would 
expect a field that overrides a field from a base interface, to retain 
the base interface's order.

One way to fix this is to do:

 >>> IDerived['b'].order = IBase['b'].order

Now both will have the same order, of course.

So, I'm wondering:

  - Is it harmful to have two fields with the same order like this when 
they share a name?

  - Should this be the default behavior when deriving interfaces from 
one another like this?

If the latter is desirable, I'd be willing to help find a way to 
implement it. The field order is just an ever-increasing int that's set 
in Field.__init__(), so we'd probably need some after-the-fact fixing up 
of fields.

One way to do that would be to fire an event at the end of 
InterfaceClass.__init__() and have an event handler to fix the order, 
though that'd make zope.interface dependent on zope.event which is 
probably not desirable.

We could simulate the event handler in another way, of course, e.g. by 
having the interface initialiser loop over its attributes and see if 
they support e.g. an IOrderAware interface and call a method on it, and 
have Field implement this.

What do you think?
Martin



More information about the Zope-Dev mailing list