[Zope-dev] Interfaces in Zope 2.5, 2.7, and 3.x

Terry Hancock hancock at anansispaceworks.com
Thu Feb 26 11:33:00 EST 2004


I have a product that uses a component/interface model
internally.  I wrote this against the "scarecrow" Interface 
module in Zope 2.5.1.

However that module has limitations.  One particular one is
what I call a "SubInterface" -- which is a special case of 
Interface.Attribute (a subclass of it) that asserts that an
object contained within a parent interface implements a
particular interface.

So, for example, a SubInterface might say that in order to
conform to interface "foo", the attribute "bar" must point to
an object which implements "Mapping" (e.g. a dictionary --
it doesn't have to *be* a dictionary, but it must act like one).

Anyway, I wrote my own interface module to do this,
extending the Interface module in Zope 2.5.1 (which lacks
this feature).  All of my code actually imports interface support
from my module instead of directly from Interface.

For unrelated reasons, though, I had to upgrade to Zope 2.7
(and someday, I imagine I'll want to consider moving to Zope 3.x).

My first attempt with Zope 2.7, though yields total breakage!

The Interface module has been extensively overhauled, method
names changed, etc. After giving up on "just fixing a few name-
changes", which seems to be woefully inadequate, I decided to
try to lift the old Interface module -- but now Zope reads the 
"__implements__" attribute and isn't happy if it isn't one of its own
interface objects!

"""
Installing Narya ... Traceback (most recent call last):
  File "./testNaryaInterface.py", line 11, in ?
    ZopeTestCase.installProduct('Narya')
  File "/usr/local/narya/z2.7.0/lib/python/Testing/ZopeTestCase/ZopeLite.py", line 119, in installProduct
    get_folder_permissions(), raise_exc=1)
  File "/usr/local/narya/z2.7.0/lib/python/OFS/Application.py", line 732, in install_product
    initmethod(context)
  File "/usr/local/narya/zope/Products/Narya/__init__.py", line 25, in initialize
    icon='www/Icon/Thread.gif')
  File "/usr/local/narya/z2.7.0/lib/python/App/ProductContext.py", line 176, in registerClass
    interfaces = instancesOfObjectImplements(instance_class)
  File "/usr/local/narya/z2.7.0/lib/python/Interface/Implements.py", line 120, in instancesOfObjectImplements
    visitImplements(implements, klass, r.append, getInterface)
  File "/usr/local/narya/z2.7.0/lib/python/Interface/Implements.py", line 90, in visitImplements
    raise Exceptions.BadImplements(
Interface.Exceptions.BadImplements: __implements__ should be an interface or tuple,
                not a instance pretending to be a Interface
"""
(Seems I'm a pretender ;-) ).

Now, I can implement a new module based on the Zope 2.7 Interface -- but
a close look at that seems to show that it, too, is rather experimental (lots of
stubs, not-yet-implemented attributes, etc).  So I'm also sort of interested in
the "interface" module in Zope X3.

It appears that some new bells and whistles have been added to the
Interface module (e.g. what's a "superinterface"?).   Any chance, I'm
wondering if "SubInterface" is now redundant?

Also, is there a general guide to "best practice" of using / learning the
Interface module?  I note there are now interfaces defined for the interface
module (cool!), and it looks like some self-documentation has been
implemented.

The biggest problem (and this seems to be the usual problem with
"self-documenting" tools) is that there doesn't seem to be a "start here"
defined anywhere.  So you wind up starting somewhere in the middle and
wasting a lot of time trying to decipher the big picture from lots of details,
which is backwards. It'd be nicer if there was a "README" to get you started
on this, maybe define some jargon, etc.  It's really hard to infer what the
overall design concept is by only looking at these details -- in particular,
I want to know what was conceptually changed from the older Interface
module in 2.5.1.

This seems to also be a problem with combining Zope 3 and Zope 2
interfaces, as was suggested by a post on the Zope3 mailing list:

http://mail.zope.org/pipermail/zope3-dev/2003-December/009023.html
(and following -- note that "__interfaces__" should read "__implements__"
in the original post).

Martijn's suggestion was to use an alternate name for the "__implements__"
attribute.  I suppost I could do that -- call mine "__narya_interfaces__", but
that sounds ugly.  In particular, I don't really want my interfaces module
to actually *conflict* with Zope's.

I also note that the post from the Zope3 list suggests that I shouldn't
really be directly assigning "__implements__", but using something called
"implements()".  Hmm. That's different too -- is there any good starting
place for understanding Zope3's "interface" module?

And how different are the Zope 2.7 / Zope X3 interface modules?  If I
re-write my module to conform to Zope 2.7, will I just have to do it
again?

Could I instead leap ahead and use the Zope X3 interface module in
Zope 2.7?

Also, since I'm posting to Zope3-dev as well -- what do you think of the
SubInterface concept?  Should I be contributing code directly to Zope X3's
interface instead of subclassing it?

All it requires is something like:

"""
class SubInterface(Attribute):
    """
    A SubInterface is an Attribute with an assigned Interface.
    """
    def __init__(self, __name__=None, __doc__=None, api=None, optional=0):
        self.__name__=__name__
        self.__doc__=__doc__ or __name__
	self.api = api
	self.optional = optional
"""

Which is what my module defines -- the trickier bit is defining a function to
recursively check SubInterfaces.  That's included too, but it breaks due to
major API changes in Interface.

Cheers,
Terry


--
Terry Hancock ( hancock at anansispaceworks.com )
Anansi Spaceworks  http://www.anansispaceworks.com



More information about the Zope-Dev mailing list