On 8/23/06, Stephan Richter <[EMAIL PROTECTED]> wrote:
Hi everyone,
today I found a nice brain teaser. What is the outcome of the following:
>>> from zope.interface import Interface
>>> from zope.schema import TextLine
>>> class IFoo(Interface):
... title = TextLine()
...
>>> class IBar(IFoo):
... pass
...
>>> IBar['title']
>>> IBar['title'].interface
???
I now know this answer since I came across this a while ago: IFoo!
Someone mentioned classes. This is not much different than this simple
situation:
>>> class Foo(object):
... title = 'bar'
>>> class Bar(Foo):
... pass
>>> Bar.title
'bar'
>>> 'title' in Bar.__dict__
False
>>> 'title' in Foo.__dict__
True
If you ask the zope.interface.interfaces.IAttribute documentation you get:
interface = Attribute('interface',
'Stores the interface instance in which the '
'attribute is located.')
In plain English:
If you ask zope.formlib (form.py, line 227)::
# Adapt context, if necessary
interface = field.interface
...
adapter = interface(context)
Here the answer would be:
Could you clarify 'would be'? Do you mean 'the answer that I often
find myself wanting' or 'the answer IS'?
If the anser IS ...IBar, it's wrong. Unless something has changed
since Zope 3.2.
Actually, what exactly are you asking here? Is the question `what is
the interface that should be provided by ``adapter``? Or is the
question `what is the value of `interface`?
>>> class Bar(object):
... implements(IBar)
... title = u""
>>> bar = Bar()
>>> IBar['title'].interface
>>> IBar['title'].interface(bar)
<__main__.Bar object at 0x2907630>
Isn't that what formlib is doing? How is this wrong?
Either way you look at it, one package is wrong and thus broken.
I'm not sure if anything is wrong and broken, besides concepts,
clarity, and terminology.
Personally, I would really love a way to re-combine Interface Fields.
I like how formlib.FormFields can be composed from many sources, or
from a single source selectively, and I wanted this at the Interface
specification level.
I ran into this situation a couple of months ago when an
object-creation situation was getting very complex. The rules that
governed the main interface fields were ones that I wanted to reuse,
but selectively. I wanted to have this creation schema in its own
interface spec, since it was going to be combined (in theory) with
others. I basically wanted a Memo object that was very similar to this
complex set of objects I had to build, which could be passed around as
a single entity in comparison to having to add more and more arguments
(parameters?) to a Factory object every time we added something new to
the system. As the Memo was starting to build on other parts of the
system, it was becoming very hard to maintain and also to visualize.
We'd either have to copy and paste a lot of Interface specification
parts manually and maintain both, or look at some other options.
I ended up writing an interface cloner tool that would make a new
InterfaceClass dynamically, composing it of attributes selectively
copied out of other Interfaces. Then the 'interface' attribute could
be set on the copied Attribute without affecting the original.
>>> import icopy
>>> IBaz = icopy.iclone('IBaz', IBar)
>>> IBaz
>>> IBaz['title']
>>> IBaz['title'].interface
>>> IBaz['title'].interface(bar)
Traceback (most recent call last):
...
TypeError: ('Could not adapt', <__main__.Bar object at 0x2907630>,
)
Without copying, you end up with this scenario::
>>> class IBadBar(IFoo):
... title = IFoo['title']
>>> IBadBar['title'].interface
>>> IFoo['title'].interface
Whoops!
The copy tools also let you omit certain names, select certain names, combine
multiple interfaces, and so on. The problem was that - particularly
for this add form - I wanted to bring in bits of schema from other
interfaces
While I still have these tools around, I ultimately abandoned that
path after a day or two of work. Eventually we just manually built up
the FormField using the bits and pieces that we wanted.
But which is it? It turns out that zope.interface wins and IFoo is returned.
This really hurts zope.formlib. After an initial discussion on IRC, more
people expected IBar, since it is more in line with im_class, but there were
also people expecting IFoo.
How exactly does this hurt formlib?
I must say, the scenarios in `formlib` for how values get bound to
their fields is pretty confusing, between all of the different
`setUp...Widgets` scenarios and the adaptation. I got mad as hell
recently because I had a nearly impossible time getting today's date
to render for an edit-field situation ('get_rendered' couldn't be used
at that point). This was for a formlib based search form that kept the
criteria stored in the session. Fortunately, I had writt