Type hints in Python

Dmitry Viskov
dmitry.viskov@webenterprise.ru

 

Background

  • 2006: PEP 3107 -- Function Annotations
  • 2008: Python 3.0
  • 2014: PEP 483 -- The Theory of Type Hints
               PEP 484 -- Type Hints
  • 2015: Python 3.5 + module typing
def fib(n: int) -> None:
    a, b = 0, 1
    while a < n:
        print(a)
        a, b = b, a+b


def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
    ...


def bar(t: int) -> None:
    print(t)
    return True


print(bar('test'))  # it works!


Where Сan It Be Used?

  • IDE
  • Documentation
  • Type checkers

Why Static Type Checkers?

Find bugs of course!

mypy - experimental static type checker

from typing import List

a = []  # type: List[str]

a.append(0)
a.append("i")

print(a)  # [0, 'i']
$ python test3.py
[0, 'i']

$ mypy test3.py
test3.py:5: error: Argument 1 to "append" of "list" has
incompatible type "int"; expected "str"

mypy - experimental static type checker

from typing import List, Any

a = []  # type: List[Any]

a.append(0)
a.append("i")

print(a)  # [0, 'i']

Also It Could Be Used In Python 2

$ mypy --py2 program.py
  • comment-based function annotation syntax
  • pip install typing

Alternatives

  • PyType (from Google):
    https://github.com/google/pytype
     
  • Cython (hardcore!)

PyContracts

  • https://github.com/AndreaCensi/contracts/
  • Python 2 + Python 3 support
from contracts import contract

@contract(a='int,>0', b='list[N],N>0', returns='list[N]')
def my_function(a, b):
    return [1,2,3]

print my_function(1, [])
  File "/srv/venvs/annotations/local/lib/python2.7/site-packages/contracts/main.py", line 253, in contracts_checker
    raise e
contracts.interface.ContractNotRespected: Breach for argument 'b' to my_function().
Condition 0 > 0 not respected
checking: N>0           for value: Instance of <type 'list'>: []   
checking: list[N],N>0   for value: Instance of <type 'list'>: []   
Variables bound in inner context:
- N: Instance of <type 'int'>: 0

PyContracts

from contracts import contract, new_contract

@new_contract
def my_condition(x):
    return x > 0


@contract
def fun(a):
    """
        Description...
        :type a: ``list(my_condition)``
    """
    pass


fun([1,0])

Thanks!

dmitry.viskov@webenterprise.ru

strannik_nnov