Programování

Typování v Pythonu a mypy: typové anotace, které chytí chyby

Jak psát typové anotace v Pythonu 3.10+, co znamená Optional, Protocol nebo TypedDict a jak nasadit mypy do projektu postupně, bez zbytečné bolesti.

12. 10. 2026 · 4 min čtení

Python je dynamicky typovaný a typové anotace za běhu nic nekontrolují. Přesto se vyplatí je psát: statický kontrolor jako mypy najde chyby dřív, než kód spustíte, a editor díky nim lépe napovídá. Ukážeme si syntaxi pro moderní Python a rozumné nasazení mypy.

Základní syntaxe

def pozdrav(jmeno: str, opakovani: int = 1) -> str:
    return ", ".join([f"Ahoj {jmeno}"] * opakovani)

vek: int = 30
ceny: list[float] = [9.9, 19.9]
sklad: dict[str, int] = {"jablka": 5}
souradnice: tuple[float, float] = (50.08, 14.42)

Od Pythonu 3.9 lze používat vestavěné typy list, dict, tuple přímo v anotacích – typing.List a spol. už nepotřebujete.

None a sjednocení typů

Od Pythonu 3.10 se sjednocení píše svislítkem:

def najdi_uzivatele(uid: int) -> dict[str, str] | None:
    ...

X | None je totéž jako starší Optional[X]. Mypy pak vynutí kontrolu:

u = najdi_uzivatele(1)
print(u["jmeno"])   # error: Value of type "dict[str, str] | None" is not indexable

if u is not None:
    print(u["jmeno"])  # OK – mypy ví, že tu už None není

Tomuto zužování typu podle podmínky se říká narrowing a funguje i s isinstance.

Užitečné typy z modulu typing

from typing import Literal, TypedDict, Protocol, Callable, Any
from collections.abc import Iterable, Sequence

Rezim = Literal["dev", "prod"]

class Konfigurace(TypedDict):
    host: str
    port: int
    debug: bool

class MaNazev(Protocol):
    nazev: str

def vypis_nazvy(polozky: Iterable[MaNazev]) -> None:
    for p in polozky:
        print(p.nazev)

Handler = Callable[[str, int], bool]
  • Literal – jen konkrétní hodnoty.
  • TypedDict – slovník s pevně danými klíči, typicky JSON z API.
  • Protocol – strukturální typování („duck typing“): vyhovuje každá třída, která má atribut nazev, bez dědění.
  • Iterable / Sequence v parametrech jsou lepší než list – funkce pak přijme i n-tici nebo generátor.
  • Any vypíná kontrolu. Používejte střídmě.

Generika

Python 3.12 přinesl novou syntaxi typových parametrů:

def prvni[T](polozky: Sequence[T]) -> T:
    return polozky[0]

type Matice = list[list[float]]

Pro starší verze použijte TypeVar:

from typing import TypeVar
T = TypeVar("T")

def prvni(polozky: Sequence[T]) -> T:
    return polozky[0]

Instalace a spuštění mypy

pip install mypy
mypy src/

Mypy ve výchozím stavu nekontroluje těla funkcí bez anotací. To je záměr: umožňuje postupné zavádění. Když tedy spustíte mypy na starý kód a nic nenajde, neznamená to, že je bez chyb.

Konfigurace v pyproject.toml

Rozumný start pro existující projekt:

[tool.mypy]
python_version = "3.12"
warn_unused_ignores = true
warn_redundant_casts = true
warn_return_any = true
check_untyped_defs = true
ignore_missing_imports = false

[[tool.mypy.overrides]]
module = ["nejaka_stara_knihovna.*"]
ignore_missing_imports = true

Pro nový projekt rovnou zapněte přísný režim:

[tool.mypy]
strict = true

strict mimo jiné vyžaduje anotace u všech funkcí a zakazuje implicitní Any.

Knihovny bez typů

Pokud knihovna nemá typy, mypy hlásí missing library stubs. Řešení:

  1. Zkuste nainstalovat stuby: pip install types-requests, types-PyYAML apod. Mypy je umí navrhnout: mypy --install-types.
  2. Pokud stuby neexistují, přidejte modul do overrides s ignore_missing_imports = true.

Postupné zavádění v praxi

  1. Přidejte mypy s mírnou konfigurací a opravte nalezené chyby.
  2. Anotujte nejdřív veřejná rozhraní – funkce, které volají jiné moduly.
  3. Zapínejte přísnější volby modul po modulu přes [[tool.mypy.overrides]], například disallow_untyped_defs = true pro už otypované balíčky.
  4. Přidejte mypy do CI, aby se nové chyby nedostaly do hlavní větve.

Ignorování konkrétních chyb

vysledek = podivna_funkce()  # type: ignore[no-untyped-call]

Vždy uvádějte kód chyby v hranatých závorkách. Holé # type: ignore umlčí všechno včetně budoucích chyb na stejném řádku. S volbou warn_unused_ignores vás mypy upozorní, když už ignore není potřeba.

Kontrola typu za běhu

Mypy je statický nástroj. Pro validaci dat zvenku (JSON, formuláře, konfigurace) potřebujete kontrolu za běhu – na to slouží Pydantic, který anotace využívá k validaci.

Alternativy

  • pyright – kontrolor od Microsoftu, rychlý, pohání Pylance ve VS Code.
  • Novější nástroje jako ty od Astralu nebo Pyrefly od Mety (oba zatím ve vývoji – ověřte si aktuální stav).

Pro začátek je mypy bezpečná volba s nejširší dokumentací. Když narazíte na nesrozumitelnou chybu typu „incompatible type“, vložte ji i s kódem do ColdHost AI v režimu Výuka – vysvětlení, proč mypy typ odvodil právě takhle, bývá rychlejší než hledání v issues.