[Python-Dev] Re: *very* revised proposal for interfaces

Gerald S. Williams gsw@agere.com
Wed, 2 Oct 2002 08:59:03 -0400


John Williams wrote:
> Here's the new version, in a no-frills stripped-down form, explained by 
> example.
...
> class I(interface):
>   prop1 = "Docstring for property prop1."
>   # It would be good form to put an argument list here,
>   # but this method will never be called so it's not necessary.
>   def meth1(): "Docstring for method meth1."

This is along the lines of what I was suggesting. Note that
you can optionally do some argument list checking. You can
also check other properties but that requires you to check
against an instantiated object and indicate the presence of
these properties when instantiating an interface object.

> class C(object, I):
...
> assert I not in C.__bases__ # Interfaces are not really base classes!

Isn't this assertion going to fail the way you showed it?
Inheritance needn't be used at all for interfaces.

> # Example of binding an existing class to an interface.  Like creating
> # an ordinary implementation, the bases are an interface and a regular
> # class, but instead of creating a usable new class, it just associates
> # an interface with a class and defines how the interface's methods are
> # implmented.  The magic class name __binding__ triggers this behavior.
> # Instances of this wrapper class are created by calling interface I.

I don't think you need any magic class names. If a class
wants to present an interface, it can provide a derived
class and/or surrogate if needed. For example:

class MyDerivedInterface(MyClass):
    def interface_name(self,x): return MyClass.my_name(self,x,1)

class MySurrogateInterface(object):
    def __init__(self,me):      self.me = me
    def __getattr__(self,attr): return self.me.__getattribute__(attr)
    def interface_name(self,x): return self.me.my_name(x,1)

Either one implements the interface.

> d = D()
> i = I(d)     # Note i could really just be d here, not that it matters.

But do interfaces really need to have this capability
built-in? If you want to present an interface that's
constrained, you can do it using a derived class or
surrogate. I would view "d" as the correct thing to
use in this example.

-----

One thing my simplified example did not show (though
it was in my local versions) is the ability to have
implemented_by() register the interface in addition
to testing compliance. This requires something like
"implementerClass.__implements__ += interfaceClass"
(with the appropriate safety checks). This would
allow a more "contractual" approach to interfaces,
since you could check to see if a class has been
registered as supporting an interface before trying
to use that interface.

-----

I think we're both saying the same thing--there is
a core issue that can be addressed without language
extensions or similar things that complicate the
implementation. But I have a more minimalist view:
don't impact anything if your class presents the
interface already. All you need is a simple means
to declare (and verify) that a class implements an
interface.

-Jerry