[Python-Dev] type categories

Guido van Rossum guido@python.org
Thu, 15 Aug 2002 08:13:52 -0400

> Extracting a category from an existing class:
> foobarlike = like(FooBar)
> The members of the foobarlike category are any classes that
> implement the same methods and attributes as FooBar, whether or not
> they are actually descended from it.  They may be defined
> independently in another library.

This seems fairly userless in practice -- you almost never want to use
*all* methods and attributes of a class as the characteristic.  (Even
if you skip names starting with _.)

> FooBar may be an abstract class used just as a template for a category.

Then the like() syntax seems unnecessary.  It then becomes similar to
Zope's Interfaces.

> Asserting that a class must be a member of a category:
> class SomeClass:
>    __category__ = like(AnotherClass)
>    ...

In Zope:

  class SomeClass:
    __implements__ = AnotherClass

By convention, AnotherClass usually has a name that indicates it
is an interface: IAnotherClass.

> At the end of the class definition it will be checked whether it
> really is a member of that category (like(SomeClass) issubsetof
> like(AnotherClass)) This attribute is inherited by subclasses.  Any
> subclass of this class will be checked whether it is still a member
> of the category.

I've been mulling over another way to spell this; perhaps you can
add categories to the inheritance list:

  class SomeClass(IAnotherClass):

There's ambiguity here though: extending an interface already uses the
same syntax:

  class IExtendedClass(IAnotherClass):

Disambiguating based on name conventions seems wrong and unpythonic.
In C++, abstract classes are those that have one or more abstract
methods; maybe we can borrow from that.

> A subclass
> may also override this attribute:
> class InheritImplementationButNotTheCategoryCheckFrom(SomeClass):
>    __category__ = some_other_category
>    ...

My alternative spelling idea currently has no way to do this; but one
is needed, and preferably one that's not too ugly.

> class AddAdditionalRestrictionsTo(SomeClass):
>    __category__ = __category__ & like(YetAnotherClass)

There's a (shallow) problem here, in that __category__ is not
initially in your class's namespace: at the start of executing the
class statement, you begin with an empty local namespace.

--Guido van Rossum (home page: http://www.python.org/~guido/)