7 November 2026•baca 5 menit

venv Python: Instalasi yang Masuk ke Python yang Salah

pip install mencetak Successfully installed, lalu jalan berikutnya melempar ModuleNotFoundError di mesin yang sama. Dua interpreter, satu instalasi, dan variabel yang skripmu periksa justru tidak pernah dipasang oleh interpreter.

Baca dalam bahasa Inggris

Instalasinya mencetak "Successfully installed". Skripnya berjalan normal di satu terminal. Lalu tombol Run di editor, atau shell baru, melempar ModuleNotFoundError untuk package yang baru saja kamu pasang, di mesin yang sama dan di proyek yang sama.

Kamu punya dua interpreter di satu mesin, yaitu interpreter sistem dan venv proyekmu, dan pip install hanya menyentuh interpreter yang menjalankannya.

Ini versi yang sudah diukur, di Linux dengan Python 3.14.9 pada 2026-11-07. Modul venv sudah bawaan Python, jadi tidak ada yang perlu dipasang lebih dulu (dokumentasi venv).

python3 -m venv .venv menulis venv ke dalam .venv/. Mengaktifkannya adalah perubahan pada shell: source .venv/bin/activate di macOS dan Linux, .venv\Scripts\activate di Windows. Setelah itu, python dan pip berarti yang ada di venv. Aktivasi itu praktis, bukan wajib, karena .venv/bin/python adalah interpreter yang sama tanpa aktivasi.

BASH
$ python3 --version
Python 3.14.9
$ python3 -m venv .venv
$ .venv/bin/pip install requests

Baris terakhir dari output instalasi:

TEXT
Successfully installed certifi-2026.10.23 charset_normalizer-3.5.2 idna-3.20 requests-2.34.2 urllib3-2.8.0

Satu pip install requests menarik lima package, dan du -sh .venv melaporkan 9.3M. Sekarang jalankan probe satu baris yang sama dengan masing-masing interpreter, di mesin yang sama pada detik yang sama:

CONSOLE
$ .venv/bin/python -c "import requests; print(requests.__version__)"
2.34.2
$ python3 -c "import requests; print(requests.__version__)"
ModuleNotFoundError: No module named 'requests'

Yang pertama berakhir dengan exit code 0. Yang kedua berakhir dengan exit code 1. Instalasinya tidak salah. Kamu bertanya ke Python yang lain.

Bug yang benar-benar akan kamu temui muncul berikutnya. Untuk mengetahui Python mana yang sedang jalan, banyak skrip membaca variabel shell VIRTUAL_ENV, yang hanya ada selama venv diaktifkan. Begini hasilnya.

Poin Penting

  • pip install hanya menyentuh interpreter yang menjalankannya, jadi proyek dengan venv punya dua Python dan paketnya mendarat di salah satunya.
  • VIRTUAL_ENV dipasang oleh aktivasi, bukan oleh interpreter, jadi .venv/bin/python where.py tetap melaporkan system.
  • sys.prefix != sys.base_prefix adalah pertanyaan yang harus kamu ajukan ke interpreter itu sendiri, karena nilainya benar tepat ketika venv yang menjalankannya.
  • Checker-nya menguji interpreter mana yang sedang jalan, bukan apakah versi dependensimu sudah benar, dan ia tidak bisa melihat interpreter yang dipakai editor.

Dua file, satu perintah

Simpan ini sebagai where.py. Ia memutuskan dengan membaca environment, dan hanya keluar dengan 0 kalau ia yakin sedang berada di venv.

PYTHON
# where.py
import os
import sys


def which_interpreter():
    if os.environ.get("VIRTUAL_ENV"):
        return "venv"
    return "system"


def main():
    kind = which_interpreter()
    print(kind)
    return 0 if kind == "venv" else 1


raise SystemExit(main())

Simpan ini di sebelahnya sebagai check_where.py. Ia membuat venv sekali pakai, menjalankan where.py dengan python milik venv dan dengan python sistem, lalu menghitung berapa yang lolos.

PYTHON
# check_where.py
import os
import subprocess
import sys
import tempfile

passed = 0
total = 0


def check(name, ok, detail=""):
    global passed, total
    total += 1
    if ok:
        passed += 1
        print(f"PASS  {name}")
    else:
        print(f"FAIL  {name}  <- {detail}")


root = os.path.dirname(os.path.abspath(__file__))
script = os.path.join(root, "where.py")

