🐍

venv の activate がなにをやっているか調べる

2024/06/07に公開

調査

ドキュメントによれば activate すると .venv/binPATH に追加される。このパスのインタプリタを使いさえすれば、activate する必要はないらしい。

.venv/bin/python をみてみると symlink で python のバイナリにリンクしているだけ。

% ls -l .venv/bin/python
lrwxr-xr-x  1 labocho  staff    58B  5 23 14:10 python -> /Users/labocho/.anyenv/envs/pyenv/versions/3.12.3/bin/python

普通に python 実行する場合と、この symlink を使って実行する場合で sys.path を見てみる

# 通常の python (出力は整形)
% echo 'import sys\nprint(sys.path)' | python
[
  '',
  '/Users/labocho/.anyenv/envs/pyenv/versions/3.12.3/lib/python312.zip',
  '/Users/labocho/.anyenv/envs/pyenv/versions/3.12.3/lib/python3.12',
  '/Users/labocho/.anyenv/envs/pyenv/versions/3.12.3/lib/python3.12/lib-dynload',
  '/Users/labocho/.anyenv/envs/pyenv/versions/3.12.3/lib/python3.12/site-packages'
]
# symlink から実行 (出力は整形)
% echo 'import sys\nprint(sys.path)' | .venv/bin/python
[
  '',
  '/Users/labocho/.anyenv/envs/pyenv/versions/3.12.3/lib/python312.zip',
  '/Users/labocho/.anyenv/envs/pyenv/versions/3.12.3/lib/python3.12',
  '/Users/labocho/.anyenv/envs/pyenv/versions/3.12.3/lib/python3.12/lib-dynload',
  '/Users/labocho/myproject/.venv/lib/python3.12/site-packages'
]

最後の要素が異なり、symlink から実行した場合は .venv 内の site-packages になっている。

sys.prefixsite について調べると…

  1. symlink から実行した場合は sys.path.venv のパスになる。
  2. .venv/pyvenv.cfg があるので .venv/lib/python3.12/site-packages が sys.path に追加される。

という挙動で仮想環境を実現しているようだ。

おまけ

direnv

source .venv/bin/activate deactivate がめんどうなので、direnv 使って下記内容の .envrc 使うとよさげ。

export PATH=$PWD/.venv/bin:$PATH

pyvenv.cfg

python -m venv .venv で作られる .venv/pyvenv.cfg は下記のような内容。カレントディレクトリのフルパスが含まれるのでディレクトリのリネーム時などは再作成する必要がある。

home = /Users/labocho/.anyenv/envs/pyenv/versions/3.12.3/bin
include-system-site-packages = false
version = 3.12.3
executable = /Users/labocho/.anyenv/envs/pyenv/versions/3.12.3/bin/python3.12
command = /Users/labocho/.anyenv/envs/pyenv/versions/3.12.3/bin/python -m venv /Users/labocho/myproject/.venv

Discussion