Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Type Checking With Mypy

In this lesson, you’ll explore how to use Mypy to do type checking on your Python code. Mypy is the most common tool for doing type checking:

Mypy is an optional static type checker for Python that aims to combine the benefits of dynamic (or “duck”) typing and static typing. (Source)

Mypy was started by Jukka Lehtosalo during his Ph.D. studies at Cambridge around 2012. Initially, Mypy started as a standalone variant of Python with seamless dynamic and static typing. See Jukka’s slides from PyCon Finland 2012 for examples of the original vision of Mypy.

Following a suggestion by Guido van Rossum, Mypy was rewritten to use annotations instead, making it a static type checker for regular Python code.

If you don’t have Mypy on your system, you can install it using pip:

Shell
$ pip install mypy

Put the following code in a file called headlines.py:

Python
# headlines.py

def headline(text: str, align: bool = True) -> str:
    if align:
        return f"{text.title()}\n{'-' * len(text)}"
    else:
        return f" {text.title()} ".center(50, "o")

print(headline("python type checking"))
print(headline("use mypy", align="center"))

This is essentially the same code you saw earlier: the definition of headline() and two examples that are using it.

Now run Mypy on this code:

Shell
$ mypy headlines.py
headlines.py:10: error: Argument "align" to "headline" has incompatible
                        type "str"; expected "bool"

Based on the type hints, Mypy is able to tell you that you are using the wrong type on line 10. To fix the issue in the code, you should change the value of the align argument you are passing in. You might also rename the align flag to something less confusing:

Python
# headlines.py

def headline(text: str, centered: bool = False):
    if not centered:
        return f"{text.title()}\n{'-' * len(text)}"
    else:
        return f" {text.title()} ".center(50, "o")

print(headline("python type checking"))
print(headline("use mypy", centered=True))

Here you changed align to centered and correctly used a Boolean value for centered when calling headline(). The code now passes Mypy:

Shell
$ mypy headlines.py
$

No output from Mypy means that no type errors were detected. Furthermore, when you run the code you see the expected output:

Shell
$ python headlines.py
Python Type Checking
--------------------
oooooooooooooooooooo Use Mypy oooooooooooooooooooo

The first headline is aligned to the left, while the second one is centered.

00:00 In this video, you’re going to explore type checking with the package Mypy. So, what is Mypy? Well, this is from the Mypy project page. “Mypy is an optional static type checker for Python that aims to combine the benefits of dynamic (or ‘duck’) typing and static typing. Mypy combines the expressive power and convenience of Python with a powerful type system and compile-time type checking.” A little background on the Mypy project.

00:28 It initially started as a standalone variant of Python with its own seamless dynamic and static typing built-in. Later on, it was rewritten to use annotations and these type hints that you’ve been using, making it a static type checker for regular Python code.

00:45 I’ll include links to the Mypy project and articles discussing the background on Mypy. You can find those in the text below this video. A quick note on installing Mypy. In your terminal, you’d use pip install mypy, all lowercase.

01:01 As you continue along in this video, you’ll practice running Mypy on your code. And even though you run Mypy against your code, it won’t execute your code.

01:11 It simply does the type checking on it. So from your terminal, you would type mypy and then the name of the Python program you’d like it to check.

01:19 Let me have you practice this yourself.

01:24 If you don’t already have Mypy on your system, you can install it using pip with pip install mypy, all lowercase. And once that’s completed, you’ll see at the bottom here that it shows Successfully installed.

01:41 Now it’s time to put it to use. In the editor of your choice, create a new file. I’ll have you name it headlines.py. This code will seem familiar as you used it earlier.

01:57 You’re going to start with an argument for headline(), text, that will have str (string) as a type hint, and then a second optional argument of align, which will be a bool with a default value of True.

02:12 And this function will return a str.

02:18 And if align: use an f-string to take the text and apply the method .title() to title case your text, then a line return.

