[Zope3-dev] Interface declaration API

Jim Fulton jim@zope.com
Tue, 11 Mar 2003 14:46:31 -0500


Phillip J. Eby wrote:
> At 01:00 PM 3/10/03 -0500, Jim Fulton wrote:
> 
>> I'd be interested in how prople feel about one of these vs the other.
> 
> 
> You probably already know how I feel about the spelling.  :)
> 
> I have a minor question about semantics, though.  In the docs for the 
> querying functions, it appears that a new declaration is created if none 
> exists, yet it also says in the Wiki proposal that (in effect) a 
> declaration is inherited if none exists.  What happens if you query the 
> declaration for a class (implementedBy/classInstancesInterfaces) which 
> has no declaration?  Do you get a declaration that is a copy of the 
> inherited one?

That's a great question. I'd say you've found a hole in the spec, or,
at least in my understanding of the spec.  It's related to the issue
you raise below.

I guess the right answer is to get a copy of the inherited one.

> I'm also curious whether the default interface spec for a class' 
> instances should perhaps be the union of the interfaces specified by 
> __bases__, rather than flat inheritance in __mro__-first order.  It 
> seems to me that it would best serve the common case for multiple 
> inheritance, and be closest to what I believe is the view Guido has 
> expressed in the past regarding what would be "Pythonic" for inheritance 
> of interface specifications.

There are several choices:

A. Don't inherit anything

B. Inherit the first set of declarations you find, if any

C. Inherit everything

D. Inherit what you say

Currently, we implicitly do B because:

- It's a compromise betwee A and C, and

- It's the easiest to implement.

My preference (ignoring implementation issues) would be to inherit
nothing implicitly and to make it relatively easy to say you inherit
everything.

Most people would prefer to inherit everything by default.
I've had to discuss this so many times that I'm getting worn down. :)

Subclassing is done to reuse implementation. If interfaces were
inherited, then you would be unable to subclass a class without
also promising to implement the base class interfaces.  I've always
viewed this as an undesireable requirement, but maybe I'm wrong,
since so many people desire it, ;) So I'm willing to give on this.

> I'm also curious whether it might be acceptable to have 
> 'alsoImplements()' and 'doesNotImplement()' functions that could be used 
> in a class body to add to or subtract from the inherited declarations.

Yes, alsoImplements might be useful. I'll call YAGNI on doesNotImplement.


Soooooooo ....

Let's suppose we decided that in:

   class C(A, B):

      alsoImplements(IFoo)

The outcome would be that C's instances would implement
IFoo and whatever A's and B's instances implement.

This is implementable, but with a hack. The hack is that the
descriptor needs to update itself the first time that it's used. :(

In::


   class C(A, B):

      pass

The outcome would be that C's instances would implement
whatever A's and B's instances implement.

This too requires a pretty heavy hack.  The first time you tried to
get the instance interface spec for a C, you'd inherit a spec from
A or B. The inherited descriptor would detect that it was inherited
and create a new descriptor for C, merging the interfaces from A and
B.

Finally, with:

   class C(A, B):

      implements(IFoo)

The outcome would be that C's instances would implement
only IFoo.



> It might be nice if in Python 2.4 we could use these things like this:
> 
> class Foo(Bar,Baz) [alsoImplements(ISpam)]:
>     ...

Maybe.

> But all of this is just idle vaporware and should not be construed as a 
> reason to hold up the current proposal, which is fine by me.  :)

Great.

Jim

-- 
Jim Fulton           mailto:jim@zope.com       Python Powered!
CTO                  (888) 344-4332            http://www.python.org
Zope Corporation     http://www.zope.com       http://www.zope.org