3.8. Typing

typing is a Python module that allows developers to specify the types of inputs to make sure the input types are correct.

3.8.1. typing.Callable: Specify an Input is of Type Function

!pip install mypy

If you want to specify an input is of type function, use typing.Callable.

%%writefile callable_example.py 

# callable_example.py 

from typing import Callable

def multiply(x: float, y: float) -> float:
    return x * y

def multiply_then_divide_by_two(multiply_func: Callable[[float, float], float], x: float, y: float) -> float:
    return multiply_func(x, y) / 2

res = multiply_then_divide_by_two(multiply, 2, 3)
$ mypy callable_example.py

Callable can now be used static type checker such as mypy to check if the input is indeed a function.

!mypy callable_example.py
Success: no issues found in 1 source file

3.8.2. Use Python Class as a Type Hint

In the code below, Orange and Apple are subclasses of Fruit. How do we use type hint to specify that fruit_type in make_fruit should be a subclass of Fruit?

Using a parent class as a type hint will give you a type error when using mypy.

# type_example_wrong.py
class Fruit:
    def __init__(self, taste: str) -> None:
        self.taste = taste 

class Orange(Fruit):
    ... 

class Apple(Fruit):
    ... 

def make_fruit(fruit_type: Fruit, taste: str):
    return fruit_type(taste=taste)

orange = make_fruit(Orange, "sour")
$ mypy type_example_wrong.py
type_example_wrong.py:12: error: "Fruit" not callable
type_example_wrong.py:14: error: Argument 1 to "make_fruit" has incompatible type "Type[Orange]"; expected "Fruit"
Found 2 errors in 1 file (checked 1 source file)

Use typing.Type instead.

from typing import Type 

class Fruit:
    def __init__(self, taste: str) -> None:
        self.taste = taste 

class Orange(Fruit):
    ... 

class Apple(Fruit):
    ... 

def make_fruit(fruit_type: Type[Fruit], taste: str):
    return fruit_type(taste=taste)

orange = make_fruit(Orange, "sour")
$ mypy type_example_right.py
Success: no issues found in 1 source file