02:31 And replicate, based on the length of the text, this dash symbol ('-') underneath it.

02:38 else: you’ll return an f-string with a space in the front, the text title cased, using that method, a space after, and then apply the .center() method with a total of 50 characters using the value of lowercase "o" as the characters.

02:58 Then here, you’re going to call your method, print headline(), and the first one is just real simple, print "python type checking".

03:08 And then this time, "use mypy". This time, you’re going to say align=, and you can see here it says align equals a bool = True, but in this case we’re going to just put, “Oh, I want to have it "center".” That’s an incorrect type, which is a string.

03:25 Okay. So, save that. Now to run Mypy on this, down in your terminal where you can run your code, you’ll start by saying mypy instead of python and then put the name of the Python file in there. So in this case, mypy headlines.py.

03:41 And it’ll take a second. In this case, you can see it says here at line 10, there’s an error. Argument align for headline() has an incompatible type of str, when it expected a bool. Based on the type hints, Mypy was able to tell you that you’re using the wrong type on that line. To fix the issue, you could change the value. In fact, it might make more sense if your argument was explained a little better and you said, instead of align, that you want this to be centered, which takes a True/False argument a little better. So up here, centered: bool, and we’ll say by default that’s False.

04:14 And I guess you would need to change this to a not. if not centered: then you do the first style, else: in this case, you would get this answer.

04:22 So here, now, we’d say centered, we do want this centered, and I’ll have you put a bool in. Okay. Save, try running Mypy again on that. Ope, if not centered, I’ve got to change that too. Okay.

04:36 So now that I’ve changed the first statement for the if statement to be centered, and it’ll default to False, it will travel into here.

04:44 Okay, this looks good. So Mypy helped me with that. After saving, run Mypy again. All right! That time Mypy didn’t return any kind of errors. So it looks like the code passes Mypy’s checks. Awesome!

04:58 So now if you want to run it by saying python headlines.py, you can see here it performed both prints here, Python Type Checking, and the centered version with Use Mypy. Nice.

05:12 In the next video, you’ll explore the pros and cons of using type hints.

Avatar image for charliem22

charliem22 on Oct. 30, 2019

Hi Chris – I use PyCharm Professional and I’m wondering if there is any advantage to adding the Mypy plugin to my PyCharm environment. I searched a bit online and couldn’t find an obvious ‘value-added’ advantage. What’s your opinion/experience?

Thanks in advance, charlie

Avatar image for Chris Bailey

Chris Bailey RP Team on Oct. 31, 2019

Hi Charlie, I’m using VScode as my primary Python tool currently. I will ask others on the team if they have experience with the Mypy plugin. Looking it over it seems like it might make the testing/type checking work flow easier, somewhat automated. I will get back to you when I hear more from the Real Python team. Thanks

Avatar image for charliem22

charliem22 on Oct. 31, 2019

Thanks Chris. I’ll be interested in the results of your ‘survey.’ charlie

Avatar image for Pygator

Pygator on Nov. 3, 2019

I wonder why the : is to the left of the args, but to the right of the return type?

Avatar image for Geir Arne Hjelle

Geir Arne Hjelle RP Team on Nov. 3, 2019

Ah … I hadn’t thought of that :)

You’re talking about something like this, right?

def headline(text: str) -> str:
                 ^            ^
            : to left    : to right

I guess the explanation is that the last : (after the return type) actually has nothing to do with the type annotation. The return type is “signaled” by the arrow ->. The final : is the usual : signaling the start of a block that you always need after a def ...

Avatar image for Chris Bailey

Chris Bailey RP Team on Nov. 4, 2019

Hi Charlie, I didn’t find many Pycharm users on the team, and if they were (and used Mypy) they used it stand alone. Also had another that uses Pycharm but mainly working in Python 2.7. Sorry I couldn’t provide more background on the plugin.

Avatar image for Pygator

Pygator on Nov. 12, 2019

Thanks Geir

Become a Member to join the conversation.