Bab 17 — Environment dan Dependency: Satu Kamar Python untuk Tiap Proyek

Seri I1 — Kode yang Rapi dan Terawat

CatatanDi bab ini, Anda akan:
  • Memahami mengapa tiap proyek perlu environment (lingkungan Python) sendiri
  • Membuat dan memakai venv, memasang paket dengan pip, dan menyimpan daftarnya di requirements.txt
  • Membaca dan menulis pyproject.toml, berkas “kartu identitas” proyek
  • Mengenal uv (pengelola proyek generasi baru), poetry, dan Anaconda/conda, lengkap dengan catatan lisensi Anaconda
  • Memasang paket inventaris dari proyek bersambung di environment sendiri

Semua skrip bab ini ada di folder kode/bab17/. Di versi web, Anda juga bisa mengunduh semuanya sekaligus (zip).

Di Bab 16, proyek inventaris lahir sebagai kumpulan kelas. Mulai Bab 18, ia akan memakai pustaka luar (pytest, ruff). Di sinilah masalah klasik muncul. Proyek A butuh pandas versi lama, proyek B butuh yang baru. Bila keduanya dipasang di satu Python yang sama, salah satu rusak. Itu seperti dua petani yang berbagi satu gudang pupuk: begitu yang satu mengganti isinya, yang lain terganggu.

Solusinya environment (lingkungan): “kamar” Python terpisah untuk tiap proyek, lengkap dengan paketnya sendiri. Dependency (ketergantungan) adalah paket luar yang dibutuhkan proyek Anda.

Satu komputer, banyak environment: tiap proyek membawa paketnya sendiri.

venv: membuat kamar baru

venv adalah modul bawaan Python untuk membuat environment. Perintah di terminal: python -m venv .venv (nama .venv hanya kebiasaan). Skrip berikut membuatnya lewat kode dan memeriksa isinya.

01_buat_venv.py
# Bab 17 - Membuat venv: "kamar" Python khusus untuk satu proyek
import os
import shutil
import subprocess
import sys
import venv
from pathlib import Path

kerja = Path(__file__).parent / "_tmp"
shutil.rmtree(kerja, ignore_errors=True)
kerja.mkdir()
lokasi = kerja / "venv_contoh"

venv.create(lokasi, with_pip=True)          # sama dengan: python -m venv venv_contoh

folder_bin = lokasi / ("Scripts" if os.name == "nt" else "bin")
print("Isi folder venv:", sorted(p.name for p in lokasi.iterdir()))
print("Berkas penting ada:", [
    nama for nama in ("python", "pip", "activate")
    if any(p.stem == nama for p in folder_bin.iterdir())
])

cfg = (lokasi / "pyvenv.cfg").read_text(encoding="utf-8").splitlines()
print([b for b in cfg if b.startswith("include-system-site-packages")])

python_venv = folder_bin / ("python.exe" if os.name == "nt" else "python")
kode = "import sys; print(sys.prefix != sys.base_prefix)"
dalam = subprocess.run([python_venv, "-c", kode], capture_output=True, text=True).stdout.strip()
python_sistem = Path(sys.base_prefix) / ("python.exe" if os.name == "nt" else "bin/python3")
luar = subprocess.run([python_sistem, "-c", kode], capture_output=True, text=True).stdout.strip()
print("Python di dalam venv terpisah dari sistem?", dalam)
print("Python sistem (induk venv) terpisah?", luar)
Isi folder venv: ['Include', 'Lib', 'Scripts', 'pyvenv.cfg']
Berkas penting ada: ['python', 'pip', 'activate']
['include-system-site-packages = false']
Python di dalam venv terpisah dari sistem? True
Python sistem (induk venv) terpisah? False
  • Folder baru berisi Scripts (di Linux/macOS bernama bin), Lib (tempat paket disimpan), Include, dan pyvenv.cfg. Di Scripts ada python, pip, dan skrip activate.
  • include-system-site-packages = false berarti paket di Python sistem tidak ikut terlihat. Kamar ini benar-benar bersih.
  • Python di dalam venv melapor sys.prefix != sys.base_prefix = True: ia tahu dirinya berada di venv. Python sistem melapor False.

Untuk memakainya di terminal, aktifkan dulu. Aktivasi menaruh folder Scripts di depan jalur pencarian perintah, sehingga python dan pip yang dipanggil adalah milik venv. Menurut dokumentasi resmi Python (dibaca 2026-10-10):

