Skip to content
Konsultasi

Selftest Hijau, Lalu ImportError Gara-Gara Nama File

Adityo Guni Waluyo

File tool bernama keyword.py lolos selftest tapi bikin import collections gagal. sys.path dan import transitif jadi jebakan yang framework besar pun kena.

Ringkasan

Menamai file sama dengan modul stdlib bisa bikin impor transitif gagal diam-diam: selftest hijau, tapi begitu collections dipanggil, Python memuat file lokal yang tidak punya iskeyword. Penyebabnya sys.path menempatkan direktori skrip di urutan pertama. Solusinya: cek nama sebelum menamai file baru, plus flag -P sebagai lapisan isolasi tambahan.

Selftest Hijau, Command Berikutnya Merah

Saya punya file tool CLI di direktori tools, namanya keyword.py. Begitu saya jalanin selftest, hasilnya hijau, sukses. Script itu sendiri jalan normal. Tapi detik kemudian saya coba perintah lain di folder yang sama yang mengimpor collections, dan layar langsung merah:

ImportError: cannot import name 'iskeyword' from 'keyword' (consider renaming
'/path/tools/keyword.py' since it has the same name as the standard library module
named 'keyword' and prevents importing that standard library module)

Saya sempat bingung. Kenapa import keyword di dalam file itu sendiri sukses, tapi impor dari modul lain gagal? Dugaan pertama saya kode sendiri yang rusak. Ternyata jawabannya ada di urutan pencarian modul Python, dan petunjuknya sebenarnya udah ada di pesan error yang saya abaikan sambil panik.

Urutan sys.path dan Import Transitif

Python mencari modul lewat sys.path, dan entri pertamanya adalah direktori script yang dijalankan, atau current working directory kalo nggak ada file script [1]. Jadi begitu saya jalanin python3 tools/keyword.py, direktori tools otomatis jadi prioritas utama pencarian.

Lalu kenapa import keyword langsung di file itu sendiri nggak meledak? Setelah saya tes ulang, import langsung emang sukses memuat file lokal, dan startup Python juga nggak memuat modul keyword lebih dulu. Masalah baru muncul lewat jalur transitif. Modul collections di CPython 3.13 punya satu baris kunci di __init__.py-nya:

from keyword import iskeyword as _iskeyword

Begitu collections diimpor, dia mencari modul bernama keyword. Karena direktori tools ada di urutan pertama sys.path, yang ketemu adalah file lokal saya, bukan modul stdlib. File lokal itu nggak punya fungsi iskeyword, dan Python langsung menyerah dengan ImportError. Ini yang bikin masalah licik: script kelihatannya sehat, selftest hijau, padahal bomnya tinggal tunggu impor pertama ke collections.

Kabar baiknya, error Python versi terbaru udah cukup membantu. Pesannya secara eksplisit menyarankan rename file yang menabrak modul stdlib. Tapi saat mata sedang berdarah membaca traceback panjang, petunjuk segitu pentingnya gampang banget terlewat.

Flag -P, Kebiasaan Naming, dan Kasus Kedro

Solusi utama saya sekarang sederhana: jangan kasih nama file .py sama dengan modul stdlib. Nama-nama pendek umum kayak keyword, json, email, types, code, atau time semuanya udah dipakai nama modul bawaan. Kasih suffix spesifik sesuai fungsi tool-nya. Saya juga tambah kebiasaan baru, jalanin python3 -c "import namafile" sepuluh detik sebelum menggenapi nama file baru. Sepuluh detik itu jauh lebih murah daripada berjam-jam mengejar error yang menunjuk ke file yang salah.

Sejak Python 3.11 ada juga tameng tambahan: flag -P atau variabel lingkungan PYTHONSAFEPATH, yang bikin Python nggak menambahkan direktori script atau cwd ke awal sys.path [2]. Dengan flag itu di command line, yang dimuat tetap modul stdlib asli walaupun ada file lokal bernama sama. Berguna untuk CI/CD dan container produksi yang butuh isolasi ketat, tapi sebagai pengembang tool CLI sehari-hari saya tetap anggap ini lapisan kedua setelah kebiasaan naming.

Jebakan ini juga pernah menjatuhkan framework besar. Juni 2026, issue #5607 di repositori Kedro melaporkan kedro new --name=email sukses bikin project, tapi tiap kedro run meledak dengan ModuleNotFoundError yang arahnya jauh dari penyebab aslinya [4]. Package email pengguna menimpa modul stdlib email. Kedro menutupnya lewat validasi nama project di rilis 1.5.0, jadi nama yang menabrak modul bawaan kini ditolak di awal. Bahkan tim framework pun sempat lolos dari radar.

Dari pengalaman ini saya pegang satu hal: error paling mahal sering datang dari keputusan paling sepele, kayak memilih nama file. Pola kegagalan begini nggak ketahuan pas testing terisolasi dan baru muncul di kombinasi yang nggak diperkirakan. Makanya ngecek sepuluh detik itu saya jadikan kebiasaan, bukan sekadar pelajaran yang hilang besok paginya. Pola serupa juga berlaku luas, misalnya saat cron artikel saya ganti mesin, kontrol nama dan jalur pemuatan selalu jadi hal pertama yang saya cek.

Artikel terkait