[Fwd: [Types-sig] Re: [Python-Dev] Revive the types sig?]

Raymond Hettinger othello@javanet.com
Mon, 12 Mar 2001 10:09:00 -0500

Ka-Ping Yee wrote:
>For the record, here is a little idea i came up with on the
>last day of the conference:
>Suppose there is a built-in class called "Interface" with the
>special property that whenever any immediate descendant of
>Interface is sub-classed, we check to make sure all of its
>methods are overridden.  If any methods are not overridden,
>something like InterfaceException is raised.
>This would be sufficient to provide very simple interfaces,
>at least in terms of what methods are part of an interface
>(it wouldn't do any type checking, but it could go a step
>further and check the number of arguments on each method).
>    >>> class Spam(Interface):
>    ...     def islovely(self): pass
>    ...
>    >>> Spam()
>    TypeError: interfaces cannot be instantiated
>    >>> class Eggs(Spam):
>    ...     def scramble(self): pass
>    ...
>    InterfaceError: class Eggs does not implement interface Spam
>    >>> class LovelySpam(Spam):
>    ...     def islovely(self): return 1
>    ...
>    >>> LovelySpam()
>    <LovelySpam instance at ...>
>Essentially this would replace the convention of writing a
>whole bunch of methods that raise NotImplementedError as a
>way of describing an abstract interface, making it a bit easier
>to write and causing interfaces to be checked earlier (upon
>subclassing, rather than upon method call).

All in all, I REALLY like this approach in terms of simplicity
and conformity with the existing language.  Also, the approach
doesn't require alot of lines of overhead to set-up an interface.

One question:  Should InterfaceError be a error or a warning?  I
think the Eggs class should still compile with a warning and allow
for islovely() to be added dynanically later.

Another suggestion:  add a built-in function to dynamically check
whether a class meets an interface specs even when the interface
was not specified in the class definition.  Example:
	>>> class Sparrow:
	... 	def islovely(self): return 1
	>>> s = Sparrow()
	>>> print implements(s, Spam)

One reservation:  does this approach provide significant advantages 
over run-time virtual assertions and normal sub-classing which we 
already have?  Example:
	>>> class Spam:
	...	def islovely(self): assert 0, 'Virtual method not implemented'
	>>> class Eggs(Spam):
	...	def scramble(self): pass
	>>> e = Eggs()
	>>> e.islovely()
	AssertionError:  Virtual method not implemented

Submitted for your approval,   Raymond Hettinger

"In theory, there is no difference between theory and practice.
 In practice, there is."  -- Yogi Berra