🙆

.egg-infoを削除すると sys.pathに残って困りますねえ

2022/06/26に公開

前提の環境条件

たとえば..
macOSの環境で,pyenvを使ってローカル開発していて,

  • カレントディレクトリ"$HOME"/{project_dir}というディレクトリにいて以下のようなディレクトリ構造をもったパッケージをインストールしたいという状況を考えます.

結論としてはglobalにinstallすると後々めんどうなことになるので, venvなどの仮想環境でこういうことはやろうね, というよく聞く話です. 1からいろんなパッケージインストールするのが面倒なのでやっちまいました.

{project_dir}
├── pyproject.toml
├── setup.cfg
└── src
    └── my_package
        ├── __init__.py
        └── mod1.py
  • pyproject.tomlの内容
[build-system]
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"

[tool.setuptools]
package-dir = {"" = "src"}  # src ディレクトリ内を対象にinstall

[project]
name = "mypackage"
version = "0.0.1"

setup.cfgはなにも記載しなくても問題なかった.

ローカルインストール

/Users/{username}/{project_dir}にカレントディレクトリを移動後.

pip install -e .

で編集可能な開発ライブラリをローカルにインストールする.
install後は...

python -m site
sys.path = [
    '/Users/{username}/{project_dir}',  # python -m siteが実行されたディレクトリ
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python39.zip',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9/lib-dynload',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9/site-packages',
+    '/Users/{username}/{project_dir}/src'  # 追加された
]
USER_BASE: '/Users/{username}/.local' (exists)
USER_SITE: '/Users/{username}/.local/lib/python3.9/site-packages' (doesn't exist)
ENABLE_USER_SITE: True

'/Users/{username}/{project_dir}/src'が追加されていることが確認できる.
また/Users/{username}/{project_dir}/srcディレクトリに移動してみてその中身を見てみると,,

ls
my_package         mypackage.egg-info

mypackage.egg-info というディレクトリが新たに追加されています.

アンインストール

pip uninstall -y mypackage
python -m site
sys.path = [
    '/Users/{username}/{project_dir}',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python39.zip',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9/lib-dynload',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9/site-packages',
-    '/Users/{username}/{project_dir}/src'  # この行がなくなっているはず
]
USER_BASE: '/Users/{username}/.local' (exists)
USER_SITE: '/Users/{username}/.local/lib/python3.9/site-packages' (doesn't exist)
ENABLE_USER_SITE: True

アンインストール後の.egg-infoどうなったのか気になるので
/Users/{username}/{project_dir}/srcディレクトリに移動してみてその中身を見てみると,,

/Users/{username}/{project_dir}/src
ls
my_package         mypackage.egg-info

mypackage.egg-info は残ってます.

誤って uninstall する前に mypackage.egg-info だけ削除すると...

/Users/{username}/{project_dir}/src
rm -r mypackage.egg-info
python -m site
sys.path = [
    '/Users/{username}/{project_dir}',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python39.zip',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9/lib-dynload',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9/site-packages',
    '/Users/{username}/{project_dir}/src'  # この行がのこっている!!
]
USER_BASE: '/Users/{username}/.local' (exists)
USER_SITE: '/Users/{username}/.local/lib/python3.9/site-packages' (doesn't exist)
ENABLE_USER_SITE: True

installしたディレクトリパスが /Users/{username}/{project_dir}/srcsys.pathに残ってしうようです.

その後開発でいろいろいじくって.egg-infoディレクトリを削除したことは忘れてアンインストールコマンドをうちます.

pip uninstall mypackage
WARNING: Skipping mypackage as it is not installed.

そんなパッケージはないといわれます🤔.

その結果、sys.pathにはパッケージのパスがあるのに pip listにそのパッケージがリストされない という理解しづらい状況が生まれてしまいます.
sys.pathに意図しないパスが追加されるのは避けたいですよね.
さてこの sys.pathの'/Users/{username}/{project_dir}/src'はどこで設定されているのかというと..
stackoverflowに回答がありました.

python -m site

で得られる
sys.pathのリストの中の

'/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9/site-packages'

このsite-packagesディレクトリの中のeasy-install.pthファイルにあるようです.

cd Users/{username}/.pyenv/versions/3.9.7/lib/python3.9/site-packages
cat easy-install.pth  # この中にテキストで書かれている
/Users/{username}/{project_dir}/src

テキストエディタで
/Users/{username}/{project_dir}/src
を削除すれば,

python -m site
sys.path = [
    '/Users/{username}/{project_dir}',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python39.zip',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9/lib-dynload',
    '/Users/{username}/.pyenv/versions/3.9.7/lib/python3.9/site-packages',
-    '/Users/{username}/{project_dir}/src'  # この行が消えるはず
]
USER_BASE: '/Users/{username}/.local' (exists)
USER_SITE: '/Users/{username}/.local/lib/python3.9/site-packages' (doesn't exist)
ENABLE_USER_SITE: True

でようやく元通りです😎

Discussion