nikkie-ftnextの日記

イベントレポートや読書メモを発信

プログラムからPythonの仮想環境にパッケージをインストールするには、subprocessを使うしかないんですね

はじめに

七尾百合子さん、お誕生日 167日目 おめでとうございます! nikkieです。

GPT-5 とやり取りしながら調べたことの備忘録です。
代案を知っている方は GPT-5 に勝っていると思われますので、ぜひ @ftnext までお知らせください。

目次

pip の User Guide

Using pip from your program

As noted previously, pip is a command line program.
While it is implemented in Python, and so is available from your Python code via import pip, you must not use pip’s internal APIs in this way.

pip は Python で実装され、Pythonコードでimport pipもできるが、この方法で内部APIを使ってはいけないとのこと。

代わりに案内される方法が、subprocess。

The most reliable approach, and the one that is fully supported, is to run pip in a subprocess.

subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'my_package'])

reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])

subprocessでpipを実行しています。

ドキュメントリンク

  • subprocess.check_call
    • 引数でコマンドを実行し、完了を待つ
    • リターンコードが0でない場合、CalledProcessError送出
  • subprocess.check_output
    • 引数でコマンドを実行し、その出力を返します。

    • コマンドのリターンコードが非ゼロならば CalledProcessError 例外が送出されます。

pipのPython実装自体は実装詳細と考えられているそうです。

What this means in practice is that everything inside of pip is considered an implementation detail.

そうなると変更しにくいコマンドラインツールに依存、そのため subprocess 利用となりますね。

すでに見ていた subprocess 利用例

python -m venv--upgrade-deps

標準ライブラリの venv モジュールには --upgrade-deps オプションがあるのですが、その実装はsubprocess.check_outputです。
最新のPythonでも確認:https://github.com/python/cpython/blob/v3.13.7/Lib/venv/__init__.py#L442

ばんくしさんによる自作 Python Package Manager 入門

subprocess.runpip installする実装です!
https://github.com/vaaaaanquish/mypa/blob/f19ac19e0edd33dbe27fb52a39198812fe8eb59a/mypa/env.py#L13-L18

終わりに

pipの内部APIの使用は推奨されておらず、subprocessでコマンドラインツールとして実行することになると知りました。
これまで知っていたやり方がなぜ subprocess なのか、他の方法がどうやらないらしいと知って明確になりました。

高速なpipとして当初登場したuvですが、subprocessから呼び出してpipの代わりに使うこともできると思われます。
Hatchなどの実装をのぞいてみたいですね