Package harold :: Package prog :: Package interface
[show private | hide private]
[frames | no frames]

Package harold.prog.interface

Contractual interfaces for Python.

Rationale

Let us illustrate the rationale of this package with a short example:
 class C:
   def m (self, x):
     return "I'm a C and I like", x

 class D (C):
   def m (self, x, y):
     return "I'm a D and I like", x, "and", y

 def proc (a_c):
   print a_c.m ("bananas")

 c1 = C()
 c2 = D()

 proc (c1) # works fine
 proc (c2) # raises a TypeError

Procedure proc expects instances of class C, and invokes their method m. c1 and c2 are both instances of C because D is a subclass of C. However, the last line raises an exception because D overrides m in a way which is incompatible with the definition of C.m: it expects 2 arguments instead of 1.

Such problems are usually considered as design flaws in a program, because they do not respect the semantics of inheritance. Python being a weakly typed language, it does not try to detect those problems at compile time. This is an advantage in many situations, making prototyping easier by allowing unfinished programs to run.

However, the drawback is that detecting such problems at runtime can be tricky, even with thoroughful tests. This package proposes an infrastructure allowing to detect such problems as soon as possible (i.e. when the class is loaded).

Contractual interface class

This package also provides the metaclass interface_class.InterfaceClass, whose class instances force their subclasses to respect the interface of their members (except all those starting with '__'). More precisely:

Failing to fullfill those requirements will issue an OverridingWarning. For strict control, those warnings can be turned into exception with the standard Python warning framework.

See interface_class.InterfaceClass for usage examples.

Forcing members to be public

In some cases, some members whose name starts with '__' are to be considered public with regard to the interface. This can be achieved by decorating the given member with the public decorator.

For example, the __init__ method is usually not considered part of the contractual interface (because it defines the interface of the class itself rather than the interface of instances, which is what we are adressing here).

However, there are situations where the subclasses are expected to produce instances in the same fashion as the superclass. In this case, the __init__ method will be decorated with public.

Warning/Disclaimer

It should be noted that InterfaceClass does not (can not) guarantee that overriding members respect the semantics of the original method. It does not even check that a property or callable will not throw an exception when used in a way it is supposed to work.

This package is of course not intended to replace good coding, but to help in early detecting coding mistakes while (hopefuly ;-P ) preserving much of python ease of use.

To Do: I plan to add method decorators to specify the expected types for callable parameters, and to ensure that the parameter types in overriding callables match those in the original callable.

Submodules

Function Summary
    Decorators
  public(f)

Generated by Epydoc 2.1 on Mon Dec 18 15:25:58 2006 http://epydoc.sf.net