Type-hinting and mypy

Python is a strongly typed language (as well as being dynamically typed). This means that every value has an associated type, even though variable types may change. Confusing, right?

For this course, we're going to use type-hinting to help us write more robust code. We will always declare the type we are associating with a variable. Type-hinting was introduced in Python 3 and is optional; the Python interpreter ignores type-hints. We will use a static type checker called mypy to analyze our code; this will check that we are being consistent with types and lead to tighter code (and fewer bugs!).

A quick aside about terminology: developers use optional tools like mypy to "lint" their code.

(I think it should be called "delinting" but for some reason it's called "linting"...)

A linter analyzes code for errors that can be automatically detected, such as inconsistent types.

Type-hinting

In Python, we can use the following syntax to declare a type for a variable when we first use it

*variable_identifier* : *type* = *initial_value*

This will probably be more clear with some examples!

founder : str = "Mary Lyon"

in-person : bool = False

year : int = 2022

The Python interpreter ignores type-hinting.

This is similar to how it ignores comments; the type-hinting code is essentially skipped by the interpreter. This may seem strange, but it allows

  • support for the the dynamically typed aspect of the language

  • simplicity of code when not used

  • developers to opt-in to indicating the type of a variable.

In this course, we will always use type-hinting!

Static type checking with mypy

There are different tools that can analyze type-hinting in Python to ensure consistency of types in your code. We'll use mypy, which is one of the most popular static type checkers. "Static" means that it looks at a snapshot of your code (as opposed to the interpreter, which "dynamically" checks types as it is executing your code). So, what sort of bugs could it detect?

Suppose we declare a variable to be of type int and printed out a value that used an operator on it, as in:

snowfall : int = 4
print( 2*snowfall )

This code is type-consistent and will perform as expected.

But, what if instead we got a bit confused and used quotes around our value:

snowfall : int = "4"
print( 2*snowfall )

The code is not type-consistent and will lead to unexpected results (but no errors).

However, if we use mypy to check it, we get results that indicate a bug:

main.py:1: error: Incompatible types in assignment (expression has type "str", variable has type "int")

Found 1 error in 1 file (checked 1 source file)

Next: Functions