Chapter pyproject.toml pada Section Virtual Environments dan Dependencies sudah memperkenalkan berkas ini sebagai tempat mendeklarasikan dependencies. Untuk project yang benar-benar dikemas dan dideploy, tabel [project] perlu diisi lebih serius: nama, versi, penulis, sampai kelompok dependencies opsional. Metadata yang lengkap menentukan bagaimana package tampil di PyPI dan bagaimana tool build memperlakukan project kita. Chapter ini membedah satu per satu.
Anatomi Tabel [project] #
Berikut contoh pyproject.toml utuh untuk project toko-api:
[build-system]
requires = ["setuptools>=77"]
build-backend = "setuptools.build_meta"
[project]
name = "toko-api"
version = "1.4.0"
description = "API manajemen produk toko buku"
readme = "README.md"
requires-python = ">=3.10"
license = "MIT"
license-files = ["LICENSE"]
authors = [
{ name = "Budi Santoso", email = "[email protected]" },
]
keywords = ["api", "toko", "fastapi"]
classifiers = [
"Programming Language :: Python :: 3",
"Operating System :: OS Independent",
]
[project.urls]
Homepage = "https://example.com/toko-api"
Documentation = "https://docs.example.com/toko-api"
Changelog = "https://example.com/toko-api/changelog"Mari kita telaah baris-baris penting pada tabel [project]:
name: distribution name sesuai konvensi kebab-case dari chapter sebelumnya; nama inilah yang diketik pengguna saatpip install toko-api.version: versi rilis; lompatan angka mengikuti semantic versioning (major.minor.patch).description: satu kalimat ringkas — muncul di hasil pencarian PyPI.readme: berkas yang isinya di-render sebagai halaman depan package di PyPI.requires-python = ">=3.10": pip menolak instalasi bila interpreter pengguna lebih tua dari batas ini — cara termurah mencegah laporan galat aneh.license = "MIT"danlicense-files: ekspresi SPDX modern; hindari bentuk tabellicense = { text = "MIT" }yang kini usang.authors: array of table — boleh berisi lebih dari satu penulis.classifiers: label taxonomi PyPI untuk memudahkan pencarian (dibahas pada Chapter Build System dan Package Metadata).[project.urls]: tautan tambahan yang tampil di bilah samping halaman PyPI.
dependencies versus optional-dependencies #
Kunci dependencies berisi paket yang selalu dibutuhkan; optional-dependencies mendefinisikan extras — kelompok paket opsional yang dipasang hanya bila diminta:
dependencies = [
"fastapi>=0.110",
"httpx>=0.27",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0",
"ruff>=0.4",
]Pengguna memilih extras dengan sintaks kurung siku setelah nama package:
pip install toko-api
pip install "toko-api[dev]"Perintah pertama hanya memasang fastapi dan httpx; perintah kedua menambahkan pytest dan ruff. Karena TOML hanyalah data, kita bisa memverifikasi struktur berkas ini dengan module tomllib (hadir di Python 3.11):
import tomllib
with open("pyproject.toml", "rb") as berkas:
data = tomllib.load(berkas)
print(data["project"]["name"])
print(data["project"]["dependencies"])
print(data["project"]["optional-dependencies"]["dev"])Output yang Dihasilkan:
toko-api
['fastapi>=0.110', 'httpx>=0.27']
['pytest>=8.0', 'ruff>=0.4']Contoh di atas diuji dengan berkas berisi kedua tabel dependencies tersebut — nilai tercetak sebagai list Python, membuktikan TOML berhasil terurai.
Versi Dinamis dengan setuptools-scm #
Menyimpan versi di dua tempat (tag Git dan pyproject.toml) mengundang ketidaksesuaian. Plugin setuptools-scm menyelesaikannya dengan membaca versi dari tag Git saat build berlangsung. Deklarasinya: hapus kunci version, lalu nyatakan versi sebagai dinamis:
[project]
name = "toko-api"
dynamic = ["version"]
[tool.setuptools_scm]Dengan konfigurasi tersebut, angka versi mengalir dari git tag v1.4.0 ke metadata package secara otomatis — praktik yang umum pada project dengan rilis terjadwal. Sebaliknya, project yang masih awam terhadap Git tag atau dirilis manual cukup memakai kunci version statis; keduanya sah, yang penting jangan mencampurnya sekaligus.
Jebakan Sintaks TOML #
TOML terasa ringan, tetapi ada dua jebakan yang sering menjatuhkan pemula. Pertama, array multi-baris tetap memerlukan koma di antara elemennya — tanda kutip di akhir baris tanpa koma membuat parser menelan elemen berikutnya sebagai string lanjutan hingga gagal:
import tomllib
isi = """
dependencies = [
"fastapi>=0.110"
"httpx>=0.27"
]
"""
try:
tomllib.loads(isi)
except tomllib.TOMLDecodeError as galat:
print(galat)Output yang Dihasilkan:
Unclosed array (at line 4, column 5)Kedua, TOML bersifat case-sensitive pada nama kunci: Version = "1.0" tidak sama dengan version = "1.0" dan tool build tidak membacanya. Nilai boolean juga harus huruf kecil (true/false), bukan True gaya Python.
Setelah metadata terisi, pertanyaan berikutnya adalah bagaimana tool build tahu cara membangun project ini — tugas tabel [build-system] yang kita bedah pada chapter berikutnya.