Codeskill

Learn to code, step by step

Type hints that help

A typing taster, not a course in static typing religion. Type hints document intent, improve autocomplete, and catch some bugs early. They do not change how Python runs unless you add a separate type checker.

Basic annotations

Annotate parameters and return values on public functions. Skip obvious script glue if it adds noise.

def add_vat(net: float, rate: float = 0.20) -> float:
    return round(net * (1 + rate), 2)

name: str = "Alice"
count: int = 0

Collections and optional values

Use standard collection types from typing or, in Python 3.9+, built-in generics.

from typing import Optional

def first_email(contacts: list[dict[str, str]]) -> Optional[str]:
    if not contacts:
        return None
    return contacts[0].get("email")

Optional[str] means str | None. Either spelling is fine; be consistent within a project.

TypedDict for structured dicts

When a dict has known keys, say so. It helps more than bare dict.

from typing import TypedDict

class UserRow(TypedDict):
    id: int
    email: str
    active: bool

def deactivate(user: UserRow) -> UserRow:
    user["active"] = False
    return user

Running mypy or pyright lightly

Install a checker in dev dependencies and run it in CI when you are ready. Start with your package, not every script at once.

pip install mypy
mypy src/mytool

You will get false positives at first. Fix real issues; add targeted # type: ignore comments sparingly when a library lacks stubs.

What not to do

  • Do not annotate every local variable – clutter without benefit.
  • Do not chase perfect generics in a 40-line script.
  • Do not treat hints as runtime validation – use explicit checks for user input.
  • This is not TypeScript – embrace duck typing where it already works.

Hints alongside dataclasses

Dataclasses and type hints complement each other neatly.

from dataclasses import dataclass

@dataclass
class Invoice:
    number: int
    total: float
    paid: bool = False

Use hints where they pay rent: public APIs, data shapes, and code you edit often. Next: exceptions and logging as a system, not a scatter of bare except: blocks.

PreviousOOP patterns you’ll use