home = tempfile.mkdtemp(prefix="venvcheck-")
venv_dir = os.path.join(home, ".venv")
subprocess.run([sys.executable, "-m", "venv", venv_dir], check=True)
bindir = "Scripts" if os.name == "nt" else "bin"
venv_python = os.path.join(venv_dir, bindir, "python" + (".exe" if os.name == "nt" else ""))

inside = subprocess.run([venv_python, script], capture_output=True, text=True)
outside = subprocess.run([sys.executable, script], capture_output=True, text=True)

check("where.py runs when a venv calls it", inside.returncode == 0, f"exit {inside.returncode}")
check("a venv interpreter reports venv", inside.stdout.strip() == "venv", repr(inside.stdout.strip()))
check(
    "the system interpreter reports system",
    outside.returncode == 1 and outside.stdout.strip() == "system",
    f"exit {outside.returncode}, said {outside.stdout.strip()!r}",
)

print()
print(f"{passed} of {total} checks passed")
raise SystemExit(0 if passed == total else 1)

Jalankan python3 check_where.py. Hasilnya exit 1:

TEXT
FAIL  where.py runs when a venv calls it  <- exit 1
FAIL  a venv interpreter reports venv  <- 'system'
PASS  the system interpreter reports system

1 of 3 checks passed

Python milik venv sendiri yang menjalankan skripnya, dan ia tetap menjawab system. source .venv/bin/activate mengubah shell-mu sehingga python berarti venv. Memanggil .venv/bin/python langsung tidak pernah menyentuh variabel shell itu, jadi VIRTUAL_ENV kosong. Skripnya bertanya ke shell, dan shell tidak pernah diberi tahu.

Tanyakan ke interpreter saja. Di dalam venv, sys.prefix menunjuk ke venv dan sys.base_prefix menunjuk ke Python tempat venv itu dibuat. Ganti where.py dengan:

PYTHON
# where.py
import sys


def inside_venv():
    return sys.prefix != sys.base_prefix


def main():
    kind = "venv" if inside_venv() else "system"
    print(kind)
    return 0 if kind == "venv" else 1


raise SystemExit(main())

Jalankan python3 check_where.py lagi. Hasilnya exit 0:

TEXT
PASS  where.py runs when a venv calls it
PASS  a venv interpreter reports venv
PASS  the system interpreter reports system

3 of 3 checks passed

Yang tidak diperiksa

Checker-nya menguji interpreter mana yang sedang jalan. Ia tidak menguji apakah dependensimu sudah yang benar, dan ia tidak mengunci versi. Ia juga tidak bisa melihat interpreter yang dikonfigurasi di editormu, jadi tombol Run tetap butuh pengecekan sendiri.

Saya hanya menjalankannya di Linux. Cabang Windows di checker (Scripts, python.exe) ada supaya kamu coba sendiri, dan saya tidak memverifikasinya.

Satu jebakan lagi: pip freeze di venv yang baru dibuat tidak mencetak apa-apa. File requirements yang kosong bukan bukti bahwa instalasinya rusak. Setelah instalasi requests di atas, pip freeze mencetak persis ini:

TEXT
certifi==2026.10.23
charset-normalizer==3.5.2
idna==3.20
requests==2.34.2
urllib3==2.8.0

Jalankan checker dari dalam venv

Sekarang jalankan checker yang sama dengan interpreter milik venv: .venv/bin/python check_where.py. Satu pengecekan gagal, dan exit code-nya 1:

TEXT
PASS  where.py runs when a venv calls it
PASS  a venv interpreter reports venv
FAIL  the system interpreter reports system  <- exit 0, said 'venv'

2 of 3 checks passed

Checker membandingkan dengan sys.executable. Pada run ini isinya python milik venv, jadi "interpreter sistem" tidak pernah benar-benar diuji.

Sebelum kamu men-debug import error berikutnya, cetak sys.executable dari skrip yang gagal. Python yang mana itu, dan apakah itu yang kamu pasangi package?

Biar makin jago ngoding.

Yuk gabung bareng temen-temen developer lainnya buat dapet update teknologi, tips, dan tutorial santai tiap minggu.

Biar Nggak Kudet

Update teknologi, tips ngoding, dan insight santai langsung ke email kamu tiap minggu.

Santai, anti spam. Bisa berhenti langganan kapan aja.

Baca Selanjutnya

Lihat semua
Struktur DataTentang Struktur Data LinkedList

Linked list adalah rantai linear berisi node, dan setiap node menyimpan data plus pointer ke node berikutnya. Ini bentuk rantainya, ongkosnya dibanding array, dan implementasi paling sederhana dalam Java, Python, serta JavaScript.

Untuk developer yang belajar dari kesulitan

© 2026 Inva.dev.