【Python】import名とインストール名が違う?パッケージ情報を正しく確認する

PythonのTopに戻る


pipで指定する名前とimport文の名前は、必ずしも同じではない。インストールした配布パッケージの情報はimportlib.metadata、実際に読み込むモジュールの場所はimportlib.utilやモジュール自身から調べられる。対応する名前、版、配置を分けて確認すれば、名前の取り違えと環境の取り違えを切り分けやすい。

配布名とimport名の役割を分ける

配布パッケージはpipが導入やバージョン管理に使う単位である。一方、importパッケージやモジュールはPythonコードから読み込む単位である。一つの配布物に複数のimport名が含まれる場合もあり、名前空間パッケージでは一つのimport名に複数の配布物が関係することもある。

そのため、import名から配布名を単純な文字列置換で推測しない方がよい。ハイフンとアンダースコアの違いだけとは限らず、importしたオブジェクトの__version__が常に存在するわけでもない。パッケージの公式案内とインストール済みメタデータの両方を使う。

対応名とバージョンを確認する

次の例では、配布名tip-distribution、import名tipmodという練習用パッケージを通常インストールしている。一般公開の同名パッケージを取得する例ではなく、名前の違いを確かめるためのローカル配布物である。

inspect_package.py

from importlib import metadata, util
from pathlib import Path

import_name = "tipmod"
names = sorted(metadata.packages_distributions().get(import_name, []))
print("distributions:", names)
assert names == ["tip-distribution"]
for name in names:
    dist = metadata.distribution(name)
    print("metadata:", dist.metadata["Name"], dist.version)
    assert dist.version == "0.1.0"

spec = util.find_spec(import_name)
assert spec is not None and spec.origin is not None
origin = Path(spec.origin)
print("module:", origin.parent.name + "/" + origin.name)

try:
    metadata.version("tip-no-such-distribution-2026")
except metadata.PackageNotFoundError:
    print("missing distribution: PackageNotFoundError")
else:
    raise AssertionError("The practice distribution must not exist")

実行結果

distributions: ['tip-distribution']
metadata: tip-distribution 0.1.0
module: tipmod/__init__.py
missing distribution: PackageNotFoundError

packages_distributions()の値は一覧であり、一つの文字列ではない。対応が得られた配布名ごとにdistribution()でメタデータを読み、Nameとversionを確認している。表示を安定させるため、配布名の一覧だけsorted()で並べている。

バージョンと実際の読み込み元を照合する

metadataが返す版は、現在のPythonから見える配布メタデータの版である。作業フォルダーに同名モジュールがある場合などは、メタデータと実際にimportするコードが一致しないこともある。版の確認だけでなく、find_specのoriginや読み込み後の__file__も照合したい。

掲載例では実機依存のパスを出さないよう、originの末尾と親フォルダーだけを表示している。実際の診断では元のorigin全文を手元で確認する。distributionのlocate_file(“”)から配布物の基準位置も調べられるが、読み込まれるモジュールの一意な場所と常に同じ意味になるわけではない。

見つからない場合を区別する

versionやdistributionへ渡した配布名が見つからないと、PackageNotFoundErrorになる。import名を渡してしまっただけなのか、本当にその環境へ導入されていないのかを区別する必要がある。失敗するプログラムのsys.executableから始め、同じPythonのpipで調べよう。

一方、標準ライブラリは通常、pipで管理する第三者配布パッケージではない。jsonのimportが成功しても、同じ名前の配布メタデータが見つかるとは限らない。メタデータがないことだけを理由に、標準ライブラリを追加インストールしようとしないことが大切である。

対応表が完全とは限らない

packages_distributionsは、利用可能なメタデータなどからトップレベルの対応を調べる補助である。特に一部のeditable installでは、必要な情報が十分でなく対応が得られない場合がある。空の一覧になったら、そのimport名が絶対に存在しないと断定せず、導入方法と公式の配布名を確認する。

また、環境内に古いメタデータや複数の配置が残ると、情報が分かりにくくなる。診断のためにsite-packages内のファイルを手作業で削るより、新しいvenvに必要なものだけを導入して比較する方が、変更の影響を限定しやすい。

問い合わせには必要な情報をそろえる

不具合を調べるときは、Python本体の版、配布名と版、実行ファイル、実際のモジュールの読み込み元を一組として記録する。これにエラー全文と最小の再現コードがあれば、単に「インストールした」という説明より環境の違いを追いやすい。

ただしパスにはユーザー名や社内のプロジェクト名が含まれる場合がある。外部へ共有する際には個人情報を伏せ、どのvenvとどのsite-packagesを指すかが分かる範囲を残す。配布名・import名・版・位置の四つを区別することが、診断の基本になる。

動作確認と参考資料

掲載例はLinux・CPython 3.12.14で動作確認した。OS固有のコマンドや環境ごとに変わるパスは、本文中の条件を確認して使ってほしい。

関連するTips


PythonのTopに戻る