Skip to content

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Explore Python Libraries: Mypy

Jul 1, 2020 • 6 Minute Read

Introduction

Mypy is an open-source type checker compatible with Python 3.5+. It is maintained by the Dropbox team, and it is used most commonly to statically type-check code.

In this guide, you will explore the exciting, new Python library Mypy. You will also learn to annotate your code in Python 3.5+ and become familiar with Mypy's duck typing compatibility.

What is Mypy?

Mypy is the Python library used to check type annotation when you want to statically type code in Python. it works as an optional static type checker for Python. With Mypy, you can combine the benefits of dynamic and static programming in Python. You can type-check basically without running the actual code as Mypy has no runtime overhead.

You may still be wondering about the benefits of statically typing a code. Let's look at some benefits of static typing or type hinting.

Benefits of Static Typing

Static typing plays a very important role when typing a production code that will be maintained for years. Some benefits of static typing include:

  • Once you have type information for the code, it becomes much easier to understand and use the code.

  • If you can understand the code perfectly, it becomes a lot easier to maintain it.

  • It makes debugging code easier because you always know every function's input and output types.

  • You know where and how the objects in the code are used without actually running the code.

  • The code looks much cleaner in static typing, and the packaging problem of the code or program is also solved.

Installation

There are no dependencies for installing Mypy, assuming that you have Python and pip installed on your system.

Using pip

To install using pip, open the terminal and run the following command:

      pip install mypy
    

Using conda

To install using conda, open the terminal and run the following command:

      conda install -c conda-forge/label/cf201901 mypy
    

Type Annotation Using Python

When you run code over Mypy without any annotation, it doesn't throw an error as you have to teach Mypy to detect errors using type annotation in the code.

Let's look at a simple code with a type annotation.

      # wo_annotation.py
def adding_numbers(a ,b):
    return a+b
print(adding_numbers(4,5))
    

Running the above code with Python:

      $ python w_annotation.py
> 9
    

If you convert with type annotations, it will look like this:

      # w_annotation.py
def adding_numbers(a: int, b: int) -> int:
    return a+b
print(adding_numbers('4','5'))
    

In the above code, you are teaching Mypy that the adding_numbers function can accept and return an integer.

Now let's run this code.

      $ python w_annotation.py
> 45
    

As you can see, even after typing annotations in the code, you don't get an error as the interpreter is ignoring those type annotations.

To run a code with Mypy, simply run your .py extension file with Mypy's interpreter.

      mypy name_of_file.py
    

Now let's run this same code with Mypy.

      # annotating our fucntion with int type.
def adding_numbers(a : int, b: int) -> int:
    return a+b
print(adding_numbers('4','5'))
    
      # annotating our fucntion with str type.
def adding_numbers(a : str, b: str) -> str:
    return a+b
print(adding_numbers(0.1,2))
    

Here, you get errors without having to set up any kind of test harness over the code or by writing any test that would exercise this code. You get them by only running a test analyzer (Mypy) over the code.

So Mypy asks us to annotate our function signatures to validate our assumptions about input and output types.

Nominal Types

There are a lot of nominal types used for type checking. Here I explain only those which are most commonly used.

  • Built-in Python types (int, float, type, object, etc.)

  • Generic containers. Here are a few examples :

    • Tuple type

        t : Tuple(int, float) = 0, 1,1.2  
      
      • Dict type

         d : dict(str, int) = {'a' : 1, 'b' : 2}
         d : mutablemappingstr[ str, int ] = {'a':1, 'b' : 20}
        
        • List Type

          l : List[int] = [1,2,3]
          
          • Iterable type

            i : Iterable[Text] = [u '1'. u '2', u '3']
            
    • Alias Types

      vector = list[float]
      
      • Distinct Types

      UserId = NewType('UserId', int)
some_id = UserId(524313)
    

Duck Type Compatibility

Sometimes certain types in Python are compatible even if they are not subclasses of each other. For example, int objects are valid whenever float objects are expected. Mypy supports this via duck type compatibility, which is supported only for a small set of built-in-types.

  • float is duck type compatible with complex
  • int is duck type compatible with float and complex
  • In Python 2, str is a duck type compatible with Unicode.
      # importing math library
import math

# annotate the fucntion which we have defined
def degrees_to_radians(degrees: float) -> float:
    return math.pi * degrees / 180

n = 90
print(degrees_to_radians(n))
    

This code annotates the input with float type and gives the input in int. Still, Mypy is not throwing a type error.

Conclusion

In this guide, we looked at the basics of Mypy and how to write a static code in Python. We described the benefits of static typing and why it's important when writing a production code that will be maintained for years. We also learned how to annotate code in Python 3.5+ and how to check the annotated code with Mypy. Finally, we also looked at the duck typing compatibility of Mypy.

I hope that through this guide you came to understand the basics of Mypy and type checking in Python and are motivated to go deeper with this wonderful type checking tool. For more information, you can always check out the Mypy documentation.