Hampir setiap program serius membaca konfigurasi dari luar kode: alamat database, batas retry, mode debug. Selama bertahun-tahun ekosistem Python terpecah antara INI, JSON, dan YAML — sampai komunitas bertemu TOML dan menjadikannya standar de facto lewat pyproject.toml. Python 3.11 akhirnya menyertakan pembaca TOML di standard library: module tomllib. Pada Chapter ini kita akan membaca file TOML dengan tomllib, memetakan sintaks TOML yang wajib dikenal, dan memilih format konfigurasi secara sadar.
Parsing dengan load dan loads #
Module tomllib menyediakan dua pintu: loads() untuk string TOML dan load() untuk file biner. Hasil keduanya adalah struktur Python biasa — dictionary, list, string, angka, boolean, serta tipe tanggal:
import tomllib
toml_teks = """
judul = "konfigurasi layanan"
diluncurkan = 2025-06-15T10:30:00Z
[server]
host = "db.example.com"
port = 5432
aktif = true
tag = ["produksi", "utama"]
[server.pemilik]
nama = "Budi"
email = "[email protected]"
"""
data = tomllib.loads(toml_teks)
print(data["judul"])
print(data["diluncurkan"])
print(data["server"]["host"], "port", data["server"]["port"])
print(data["server"]["tag"])
print(data["server"]["pemilik"]["nama"])Output yang Dihasilkan:
konfigurasi layanan
2025-06-15 10:30:00+00:00
db.example.com port 5432
['produksi', 'utama']
BudiMari kita bedah pemetaan yang dilakukan parser tomllib:
- Baris
judul = "...": pasangan kunci-nilai sebelum header tabel apa pun menjadi item pada dictionary paling atas. - Baris
diluncurkan = 2025-06-15T10:30:00Z: TOML memiliki tipe datetime asli; parser mengembalikan objekdatetimedari moduledatetimeyang sadar zona waktu (+00:00menandakan UTC), bukan string. - Baris
[server]: header tabel membuat sub-dictionarydata["server"]; pasangan di bawahnya menjadi anggota tabel tersebut. - Baris
[server.pemilik]: header bertitik membuat tabel bersarangdata["server"]["pemilik"]tanpa perlu deklarasi[server]terpisah — keduanya bisa hadir berurutan seperti contoh.
Esensi sintaks TOML dirangkum pada tabel berikut:
| Elemen TOML | Sintaks | Hasil di Python |
|---|---|---|
| Pasangan kunci-nilai | port = 5432 | {"port": 5432} |
| Tabel | [server] | {"server": {...}} |
| Tabel bersarang | [server.pemilik] | dict di dalam dict |
| Array | tag = ["produksi", "utama"] | list |
| Inline table | titik = {x = 1, y = 2} | dict satu baris |
| Array of tables | [[produk]] | list berisi dict |
| Tanggal | diluncurkan = 2025-06-15 | datetime.date / datetime |
| Boolean | aktif = true | True (huruf kecil) |
Membaca File Konfigurasi Nyata #
Untuk file di disk, gunakan tomllib.load() dengan mode biner — load() menolak mode teks karena parser tomllib membaca bytes:
import tomllib
from pathlib import Path
isi_toml = """
[aplikasi]
nama = "kasir"
versi = "1.2.0"
[pengguna]
max_login = 3
"""
path = Path("konfigurasi.toml")
path.write_text(isi_toml, encoding="utf-8")
with open(path, "rb") as berkas: # tomllib.load wajib mode biner
data = tomllib.load(berkas)
print(data["aplikasi"]["nama"], "versi", data["aplikasi"]["versi"])
print("maksimum login:", data["pengguna"]["max_login"])
path.unlink()Output yang Dihasilkan:
kasir versi 1.2.0
maksimum login: 3Skrip di atas menulis file konfigurasi lebih dulu agar contoh berdiri sendiri; pada proyek nyata, file konfigurasi.toml sudah ada di disk dan kita cukup membacanya. Galat pada file (tipe tidak cocok, kurung tidak seimbang) dinaikkan sebagai tomllib.TOMLDecodeError — subclass ValueError — sehingga bisa ditangkap dengan pola try/except biasa dari Chapter Memahami Exceptions.
pyproject.toml sebagai Contoh Unggulan #
Sekarang kita lihat mengapa TOML menang: file pyproject.toml yang sama rapi dibaca oleh pip dan tool lain. Contoh metadata package berikut (topik lengkapnya ada pada Chapter pyproject.toml) menunjukkan campuran skenario nyata — tabel bertingkat dan array string:
import tomllib
pyproject = """
[project]
name = "alat-kasir"
version = "0.3.1"
requires-python = ">=3.12"
dependencies = ["httpx", "rich"]
[tool.ruff]
line-length = 100
"""
meta = tomllib.loads(pyproject)
print(meta["project"]["name"], meta["project"]["version"])
print("butuh Python", meta["project"]["requires-python"])
print("dependensi:", meta["project"]["dependencies"])
print("ruff line-length:", meta["tool"]["ruff"]["line-length"])Output yang Dihasilkan:
alat-kasir 0.3.1
butuh Python >=3.12
dependensi: ['httpx', 'rich']
ruff line-length: 100Konvensi [tool.<nama>] pada pyproject.toml memberi setiap tool tabel konfigurasinya sendiri; tomllib membaca semuanya sebagai dictionary biasa tanpa kejutan.
TOML vs JSON vs YAML vs INI #
| Aspek | TOML | JSON | YAML | INI (configparser) |
|---|---|---|---|---|
| Komentar | Ya (#) | Tidak | Ya | Ya |
| Tipe data | Lengkap (tanggal, array, inline table) | Lengkap, tanpa komentar | Lengkap, plus jangkar | Semua string |
| Kesalahan umum | Kurung tidak seimbang | Koma/kutip terlupakan | Indentasi, implicit typing (no → False) | Struktur datar |
| Edit manual | Nyaman | Kurang nyaman | Nyaman, rawan silap | Nyaman, terbatas |
| Writer stdlib | Tidak | Ya (json.dump) | Tidak | Ya (configparser.write) |