Typing
Type Check
  • Python does not implement type checking, use mypy to implement checking
  • Run it as part of your unit tests
  • pip install mypy
    
    # check type
    mypy scripy.py
    
    # recursively check type in a directory
    mypy ./path
            
    from typing import List
    
    # declare variable type
    # variable : type
    numbers: List[int] = list(range(4)) # [0, 1, 2, 3]
    
    numbers2: List[str] = list(range(4)) # error by mypy
    
    # decleare function input and output types
    # def function_name(parameter: type) -> return_type:
    def get_info(m: str) -> str:
        return 'Info: ' + m
    
    print(get_info('Hello')) # no error by mypy
    
    def get_info2(m: int) -> str:
        return 'Info: ' + str(m)
    
    print(get_info2('Hello')) # error by mypy
    		
    Multiple Types
  • @overload-decorated definitions are for the benefit of the type checker only, they are not called at runtime
  • non-@overload-decorated definition will be called at runtime
  • import typing
    
    @typing.overload
    def get_info(m: str) -> str:
        print('Call str type ...')
        return 'Info: ' + str(m)
    
    @typing.overload
    def get_info(m: int) -> str:
        print('Call int type ...')
        return 'Info: ' + str(m)
    
    def get_info(m):
        print('Call general function ...')
        return 'Info: ' + str(m)
    
    # general function will be call at run time
    print(get_info(100))
    print(get_info('Hello'))
    print(get_info(3.14)) # error by type checker
    		
  • Use Union to define either type contained in Union[]
  • import typing
    
    def get_info(m : typing.Union[int, str]) -> str:
        print('Call general function ...')
        return 'Info: ' + str(m)
    
    print(get_info(100))
    print(get_info('Hello'))
    print(get_info(3.14)) # error by type checker
    		
    Typing types
    from typing import List, Tuple, Dict, Set
    
    l: List[int] = list(range(4))
    t: Tuple[int, int] = (1, 2)
    d: Dict[str, int] = {'Age': 38}
    s: Set[int] = set([3, 2, 5, 6])
    
    l_d: List[Dict[str, int]] = [{'Age': 39}, {'ID': 1}]
    		
    Any
  • Take any data type
  • import typing
    
    def get_info(m : typing.Any) -> str:
        return 'Info: ' + str(m)
    
    print(get_info(100))
    print(get_info('Hello'))
    print(get_info(3.14))
    		
    None
    import typing
    
    def get_info(m : typing.Any) -> None:
        print('Info: ' + str(m))
        return 'Done' # error by type checker
    
    get_info(100)
    		
    Type Aliase
    import typing
    
    Lint = typing.List[int]
    
    def get_info(m : Lint) -> None:
        print('Info: ' + str(m))
    
    get_info([1, 2, 3, 4])
    get_info(100) # error by type checker
    		
    User-Defined Type
    import typing
    
    class Employee:
        def __init__(self, name: str):
            self.name = name
    
        def __str__(self):
            return self.name
    
    def get_employee(e: Employee):
        print(e)
    
    e = Employee('Lin')
    get_employee(e)
            
    # inheritence
    class QRFMember(Employee):
        def __init__(self, name: str, role:str):
            super().__init__(name)
            self.role = role
    
        def __str__(self):
            return super().__str__()+': '+self.role
    
    def get_employee(e: Employee):
        print(e)
    
    e = Employee('Lin')
    e_2 = QRFMember('Yanhua', 'Data Scientist')
    
    get_employee(e)
    get_employee(e_2)
            
    Generics
    import typing
    from collections.abc import Sequence
    
    def get_seq(s: Sequence):
        print(s)
    
    get_seq(list(range(10)))
    get_seq(range(10))
            
    import typing
    
    T = typing.TypeVar('T', str, int)
    
    def get_info(m : T, n : T) -> str:
        return str(m) + str(n)
    
    print(get_info('Hello', 'World!'))
    print(get_info(1, 2))
    print(get_info(1, 'Hello')) # error by type checker
    print(get_info(1, 3.14)) # error by type checker
    		
    NewType
    from typing import NewType
    
    UserId = NewType('UserId', int)
    some_id = UserId(524313) # int
    
    def get_id(id: UserId) -> int:
        return id+1
    
    print(get_id(some_id))
            
    Reference
  • Python STL Library
  • A BRIEF INTRODUCTION TO MYPY
  • Document
  • How to Use Static Type Checking in Python 3.6