Terminal Perintah aktivasi
Windows, cmd .venv\Scripts\activate.bat
Windows, PowerShell .venv\Scripts\Activate.ps1
Linux/macOS, bash/zsh source .venv/bin/activate

Untuk keluar, ketik deactivate. Aktivasi sifatnya opsional: Anda juga bisa memanggil langsung .venv\Scripts\python.exe, itulah yang dilakukan skrip-skrip di bab ini.

PeringatanAWAS

Jangan memindah atau menyalin folder venv ke tempat lain, dan jangan menyimpannya di git. Dokumentasi Python menjelaskan bahwa skrip di dalamnya memuat jalur absolut, jadi venv yang dipindah bisa rusak. Cara yang benar: buang, lalu buat ulang dari daftar paket (requirements.txt atau pyproject.toml). Python 3.13 ke atas bahkan otomatis menaruh .gitignore di dalam venv.

pip dan requirements.txt

pip adalah pemasang paket bawaan Python; paketnya diunduh dari PyPI (Python Package Index, gudang paket resmi). Skrip berikut membuktikan isolasi venv: paket requests dipasang di satu venv, lalu daftarnya dibekukan (pip freeze) ke requirements.txt dan dipakai membangun venv kedua.

02_isolasi_paket.py
# Bab 17 - pip di dalam venv: pasang, bekukan, pasang ulang dari requirements.txt
import os
import shutil
import subprocess
import venv
from pathlib import Path

kerja = Path(__file__).parent / "_tmp"
shutil.rmtree(kerja, ignore_errors=True)
kerja.mkdir()


def python_dari(lokasi):
    return lokasi / ("Scripts/python.exe" if os.name == "nt" else "bin/python")


def jalan(lokasi, *argumen):
    return subprocess.run([python_dari(lokasi), *argumen], capture_output=True, text=True)


venv_a = kerja / "venv_a"
venv.create(venv_a, with_pip=True)

hasil = jalan(venv_a, "-c", "import requests")
print("Sebelum dipasang:", hasil.stderr.strip().splitlines()[-1])

jalan(venv_a, "-m", "pip", "install", "--quiet", "--disable-pip-version-check", "requests")
hasil = jalan(venv_a, "-c", "import requests; print('berhasil diimpor')")
print("Sesudah dipasang:", hasil.stdout.strip())

beku = jalan(venv_a, "-m", "pip", "freeze").stdout
(kerja / "requirements.txt").write_text(beku, encoding="utf-8")
print("--- requirements.txt ---")
print(beku.strip())

venv_b = kerja / "venv_b"
venv.create(venv_b, with_pip=True)
jalan(venv_b, "-m", "pip", "install", "--quiet", "--disable-pip-version-check",
      "-r", str(kerja / "requirements.txt"))
beku_b = jalan(venv_b, "-m", "pip", "freeze").stdout
print("venv_b identik dengan venv_a?", beku_b == beku)
Sebelum dipasang: ModuleNotFoundError: No module named 'requests'
Sesudah dipasang: berhasil diimpor
--- requirements.txt ---
certifi==2026.7.22
charset-normalizer==3.5.2
idna==3.20
requests==2.34.2
urllib3==2.8.0
venv_b identik dengan venv_a? True

Kode ini dijalankan sungguhan satu kali oleh penulis, lalu keluarannya disimpan, karena butuh internet dan memuat nomor versi yang terus berubah. Jadi nomor versi di atas adalah keadaan pada saat buku ini ditulis; di komputer Anda akan berbeda.

Telusuri hasilnya:

  • Sebelum dipasang, import requests gagal dengan ModuleNotFoundError. Kamar baru memang kosong.
  • Sesudah pip install requests, impor berhasil.
  • pip freeze mencatat lima paket, bukan satu: requests membawa empat dependensi lain (certifi, charset-normalizer, idna, urllib3). Masing-masing dikunci pada nomor versi persis (==).
  • Venv kedua yang dibangun dari requirements.txt identik dengan yang pertama (True). Itulah gunanya berkas ini: rekan kerja atau server dapat membuat kamar yang sama.
TipTIPS

Pasang paket dengan python -m pip install ..., bukan hanya pip install .... Bentuk pertama memastikan pip yang dipakai adalah milik Python yang sedang Anda panggil. Itu menghindari kesalahan “terpasang di Python yang salah”.

