[Python-ideas] Optional static typing -- late to the party

David Mertz mertz at gnosis.cx
Wed Aug 20 19:23:02 CEST 2014


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.

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.


2) Using annotations:
>
>     @contract
>     def mysum(l: 'list[>=1](int,>0)') -> 'int,>0':
>         ...
>
> 3) Using docstrings, with the :type: and :rtype: tags:
>
>     @contract
>     def mysum(l):
>         """
>             :type l: list[>=1](int,>0)
>             :rtype: int,>0
>         """
>

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.


>    @contract
>    def matrix_multiply(a,  b):
>         ''' Multiplies two matrices together.
>
>             :param a: The first matrix. Must be a 2D array.
>             :type a: array[MxN],M>0,N>0
>
>            :param b: The second matrix. Must be of compatible dimensions.
>            :type b: array[NxP],P>0
>
>             :rtype: array[MxP]
>        '''
>         return numpy.dot(a, b)
>

This is also quite lovely and powerful (and not doable in mypy), as is the
error report produced.


> Example:
>
>     a = numpy.zeros((2,2))
>     b = numpy.zeros((3,2))
>     matrix_multiply(a,b)
>
> Exception:
>
>     Breach for argument 'b' to matrix_multiply().
>     Expected value for 'N' was: Instance of int: 2
>             instead I received: Instance of int: 3
>     checking: N                for value: Instance of int: 3
>     checking: NxP              for value: Instance of tuple: (3, 2)
>     checking: array[NxP]       for value: array['3x2'](float64)
> array([[ 0.,  0.],        [ 0.,  0.], ... [clip]
>     checking: array[NxP],P>0   for value: array['3x2'](float64)
> array([[ 0.,  0.],        [ 0.,  0.], ... [clip]
>


-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140820/30600ce1/attachment.html>


More information about the Python-ideas mailing list