0Pricing
Python Academy · Lesson

Basic Type Annotations

Annotate variables, function parameters, and return types.

Basic Type Annotations is a free Python Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Python Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Are Type Annotations?

Type annotations are hints that declare the expected type of variables, parameters, and return values. They are not enforced at runtime — they are read by type checkers like mypy.

def greet(name: str) -> str:
    return f"Hello, {name}"

result: str = greet("Alice")
print(result)

Variable Annotations

Annotate module-level, class-level, or local variables with a colon followed by the type.

count: int = 0
pi: float = 3.14159
name: str = "Python"
flag: bool = True

# Annotation without assignment (declaration only)
future_value: int

Function Parameter Annotations

Annotate each parameter in the function signature. Use -> type to annotate the return type.

def add(a: int, b: int) -> int:
    return a + b

def repeat(text: str, times: int = 1) -> str:
    return text * times

def no_return() -> None:
    print("side effect only")

Built-in Collection Types (Python 3.9+)

From Python 3.9+, use lowercase built-in types directly as generics: list[int], dict[str, int], tuple[int, ...].

def total(numbers: list[int]) -> int:
    return sum(numbers)

def config() -> dict[str, str]:
    return {"host": "localhost", "port": "8080"}

def coords() -> tuple[float, float]:
    return (1.0, 2.0)

Optional and Union

X | None (Python 3.10+) or Optional[X] means a value can be X or None. X | Y means X or Y.

from typing import Optional

def find(items: list[int], target: int) -> int | None:
    return next((x for x in items if x == target), None)

# Older style:
# def find(...) -> Optional[int]:

Union Types

int | str (Python 3.10+) or Union[int, str] annotates a value that may be one of several types.

from typing import Union

def process(value: int | str) -> str:
    return str(value)

# Older style:
# def process(value: Union[int, str]) -> str:

Type Aliases

Assign a type expression to a name to create a reusable alias, improving readability.

from typing import TypeAlias

Vector: TypeAlias = list[float]
Matrix: TypeAlias = list[Vector]

def dot(a: Vector, b: Vector) -> float:
    return sum(x * y for x, y in zip(a, b))

Callable Annotations

Use Callable[[arg_types], return_type] to annotate functions passed as arguments.

from typing import Callable

def apply(func: Callable[[int, int], int], x: int, y: int) -> int:
    return func(x, y)

result = apply(lambda a, b: a + b, 3, 4)
print(result)  # 7

Annotating *args and **kwargs

Annotate *args with the element type (not a tuple) and **kwargs with the value type.

def log(*messages: str, level: str = "INFO") -> None:
    for msg in messages:
        print(f"[{level}] {msg}")

def configure(**options: int) -> None:
    for key, val in options.items():
        print(f"{key}: {val}")

from __future__ import annotations

Add this import at the top of the file to enable postponed evaluation of annotations, allowing forward references without quotes.

from __future__ import annotations

class Node:
    def __init__(self, value: int, next: Node | None = None):
        self.value = value
        self.next = next   # forward ref to Node works here

TYPE_CHECKING Guard

Import types only when type-checking (not at runtime) to avoid circular imports or heavy imports.

from __future__ import annotations
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from mymodule import HeavyClass

def process(obj: HeavyClass) -> None:
    ...   # HeavyClass not imported at runtime

Quick Check

What annotation syntax marks a function as returning nothing?

Recap

Annotate variables with name: Type, parameters with param: Type, and returns with -> Type. Use list[T], dict[K,V] (Python 3.9+), X | None (3.10+), and from __future__ import annotations for forward refs.

Frequently asked questions

Is the “Basic Type Annotations” lesson free?

Yes — the full text of “Basic Type Annotations” is free to read here on the web, and the Python Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Python Academy course, upgrade to CoddyKit PRO.

What will I learn in “Basic Type Annotations”?

Annotate variables, function parameters, and return types. You practise Python Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Python Academy?

No prior experience is required. Python Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Basic Type Annotations” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Python Academy lesson?

Yes. Every Python Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Basic Type Annotations
  2. Complex Types: List, Dict, Optional, Union
  3. TypeVar, Generic Classes, and Protocol
  4. Running mypy and Fixing Type Errors
← Back to Python Academy