โ† Semua pembelajaran / Python untuk AI Engineer
Fase 0 ยท Setup Toolchain

mypy

mypy memeriksa kecocokan tipe tanpa menjalankan kode. Ini pemasangan dan konfigurasi awal yang perlu kamu siapkan.

Intisari

  • mypy membaca type hint dan menemukan bug sebelum kode dijalankan โ€” tidak ada dampak ke runtime.
  • Type hint di Python bersifat opsional dan tidak dicek saat program jalan. mypy-lah yang mengeceknya.
  • Jalankan dengan uvx mypy . โ€” tidak perlu ditambahkan sebagai dependency proyek.
  • Mulai dari mode longgar, naikkan ketat secara bertahap. Jangan langsung --strict di hari pertama.
  • Yang paling sering ditangkap: None yang tidak diperiksa, salah tipe argumen, dan atribut yang tidak ada.

Apa yang sebenarnya dilakukan mypy

Python tidak memeriksa type hint saat program berjalan. Kode ini jalan mulus sampai meledak di baris ketiga:

def sapa(nama: str) -> str:
    return "Halo " + nama

sapa(42)   # Python: diam saja sampai runtime โ†’ TypeError

mypy membaca file yang sama tanpa menjalankannya, dan langsung melapor:

error: Argument 1 to "sapa" has incompatible type "int"; expected "str"  [arg-type]

Jadi type hint punya dua konsumen berbeda:

Pemakaian

uvx mypy .                  # cek seluruh proyek
uvx mypy src/               # satu folder
uvx mypy src/llm.py         # satu file

Pakai uvx, bukan uv add --dev mypy. mypy adalah tool, bukan sesuatu yang kodemu impor. Kecuali kamu butuh versinya terkunci untuk CI โ€” baru masukkan ke grup dev.

Konfigurasi bertahap

Taruh di pyproject.toml. Mulai dari sini:

Tahap 1 โ€” sekarang (Fase 0โ€“1)

[tool.mypy]
python_version = "3.13"
warn_unused_ignores = true
warn_redundant_casts = true

Ringan. Hanya mengecek kode yang sudah punya type hint, tidak memaksa apa-apa.

Tahap 2 โ€” mulai Fase 2

[tool.mypy]
python_version = "3.13"
strict = true

[[tool.mypy.overrides]]
module = ["chromadb.*", "beberapa_lib_tanpa_stub.*"]
ignore_missing_imports = true

strict = true menyalakan sekitar sepuluh flag sekaligus โ€” yang terpenting: fungsi tanpa anotasi jadi error, dan Any implisit tidak diizinkan. Blok overrides diperlukan karena beberapa library pihak ketiga belum menyertakan informasi tipe; tanpa itu mypy akan mengeluh soal import.

Tiga error yang paling sering muncul

1. Nilai bisa None tapi tidak diperiksa

def cari(id: str) -> Dokumen | None: ...

d = cari("abc")
print(d.judul)   # error: Item "None" of "Dokumen | None" has no attribute "judul"

Perbaikannya adalah memeriksanya โ€” dan itu memang bug nyata yang baru saja dicegah:

d = cari("abc")
if d is None:
    raise DokumenTidakDitemukan("abc")
print(d.judul)   # aman: mypy tahu d pasti Dokumen di sini

2. Fungsi tanpa anotasi (mode strict)

error: Function is missing a type annotation  [no-untyped-def]

Tambahkan anotasi. Untuk fungsi yang tidak mengembalikan apa-apa, tulis -> None secara eksplisit.

3. Library tanpa informasi tipe

error: Skipping analyzing "chromadb": module is installed, but missing library stubs

Dua kemungkinan solusi:

uv add --dev types-requests    # kalau ada paket stub resminya
# kalau tidak ada โ€” daftarkan di overrides seperti contoh Tahap 2 di atas

Kabur dari mypy (seperlunya)

hasil = fungsi_aneh()  # type: ignore[no-any-return]

from typing import cast
x = cast(Dokumen, data_mentah)   # "percaya saja, ini Dokumen"

Selalu sertakan kode errornya di dalam kurung siku. # type: ignore polos mematikan semua pengecekan di baris itu โ€” termasuk error baru yang muncul nanti karena perubahan yang tidak kamu sadari. Flag warn_unused_ignores akan memberi tahu kalau ada ignore yang sudah tidak diperlukan.

Di CI

uvx mypy . --no-error-summary   # exit code non-nol kalau ada error

Yang perlu diingat

Di Fase 0 kamu cukup memasang mypy dan tahu cara menjalankannya. Type hint yang sebenarnya โ€” sintaks modern, generic, Protocol, Literal โ€” dibahas tuntas di Fase 2. Checkpoint fase itu adalah uvx mypy . lolos tanpa error.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.