Using Design by Contract in Python

The PEP you found hasn’t yet been accepted, so there isn’t a standard or accepted way of doing this (yet — you could always implement the PEP yourself!). However, there are a few different approaches, as you have found.

Probably the most light-weight is just to simply use Python decorators. There’s a set of decorators for pre-/post-conditions in the Python Decorator Library that are quite straight-forward to use. Here’s an example from that page:

  >>> def in_ge20(inval):
  ...    assert inval >= 20, 'Input value < 20'
  ...
  >>> def out_lt30(retval, inval):
  ...    assert retval < 30, 'Return value >= 30'
  ...
  >>> @precondition(in_ge20)
  ... @postcondition(out_lt30)
  ... def inc(value):
  ...   return value + 1
  ...
  >>> inc(5)
  Traceback (most recent call last):
    ...
  AssertionError: Input value < 20

Now, you mention class invariants. These are a bit more difficult, but the way I would go about it is to define a callable to check the invariant, then have something like the post-condition decorator check that invariant at the end of every method call. As a first cut you could probably just use the postcondition decorator as-is.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)