pyproject.toml: kartu identitas proyek

requirements.txt hanya daftar paket. Proyek modern menyimpan semuanya dalam satu berkas, pyproject.toml: nama, versi, Python yang dibutuhkan, dependensi, dan pengaturan alat (pytest, ruff). Formatnya TOML: bagian ditulis [nama], isinya kunci = nilai. Ini berkas milik paket inventaris:

[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"

[project]
name = "inventaris"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []

[project.optional-dependencies]
dev = ["pytest", "ruff"]

[tool.ruff]
line-length = 88
  • [build-system] memberi tahu alat pemasang cara “membangun” paket (di sini memakai setuptools).
  • [project] memuat identitas proyek. dependencies adalah paket wajib (kosong: inventaris hanya memakai pustaka bawaan). optional-dependencies memuat kelompok tambahan, di sini dev untuk alat pengembang.
  • [tool.xxx] adalah ruang pengaturan untuk alat, seperti [tool.ruff] dan [tool.pytest.ini_options] (Bab 18).

Python 3.11 ke atas punya modul bawaan tomllib untuk membacanya:

03_baca_pyproject.py
# Bab 17 - Membaca pyproject.toml dengan tomllib (pustaka bawaan Python 3.11+)
import tomllib
from pathlib import Path

berkas = Path(__file__).parent / "proyek" / "pyproject.toml"
with open(berkas, "rb") as f:             # tomllib mewajibkan mode biner
    data = tomllib.load(f)

proyek = data["project"]
print("Nama proyek      :", proyek["name"])
print("Versi            :", proyek["version"])
print("Butuh Python     :", proyek["requires-python"])
print("Dependensi       :", proyek["dependencies"])
print("Dependensi dev   :", proyek["optional-dependencies"]["dev"])
print("Alat build       :", data["build-system"]["build-backend"])
print("Bagian [tool.*]  :", sorted(data["tool"]))
print("Panjang baris ruff:", data["tool"]["ruff"]["line-length"])
Nama proyek      : inventaris
Versi            : 0.1.0
Butuh Python     : >=3.12
Dependensi       : []
Dependensi dev   : ['pytest', 'ruff']
Alat build       : setuptools.build_meta
Bagian [tool.*]  : ['ruff', 'setuptools']
Panjang baris ruff: 88

Ingat: TOML dibaca sebagai dict biasa. data["project"]["name"] adalah dict di dalam dict (Bab 9).

uv: pengelola paket generasi baru

uv adalah pengelola paket dan proyek Python buatan Astral (pembuat ruff yang kita pakai di Bab 19). Ia melakukan pekerjaan venv + pip + kunci versi dalam satu perintah, dan sangat cepat. Berdasarkan dokumentasi resmi uv (dibaca 2026-10-10) dan percobaan di komputer penulis:

Perintah Fungsi
uv init membuat proyek baru (pyproject.toml, .python-version, main.py)
uv add paket menambah dependensi ke pyproject.toml, membuat .venv dan uv.lock
uv run perintah menjalankan perintah di environment proyek, memastikan environment mutakhir
uv lock / uv sync memperbarui berkas kunci / menyelaraskan environment dengan kunci
uv tree menampilkan pohon dependensi
uv venv, uv pip ... pengganti python -m venv dan pip yang kompatibel
04_uv_proyek_baru.py
# Bab 17 - uv: proyek baru dari nol (init, add, run, tree)
import shutil
import subprocess
from pathlib import Path

kerja = Path(__file__).parent / "_tmp" / "uv_demo"
shutil.rmtree(kerja, ignore_errors=True)
kerja.mkdir(parents=True)


def uv(*argumen):
    hasil = subprocess.run(["uv", *argumen], cwd=kerja, capture_output=True, text=True)
    return hasil.stdout.strip()


uv("init", "--name", "inventaris-demo", "--no-readme", "--vcs", "none", "--python", "3.12")
print("Berkas setelah uv init:", sorted(p.name for p in kerja.iterdir()))

uv("add", "requests")
print("Berkas setelah uv add :", sorted(p.name for p in kerja.iterdir()))

baris = (kerja / "pyproject.toml").read_text(encoding="utf-8").splitlines()
print("--- pyproject.toml (dependencies) ---")
print("\n".join(baris[baris.index("dependencies = [") : baris.index("]")+1]))

print("--- uv run ---")
print(uv("run", "python", "-c", "import requests; print('requests siap dipakai')"))

print("--- uv tree ---")
print(uv("tree"))
Berkas setelah uv init: ['.python-version', 'main.py', 'pyproject.toml']
Berkas setelah uv add : ['.python-version', '.venv', 'main.py', 'pyproject.toml', 'uv.lock']
--- pyproject.toml (dependencies) ---
dependencies = [
    "requests>=2.34.2",
]
--- uv run ---
requests siap dipakai
--- uv tree ---
inventaris-demo v0.1.0
└── requests v2.34.2
    ├── certifi v2026.7.22
    ├── charset-normalizer v3.5.2
    ├── idna v3.20
    └── urllib3 v2.8.0

Ini juga dijalankan sungguhan dan keluarannya disimpan (butuh internet dan memuat nomor versi). Perhatikan:

  • uv init hanya membuat tiga berkas. .venv dan uv.lock baru lahir ketika uv add dijalankan. uv.lock adalah berkas kunci berisi versi persis semua paket, dikelola uv dan tidak boleh disunting tangan (dokumentasi uv).
  • uv add requests menulis "requests>=2.34.2" ke pyproject.toml: batas bawah, bukan harga mati. Versi persis ada di uv.lock.
  • uv tree memperlihatkan pohonnya: requests di atas, empat dependensi di bawahnya, sama dengan hasil pip freeze tadi.
CatatanINGAT

Dua jenis daftar punya tugas berbeda. pyproject.toml menyatakan “paket apa yang saya butuhkan” (longgar: >=2.34.2). Berkas kunci (uv.lock, requirements.txt hasil freeze) menyatakan “versi persis yang terpasang” supaya semua orang mendapat hasil yang sama.

Proyek Bersambung I1: memasang inventaris

Sekarang paket inventaris dari Bab 16 dipasang di environment sendiri memakai uv. Opsi -e (editable) membuat Python membaca kode langsung dari folder proyek, jadi perubahan kode langsung terlihat tanpa memasang ulang.

05_pasang_proyek.py
# Bab 17 - Proyek bersambung I1: memasang paket inventaris di environment sendiri
import os
import shutil
import subprocess
from pathlib import Path

induk = Path(__file__).parent
kerja = induk / "_tmp" / "pasang"
shutil.rmtree(kerja, ignore_errors=True)
kerja.mkdir(parents=True)
salinan = kerja / "proyek"
shutil.copytree(induk / "proyek", salinan)

lingkungan = kerja / "venv_inventaris"
subprocess.run(["uv", "venv", str(lingkungan), "--quiet"], check=True)
python = lingkungan / ("Scripts/python.exe" if os.name == "nt" else "bin/python")

# -e = "editable": kode di folder proyek langsung terbaca tanpa memasang ulang
subprocess.run(["uv", "pip", "install", "--quiet", "--python", str(python), "-e", str(salinan)],
               check=True)

kode = """
from importlib.metadata import version
import inventaris
from inventaris.contoh import buat_contoh

print("Terpasang: inventaris", version("inventaris"))
from pathlib import Path
print("Kode dibaca dari folder proyek?", Path(inventaris.__file__).parent.parent.name == "proyek")
for unit in buat_contoh():
    print(unit.ringkasan())
"""
hasil = subprocess.run([python, "-c", kode], capture_output=True, text=True)
print(hasil.stdout.strip())
Terpasang: inventaris 0.1.0
Kode dibaca dari folder proyek? True
Plot hutan A: 3 catatan, 2.0 pohon sehat
Kebun Kopi: 2 catatan, 555.5 kg
Sawah Hilir: 1 catatan, 1250.0 kg (2500 kg/ha)
Kolam A: 1 catatan, 432.4 kg biomassa
Kandang 1: 3 catatan, 1151.5 kg bobot

Jalan ceritanya: salinan proyek ditaruh di _tmp/, uv venv membuat kamar kosong, uv pip install -e memasang paket (uv mengunduh alat build setuptools, itulah sebabnya butuh internet, dan keluarannya disimpan dari satu kali jalan). Lalu di dalam kamar itu inventaris bisa diimpor dari mana saja dan hasilnya sama persis dengan Bab 16: plot hutan A, kebun kopi, sawah hilir, kolam, dan kandang.

Poetry: pesaing uv

poetry adalah pengelola proyek Python yang lebih dulu populer; ia juga memakai pyproject.toml dan membuat berkas kunci poetry.lock. Dari dokumentasi resmi poetry (dibaca 2026-10-10): poetry new membuat folder proyek, poetry add menambah dependensi dan memasangnya, poetry install memasang semua dependensi, dan poetry run menjalankan perintah di environment proyek. Dependensi ditulis di project.dependencies (standar PEP 621); poetry versi lama memakai tool.poetry.dependencies.

07_poetry.py
# Bab 17 - Alur dasar poetry (hanya contoh; tidak dijalankan saat buku dibuat)
import subprocess

perintah = [
    ["poetry", "new", "inventaris-poetry"],   # membuat folder proyek baru
    ["poetry", "add", "requests"],            # menambah dependensi + mengunci versinya (poetry.lock)
    ["poetry", "install"],                    # memasang semua dependensi proyek
    ["poetry", "run", "pytest"],              # menjalankan perintah di environment proyek
]
for p in perintah:
    print("$", " ".join(p))
    subprocess.run(p, check=True)

Kode ini tidak dijalankan saat buku dibuat karena poetry belum terpasang di komputer penulis (lihat hasil 06_cek_alat.py di bawah), jadi keluarannya tidak ditampilkan. Perintahnya dicocokkan dengan dokumentasi resmi, tetapi belum diuji langsung.

Anaconda dan conda

Anaconda adalah cara lain memasang dan mengelola Python, populer di dunia data science. Ada tiga istilah yang sering tertukar:

  • conda: alat baris perintah untuk membuat environment dan memasang paket. Dokumentasinya menyebut conda mengelola “paket, dependensi, dan environment untuk bahasa apa pun”, jadi bukan hanya paket Python.
  • Anaconda Distribution: paket pemasang yang membawa conda, Python, Anaconda Navigator (aplikasi berjendela untuk membuat environment dan membuka alat tanpa mengetik perintah), dan 600+ paket sains data siap pakai, sekitar 9,7 GB.
  • Miniconda: versi ringkas: conda, Python, 130+ paket, tanpa Navigator, sekitar 900 MB.

(Angka ukuran dari halaman resmi Anaconda, dibaca 2026-10-10.)

Bedanya dengan python.org: pemasang python.org hanya memberi Python; selebihnya Anda urus dengan venv dan pip. Anaconda memberi Python plus perangkat pengelola environment dan banyak paket sekaligus. Paketnya diambil dari channel (saluran) conda, bukan dari PyPI.

Alurnya di terminal (dari dokumentasi resmi conda, dibaca 2026-10-10):

conda create --name inventaris python numpy    # buat environment berisi Python dan numpy
conda activate inventaris                      # masuk ke environment
conda install --name inventaris matplotlib     # pasang paket lain
conda info --envs                              # daftar environment
conda deactivate                               # keluar
08_conda.py
# Catatan: "conda activate inventaris" diketik langsung di terminal, bukan lewat skrip.
# Bab 17 - Alur dasar conda (hanya contoh; tidak dijalankan saat buku dibuat)
import subprocess

perintah = [
    ["conda", "create", "--name", "inventaris", "python", "numpy"],   # membuat environment + isinya
    ["conda", "install", "--name", "inventaris", "numpy"],        # memasang paket
    ["conda", "info", "--envs"],                                  # daftar environment
]
for p in perintah:
    print("$", " ".join(p))
    subprocess.run(p, check=True)

Kode ini tidak dijalankan saat buku dibuat karena conda belum terpasang di komputer penulis, jadi keluarannya tidak ditampilkan dan seluruh bagian conda di bab ini belum diuji langsung. (conda activate sengaja tidak ada dalam skrip: ia diketik di terminal.)

06_cek_alat.py
# Bab 17 - Memeriksa alat apa saja yang ada di komputer
import shutil

for alat in ["python", "pip", "uv", "git", "poetry", "conda"]:
    jalur = shutil.which(alat)
    print(f"{alat:7}", "ada" if jalur else "TIDAK ada")
python  ada
pip     ada
uv      ada
git     ada
poetry  TIDAK ada
conda   TIDAK ada

Keluaran ini diambil sekali di komputer penulis dan berbeda bila dijalankan di komputer Anda. Di sini uv dan git ada, poetry dan conda tidak.

conda vs pip: pip memasang dari PyPI, conda dari channel conda. Dokumentasi conda menyarankan: bila perlu keduanya di satu environment, pasang sebanyak mungkin dengan conda dulu, baru pip (“Use pip only after conda”). conda-forge adalah channel yang dijalankan komunitas, terpisah dari channel defaults milik Anaconda, Inc. Dokumentasi conda-forge menyarankan Miniforge sebagai cara termudah memulainya.

Jupyter: halaman resmi Anaconda menyebut Jupyter Notebook dapat dibuka dari Navigator. (Halaman itu tidak merinci apakah Jupyter terpasang bawaan; periksa setelah memasang.)

PeringatanAWAS

Lisensi Anaconda. Anaconda tidak gratis untuk semua orang. Menurut Ketentuan Layanan Anaconda (https://www.anaconda.com/legal/terms/terms-of-service, tanggal berlaku tertulis 15 Juli 2025, dibaca 2026-10-10), penggunaan platform gratis bila Anda: (1) individu untuk keperluan pribadi nonkomersial, (2) terkait lembaga akademik yang memenuhi syarat, (3) terkait organisasi nirlaba dan riset yang memenuhi syarat, atau (4) untuk organisasi berorientasi laba dengan 200 karyawan/kontraktor atau kurang (termasuk afiliasi). Organisasi berorientasi laba dengan lebih dari 200 karyawan/kontraktor yang tidak termasuk kategori gratis harus berlangganan paket Business. Halaman harga (https://www.anaconda.com/pricing, dibaca 2026-10-10) menulis “200+” dan menyebut paket Free untuk yang belajar Python. Anaconda berhak meminta bukti kelayakan. Syarat ini bisa berubah, jadi baca halaman resminya sendiri sebelum memakai Anaconda di tempat kerja. Penulis tidak memeriksa apakah syarat itu berlaku bagi channel conda-forge; dokumen ketentuan tidak menyebutnya.

Kapan memilih yang mana? Rekomendasi penulis untuk pembaca buku ini: untuk proyek pengembangan umum (aplikasi, otomasi), venv + pip atau uv sudah cukup, ringan, dan tanpa urusan lisensi. Pertimbangkan Anaconda/conda bila Anda bekerja dengan pustaka sains yang sulit dipasang dengan pip, atau bila tim Anda sudah memakainya. Di tempat kerja, periksa dulu ketentuan lisensi di atas.

Pada Windows, PowerShell bisa menolak Activate.ps1 karena kebijakan eksekusi skrip. Dokumentasi Python menyarankan Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser. Ini mengubah pengaturan keamanan akun Anda sendiri, jadi lakukan hanya bila paham akibatnya; alternatifnya, panggil .venv\Scripts\python.exe langsung tanpa aktivasi.

Latihan

  1. Di terminal, buat venv latihan_venv dengan python -m venv latihan_venv, aktifkan, lalu ketik python -c "import sys; print(sys.prefix)". Bandingkan dengan hasil tanpa aktivasi.
  2. Pasang six (paket kecil) di venv itu dengan python -m pip install six, lalu simpan python -m pip freeze > requirements.txt dan lihat isinya.
  3. Ubah 03_baca_pyproject.py agar mencetak juga daftar dev, satu paket per baris.
  4. Tantangan: dengan uv, buat proyek baru (uv init), tambahkan pytest sebagai dependensi pengembangan (uv add --dev pytest; periksa uv add --help), lalu jalankan uv run pytest --version.

Ringkasan Bab

  • Environment = kamar Python terpisah per proyek; dependency = paket luar yang dibutuhkan.
  • venv membuat environment; aktivasi opsional; jangan dipindah atau dimasukkan ke git, cukup dibuat ulang.
  • pip memasang dari PyPI; pip freeze menghasilkan requirements.txt berisi versi persis.
  • pyproject.toml menyimpan identitas proyek, dependensi, dan pengaturan alat; dibaca dengan tomllib.
  • uv menggabungkan venv, pip, dan berkas kunci (uv.lock) dengan cepat. poetry adalah pesaingnya (tidak diuji di sini).
  • Anaconda/conda punya kegunaan dan lisensi sendiri; baca ketentuan resminya sebelum dipakai di tempat kerja. Bagian conda di buku ini belum diuji langsung.

Selanjutnya, di Bab 18: testing dasar dengan pytest, cara membuat kode yang memeriksa kode Anda sendiri.