Type Hints

Python 3.14 · ✓ verified by execution on 2026-07-28

Type Hints

Type hints allow you to define what types of arguments a function expects and what type it returns. However, the Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.

Annotations

Here is a basic example of type annotations:

python
def greeting(name: str) -> str:
    return 'Hello ' + name
print(greeting('Alice'))
Output
Hello Alice

Predict the Output: What happens if we pass strings to a function annotated to take integers?

Click here to make your guess

If you guessed it throws a TypeError, you’re not alone! But click Run below to see what Python actually does.

python
def add(x: int, y: int) -> int:
    return x + y
# Python runtime ignores the incorrect type
print(add('a', 'b'))
Output
ab

Python will happily execute the code above because runtime doesn’t enforce annotations. This is a common misconception! Python won’t throw an error if you pass the wrong type; the tools are meant for static analysis, like mypy.

The Union Type (|)

Sometimes a variable can be one of several types. To define a union, use e.g. Union[int, str] or the shorthand int | str.

python
def process(data: int | str) -> str:
    return str(data) * 2
print(process(3))
Output
33

Similarly, if a variable can be None, you can use Optional.

python
from typing import Optional
def greet(name: Optional[str] = None) -> str:
    if name:
        return f'Hi, {name}'
    return 'Hi'
print(greet())
Output
Hi

Generics

Generic functions and classes can be parameterized by using type parameter syntax:

python
def get_first[T](items: list[T]) -> T:
    return items[0]
print(get_first([1, 2, 3]))
Output
1

Generic classes have __class_getitem__() methods, meaning they can be parameterised at runtime (e.g. list[int] below):

python
MyList = list[int]
nums: MyList = [1, 2, 3]
print(nums)
Output
[1, 2, 3]
Input (str) Output (str)
A type checker acting as a filter before runtime.

Now test your understanding with the challenges below!

Check yourself

How does the Python runtime use type annotations?

Reveal answer

It completely ignores them. — Python type hints are completely ignored at runtime by standard Python; they don't affect performance or throw errors. They are checked by third-party tools like mypy.

Which syntax is valid in Python 3.10+ to express that a variable can be an integer or a string?

Reveal answer

int | str — Python 3.10 introduced the `|` operator for Union types, making `int | str` the standard modern syntax.

What is the primary purpose of generic classes like `list[T]`?

Reveal answer

To parameterize the class so type checkers know what type of elements it contains. — Generics allow type checkers to verify the types of items stored in containers, preventing type-related bugs without changing runtime behavior.

Challenges

Challenge 1 +50 XP

Fix the function signature using the `|` operator so that `value` can be either an `int` or a `float`.

python
  • Test 1 — expects "7.0\n"
Show solution (0 XP)
def double(value: int | float) -> float:
    return float(value * 2)
print(double(3.5))

Challenge 2 +50 XP

Update the function signature to specify that it takes a `list` of `str` and returns a `str`.

python
  • Test 1 — expects "ab\n"
Show solution (0 XP)
def combine(items: list[str]) -> str:
    return ''.join(items)
print(combine(['a', 'b']))