PythonのImportErrorを即座に解消!「パッケージ名と同名のスクリプト名」による名前衝突の罠と回避策

venv環境で正しくライブラリをインストールしたはずなのに、謎のImportErrorが発生して開発が停止してしまう現場は少なくありません。その原因の多くはライブラリ名と自作スクリプト名の重複にあり、Pythonのインポート優先順位を理解することで根本解決が可能です。

背景:Pythonのインポート検索順序(sys.path

Pythonがモジュールを検索する際、sys.pathというリストの順番に従います。このリストの最初(sys.path[0])は、常に「実行したスクリプトが存在するディレクトリ」です。

今回のように asyncpg を使おうとして、自身のファイル名も asyncpg.py にしてしまっている場合、Pythonはvenv内の正規ライブラリではなく、自分自身をインポートしようとします。

その結果、自分自身(空、あるいはクラス定義中)の中に asyncpg という名前が見つからず、

cannot import name 'asyncpg' from 'asyncpg'

という循環参照に近いエラーが発生します。

現場での注意点とハマりどころ

  • 特に注意すべきは、ファイル名だけでなく「ディレクトリ名」もパッケージとして認識される点です。プロジェクトルートに asyncpg/ というフォルダを作ってしまうと同じ現象が起きます。
  • 一度実行して生成された __pycache__ 内に古い情報のキャッシュが残っている場合があるため、ファイル名を変更した後は必ずキャッシュディレクトリを削除するのが運用上の鉄則です。

解決のためのデバッグコード例

import sys
import os

# 1. どこからインポートされているかを確認する
try:
    import asyncpg
    print(f"Location: {asyncpg.__file__}")
except ImportError as e:
    print(f"Error: {e}")

# 2. 現在の検索パスの優先順位を表示
print("Search paths:")
for path in sys.path:
    print(f" - {path}")

# 解決策:ファイル名が asyncpg.py なら今すぐリネームしてください

解決策:ファイル名の変更とキャッシュの削除

  • 自作のスクリプトファイル名(例:asyncpg.py)を、インストールしたライブラリ名と重複しない別の名前(例:db_client.py)に変更してください。
  • ファイル名を変更した後は、__pycache__ ディレクトリや、.pyc ファイルを削除して、古いキャッシュをクリアすることを忘れないでください。

メリット:命名規則の統一によるデバッグ工数の削減

私の経験上、この問題の解決策をチームで共有し、命名規則(例:自作スクリプトには test_app_ などのプレフィックスを付ける)を徹底することで、環境構築時の「動かない」というトラブルをゼロにできます。これにより、シニアエンジニアがジュニア層の環境トラブル対応に時間を取られることがなくなり、開発サイクルを20%以上高速化することが可能です。

結論:ライブラリ名との衝突を避けることが安定稼働への近道

ImportError: cannot import name 'X' from 'X'」というエラーが出た際は、環境構築の失敗を疑う前に、まず自分の作成したファイル名を確認してください。

自作スクリプトにパッケージ名と同じ名前を付けないという基本を徹底するだけで、venvやDocker環境での「なぜか動かない」という不毛なトラブルの大部分は回避できます。

タイトルとURLをコピーしました