This module implements a sort of design by contract. It's interfacae is similar to Guido van Rossum's metaclass version. However it doesn't currently mix well with inheritance, which makes it pretty useless.
One thing it does have over Guido's effort is the support for `old' values.
I'm not a expert in Eiffel (I've played with it a bit) or design by contract so I can't really explain this in the proper terminology. I can give a toy example though:
class Uncontracted: def __init__(self,x,y): self.x=x self.y=y def do(self): self.x = self.x + 1 # sneaky! return self.x/self.y class Contracts: def pre___init__(self,x,y): assert y <> 0 def post_do(self): assert Old.self.x == self.x assert Old.self.y == self.y assert Result > 0, "Result was %s"%`Result` def class_invariants(self): assert self.x > 0 Contracted = dbc.add_contracts(Uncontracted,Contracts)
Looking at the "post_do" method you might be tempted to think ``Oh, but self is a mutable object, so refering to the old value of "self.x" will always give the same value.'' This is in fact not the case - the attribute access is computed before the function begins.
If __debug__ is not true, then dbc.add_contracts is a no-op. There are also strength parameters that affect how many of the conditions are added by add_contracts.
Send comments to email@example.com