Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Zope: Dev

Ordering of fields with schema interface subclassing

 

 

Zope dev RSS feed   Index | Next | Previous | View Threaded


optilude at gmx

Jul 20, 2008, 10:22 AM

Post #1 of 3 (284 views)
Permalink
Ordering of fields with schema interface subclassing

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

_______________________________________________
Zope-Dev maillist - Zope-Dev[at]zope.org
http://mail.zope.org/mailman/listinfo/zope-dev
** No cross posts or HTML encoding! **
(Related lists -
http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )


ct at gocept

Jul 22, 2008, 12:37 AM

Post #2 of 3 (258 views)
Permalink
Re: Ordering of fields with schema interface subclassing [In reply to]

On Sun, 2008-07-20 at 18:22 +0100, Martin Aspeli wrote:
> 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?

"Sharing" a name sounds weird. The attribute get's overriden and the
field from the base class isn't considered anymore.

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

I'm not sure about that. IIRC the general issue here is that there's a
*global* counter involved when determining the order of fields.

> 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.

Ah. Sounds like my memories are right.

> 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.

Another way to to that would be to derive the `order` attribute of a
using the MRO (is that the mechanism relevant here?) of the class it
belongs to find inheritance ancestors and use their `order` attribute
instead. That behaviour could also easily be controlled using a flag of
the field.

Christian

--
Christian Theune · ct[at]gocept.com
gocept gmbh & co. kg · forsterstraße 29 · 06112 halle (saale) · germany
http://gocept.com · tel +49 345 1229889 7 · fax +49 345 1229889 1
Zope and Plone consulting and development
Attachments: signature.asc (0.18 KB)


optilude at gmx

Jul 22, 2008, 1:45 PM

Post #3 of 3 (254 views)
Permalink
Re: Ordering of fields with schema interface subclassing [In reply to]

Hi Christian,


>> So, I'm wondering:
>>
>> - Is it harmful to have two fields with the same order like this when
>> they share a name?
>
> "Sharing" a name sounds weird. The attribute get's overriden and the
> field from the base class isn't considered anymore.

Right, that's what I meant. Except that if you access IBase['b'].order
it will be equal to IDerived['b'].order, though I don't think this is
necessarily a problem.

>> - Should this be the default behavior when deriving interfaces from
>> one another like this?
>
> I'm not sure about that. IIRC the general issue here is that there's a
> *global* counter involved when determining the order of fields.

Right, but I think the end result is counter-intuitive in the case I'm
describing. I don't know if the global (non-thread-safe) was just the
easiest implementation or a deliberate choice.

>> 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.
>
> Another way to to that would be to derive the `order` attribute of a
> using the MRO (is that the mechanism relevant here?) of the class it
> belongs to find inheritance ancestors and use their `order` attribute
> instead. That behaviour could also easily be controlled using a flag of
> the field.

Yes, this could be an option. So, 'order' becomes a property and looks
up (any maybe caches) the order from its base interfaces - loop through
base interface in MRO, look for field with same name, if so, return its
'raw' order, otherwise, return self's 'raw' order.

I'd be willing to implement this (if I can find the time) if people
agree that it's a good idea.

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

_______________________________________________
Zope-Dev maillist - Zope-Dev[at]zope.org
http://mail.zope.org/mailman/listinfo/zope-dev
** No cross posts or HTML encoding! **
(Related lists -
http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )

Zope dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact lists@gossamer-threads.com
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.