pip-compileでMetadataGenerationFailedの例外が起きる
pip-compileは、pip-toolsパッケージ(jazzband/pip-tools)に含まれるコマンドで、
Pythonパッケージのリストrequirements.in
から、
依存ツリーのライブラリバージョンリストrequirements.txt
を出力してくれる便利なツールである。
入力例 requirements.in
djangorequestsgunicornmysqlclientpython-dateutilrequests-oauthlibschedule
pip-compile requirements.in
出力例 requirements.txt
## This file is autogenerated by pip-compile with python 3.8# To update, run:## pip-compile requirements.in#asgiref==3.5.2# via djangobackports-zoneinfo==0.2.1# via djangocertifi==2022.6.15# via requestscharset-normalizer==2.0.12# via requestsdjango==4.0.5# via -r requirements.ingunicorn==20.1.0# via -r requirements.inidna==3.3# via requestsmysqlclient==2.1.1# via -r requirements.inoauthlib==3.2.0# via requests-oauthlibpython-dateutil==2.8.2# via -r requirements.inrequests==2.28.0# via# -r requirements.in# requests-oauthlibrequests-oauthlib==1.3.1# via -r requirements.inschedule==1.1.0# via -r requirements.insix==1.16.0# via python-dateutilsqlparse==0.4.2# via djangourllib3==1.26.9# via requests# The following packages are considered to be unsafe in a requirements file:# setuptools
- https://pypi.org/project/pip-tools/ (現在 pip-tools==6.6.2)
- https://github.com/jazzband/pip-tools
ところでPythonパッケージは、システムパッケージの事前インストールを要求することがある。 以下、システムパッケージ名はDebian/Ubuntuを想定する。
依存先が動的ライブラリであれば、モジュールのimport時に例外を投げる作りになっている場合もあるが、 Pythonパッケージのインストールと同時にC言語コードからネイティブバイナリをコンパイルするような作りになっている場合には、 コンパイラや依存関係のヘッダファイルなどが必要になることがある。
このような依存関係が不足しているとき、pip-compileは以下のようなエラーログを出力する。
pip._internal.exceptions.MetadataGenerationFailed: metadata generation failed
ただし、このエラーログが出力されたとき、必ずしも原因が依存関係の不足とは限らない点は指摘しておく。 いまのところpip-compileには、パッケージのインストール処理が記述されたsetup.pyの実行時に例外が起きたとき、その例外の内容が隠されてしまう問題があり、他に原因がある可能性もある。 他に原因がありそうなときには、venvで仮想環境を作るなどして、一度通常のpip installを実行してみて、エラーログを確認して対処するとよいと思う。
ともあれ、このようなpipに管理されていない依存関係は、 ドキュメントが整備されている通常のPythonパッケージであれば、 PyPIやパッケージの公式ドキュメントに利用者向けの記載があるはずなので、 そちらを確認してインストールしてからpip-compileを実行すると解消するだろう。
例えば、PostgreSQLドライバのpsycopg2は、以下のようなパッケージの事前インストールが必要である。
- Cコンパイラ
- Pythonのヘッダ
- Postgresライブラリlibpqのヘッダ
sudo apt install python3-dev libpq-dev build-essential
- https://pypi.org/project/psycopg2/ (現在 psycopg2==2.9.3)
- https://www.psycopg.org/docs/install.html#build-prerequisites
MySQLドライバのmysqlclientは、以下のようなパッケージの事前インストールが必要である。
sudo apt install python3-dev default-libmysqlclient-dev build-essential
- https://pypi.org/project/mysqlclient/ (現在 mysqlclient==2.1.1)