HOLIDAY SALE! Save 50% on Membership with code HOLIDAY50. Save 15% on Mentorship with code HOLIDAY15.

4) Functions and Scope Lesson

What is Python Type Hinting

12 min to complete · By Martin Breuss

Thanks to the docstring you wrote in the previous lesson, your function is now well-documented, and you can always look up what types of arguments it takes and what it returns. To keep the code easier to read in your learning material, you'll see an abbreviated version of the docstring here:

def greet(greeting, name):
    """Generates a greeting."""
    sentence = f"{greeting}, {name}! How are you?"
    return sentence

In your IDE, you can collapse parts of your code, usually by clicking a small arrow displayed in the margins next to your line numbering. But what if you have ever only written a short docstring like the one above?

Python is a dynamically-typed language, which means that you don't need to define what data type a variable is or what data types a function can take as input. This means that strange things can happen with your function!

Dynamic Typing And Static Typing

Dynamic typing, also called "duck typing", evaluates variables and inputs at runtime of your script. There is no need to declare the type of a variable when you initialize it. Your variable, e.g., a, could be of any type and change types throughout its lifetime:

a = 3
a = "hello"
a = 4.2
a = True

Static typing, on the other hand, gives every variable a specific type when you create it. In a statically-typed language, you can't change the variable's type once it's declared in the same way you can in Python.

Both approaches have advantages as well as disadvantages. Static typing can make programs more secure, avoiding accidental mess-ups that could come from poorly designed code.

Example

Irrespective of whether you wrote an extensive docstring or not, anyone using your greet() function could input any sort of data type as arguments and get surprising outputs:

greet([1, 2, 3], 42)  
# [1, 2, 3], 42! How are you?

greet(True, False)  
# True, False! How are you?

A function in a statically-typed language would have strict definitions of what data type the function can take as inputs; and throw an error if anything else was passed to it.

As you can see, Python doesn't throw an error. It's able to handle the input, even though it might not be what you wrote the function for. This can potentially cause troubles in the applications you're building, but it also opens up new possibilities and makes it faster and more convenient to develop.

In an attempt to get the best of both worlds, Python started to introduce type hinting, also called type annotations, to the language.

Type Hinting

Type hinting was introduced to improve documentation on which data types should be used when calling a function.

Colorful illustration of a light bulb

Info: Python remains dynamically typed, which means that even if you add type hints to your function, the types aren't enforced.

Primarily, type hints are a way to more concisely and unambiguously document your function.

To add type hints to your function definition, you add the expected type of a parameter after a colon (:). You can also define the expected type of your return value with an arrow (->) at the end of the first line of your function definition:

def greet(greeting: str, name: str) -> str:
    """Generates a greeting."""
    sentence = f"{greeting}, {name}! How are you?"
    return sentence

With the type hints added to greet(), it's quicker to see what type of input the function expects and what type of data it returns.

But Python stays true to its dynamic typing and won't enforce these type hints. Even if you added them and you pass an int to greet(), you still won't get an error. Type hints are mainly meant to improve the documentation of your functions.

Enforced Type Hinting

There are external packages, such as mypy, that make it possible to enforce static typing in Python. mypy uses the type hints and throws errors if you attempt to pass any data type that contradicts them. By using type hints together with mypy to check your code, you can benefit from some of the advantages of static typing in Python.

Colorful illustration of a light bulb

Info: mypy is an external package, which means you need to install it before you can use it. If you haven't done this before, read over the next sections about virtual environments and external packages before completing the exercise below.

To check your code with mypy, you need to first install the package, and then run mypy from your CLI and pass it the path to your Python script:

mypy yourscriptname.py

If mypy doesn't identify any issues where your type-hinted function might be called with the wrong data types as input, it'll show you a success message. Otherwise, you'll get to meet a new error-message friend:

mypy typechecker.py
typechecker.py:7: error: Argument 1 to "greet" has incompatible type "List[int]"; expected "str"
typechecker.py:7: error: Argument 2 to "greet" has incompatible type "int"; expected "str"
typechecker.py:8: error: Argument 1 to "greet" has incompatible type "bool"; expected "str"
typechecker.py:8: error: Argument 2 to "greet" has incompatible type "bool"; expected "str"
Found 4 errors in 1 file (checked 1 source file)

mypy successfully analyzed your code and identified that it included some use cases that contradict the information encoded through your function's type hints.

Practice with Type Hinting

  • Write a script called typechecker.py where you add your type-hinted greet() function.
  • Add some example calls to the greet() function that takes data types other than strings as their input.
  • Run the file normally and confirm that everything works fine
  • Now run the file with mypy and confirm that you get similar error messages as the ones shown above.
  • Fix the errors by changing the inputs to your function calls, then confirm that checking your script with mypy now passes all tests.

You don't need to add type hints to your functions. It's good to know that this feature exists, but it doesn't need to be part of your workflow. If you like the additional descriptiveness that it gives to your functions, then it's a great habit to get into adding type hints as a part of documenting your functions.

Colorful illustration of a light bulb

Additional Resources

Now that you have a well-documented function, both through adding a descriptive docstring, as well as type hints, you're ready to learn about how the concept of scopes applies in regards to functions.

Summary: What is Python Type Hinting

  • Python is a dynamically typed language, which gives you freedom but also introduces potential errors. You can add type hints to your functions to better document them. You can even use external packages, such as mypy, to enforce type hints and use Python more like a statically typed language.
  • To add type hints to your function definition, you add the expected type of a parameter after a colon (:). You can also define the expected type of your return value with an arrow (->) at the end of the first line of your function definition.