Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Design by Contract in Python

I am looking to start using DBC on a large number of Python-based projects at work and am wondering what experiences others have had with it. So far my research turned up the following:

  • http://www.python.org/dev/peps/pep-0316/ - PEP 316 that is supposed to standardize design by contract for Python which has been deferred. This PEP suggests using docstrings.
  • http://www.wayforward.net/pycontract/ - Contracts for Python. This seems to be a complete, but unmaintained framework using docstrings.
  • http://www.nongnu.org/pydbc/ - PyDBC which implements contracts using metaclasses. Also unmaintained for a few years.

My questions are: have you used DBC with Python for mature production code? How well did it work/was it worth the effort? Which tools would you recommend?

like image 531
ipartola Avatar asked Dec 19 '11 15:12

ipartola


People also ask

What is a contract in Python?

Contracts for Python Functions Contracts can be used to validate the input or output of a function. Data flow among components can be hard to keep track or maintained, sometimes forcing us to write print statements everywhere trying to catch malformed data.

What is Design by Contract in programming?

Design by contract also defines criteria for correctness for a software module: If the class invariant AND precondition are true before a supplier is called by a client, then the invariant AND the postcondition will be true after the service has been completed.

What is design by contract in Java?

Design by Contract™ is an approach to designing robust yet simple software. It provides methodological guidelines to achieve these goals without resorting to defensive programming. Instead, Design by Contract builds class invariants and pre/post validation of methods arguments and return values into the code itself.

What is the design by contract feature in the .NET framework?

Microsoft has released a library for design by contract in version 4.0 of the . net framework. One of the coolest features of that library is that it also comes with a static analysis tools (similar to FxCop I guess) that leverages the details of the contracts you place on the code.


1 Answers

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.

like image 52
snim2 Avatar answered Sep 18 '22 22:09

snim2