Today I stumbled upon the python package called PyContracts. However, python has the
assert statement which seems to allow you to do exactly those things. What advantages do contracts have over assert statements?
Thanks for pointing out the existence of this interesting Python module. I checked it out and, in short, PyContracts is much higher level and powerful than mere built-in assertions, for checking function parameters and types.
Taking an example from the documentation itself, in the following, "PyContracts is smart enough to check that the two parameters a and b are matrices of compatible dimensions."
@contract def matrix_multiply(a, b): ''' Multiplies two matrices together.''' return numpy.dot(a, b)
Note that the only statement added is
@contract whereas, if using an assertion, one would have to explicitly compare the dimensions! For example:
assert a.shape == b.shape
The next example, from the tour again, "checks that the two lists a and b have elements of the same type (indicated by the variable x) and also that the returned list has the correct size (the sum of the two lengths)!"
@contract( a='list[ M ](type(x))', b='list[ N ](type(x))', returns='list[M+N](type(x))') def my_cat_equal(a, b): ''' Concatenate two lists together. ''' return a + b
Quite amazing. Again the above could be done using assertions only, but then it'd be much more complicated! PyContracts is about making it easier and yielding more readable code.
On the other hand, this clearly does not replace the need for assertions within the body of a function or method. So the two are complementary tools...