<div dir="ltr">I have to say that I find the capabilities in PyContracts--which are absent currently in mypy--to be very compelling. If we are going to add encouragement to use type annotations, adding richer types seems extremely worthwhile. <div>
<br></div><div>I do not see in any of the discussion a way that mypy/typing.py could express a concept like "A list/sequence of at least N elements, each of which has some property (as well as a basic data type)." In fact, I have trouble imagining how a native syntax could do this, rather than using a custom DSL like PyContracts uses. Well, we could do it by sticking lambdas in for properties, but that would get very ugly quickly.<div>
<br></div><div><br></div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">2) Using annotations:<br>
<br>
@contract<br>
def mysum(l: 'list[>=1](int,>0)') -> 'int,>0':<br>
...<br>
<br>
3) Using docstrings, with the :type: and :rtype: tags:<br>
<br>
@contract<br>
def mysum(l):<br>
"""<br>
:type l: list[>=1](int,>0)<br>
:rtype: int,>0<br>
"""<br></blockquote><div><br></div><div>I don't really care about the annotations vs. docstring issue much. But incorporating pre/post-conditions as part of typing makes a whole lot of sense to me.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=""> @contract<br></div>
def matrix_multiply(a, b):<br>
''' Multiplies two matrices together.<br>
<br>
:param a: The first matrix. Must be a 2D array.<br>
:type a: array[MxN],M>0,N>0<br>
<br>
:param b: The second matrix. Must be of compatible dimensions.<br>
:type b: array[NxP],P>0<br>
<br>
:rtype: array[MxP]<br>
'''<br>
return numpy.dot(a, b)<br></blockquote><div><br></div><div>This is also quite lovely and powerful (and not doable in mypy), as is the error report produced.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Example:<br>
<br>
a = numpy.zeros((2,2))<br>
b = numpy.zeros((3,2))<br>
matrix_multiply(a,b)<br>
<br>
Exception:<br>
<br>
Breach for argument 'b' to matrix_multiply().<br>
Expected value for 'N' was: Instance of int: 2<br>
instead I received: Instance of int: 3<br>
checking: N for value: Instance of int: 3<br>
checking: NxP for value: Instance of tuple: (3, 2)<br>
checking: array[NxP] for value: array['3x2'](float64)<br>
array([[ 0., 0.], [ 0., 0.], ... [clip]<br>
checking: array[NxP],P>0 for value: array['3x2'](float64)<br>
array([[ 0., 0.], [ 0., 0.], ... [clip]<br></blockquote></div><br clear="all"><div><br></div>-- <br>Keeping medicines from the bloodstreams of the sick; food <br>from the bellies of the hungry; books from the hands of the <br>
uneducated; technology from the underdeveloped; and putting <br>advocates of freedom in prisons. Intellectual property is<br>to the 21st century what the slave trade was to the 16th.<br>
</div></div></div></div>