Introduction

忘備録。
きっかけは pip からインストールした mmdetection をソース修正なしに挙動を変更できないかを試していた時。

How to do?

sitecustomizeusercustomize という python 公式の方法。
両方とも特定のファイル名を持つ python コードをシステムの特定の場所に配置することで python インタープリタ起動時、一番最初に呼び出してくれるというもの。

sitecustomize はシステム全部に影響するが、usercustomize であれば実行しているユーザのみに影響する。

場所はシステムによって異なるため、都度調べる必要がある。

sitecustomize.py の置き場所

Windows
1
2
$ python3 -c "import site; print(site.getsitepackages())"
['C:\\Python\\3.10\\x64', 'C:\\Python\\3.10\\x64\\lib\\site-packages']
Linux
1
2
$ python3 -c "import site; print(site.getsitepackages())" 
['/usr/local/lib/python3.8/dist-packages', '/usr/lib/python3/dist-packages', '/usr/lib/python3.8/dist-packages']
OSX
1
2
$ python3 -c "import site; print(site.getsitepackages())" 
['/opt/homebrew/opt/python@3.13/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages']

usercustomize.py の置き場所

Windows
1
2
$ python3 -c "import site; print(site.getusersitepackages())"
C:\Users\TAKUYA\AppData\Roaming\Python\Python310\site-packages
Linux
1
2
$t-takeuchi@esxi-vm03:~$$ python3 -c "import site; print(site.getusersitepackages())" 
/home/t-takeuchi/.local/lib/python3.8/site-packages
OSX
1
2
$ $python3 -c "import site; print(site.getusersitepackages())"
/Users/t-takeuchi/Library/Python/3.13/lib/python/site-packages

実行してみる

下記の実行スクリプトを用意する

main.py
1
2
3
4
import sys

print(f"{sys.getdefaultencoding()}")
print("This is main.py")
sitecustomize.py
1
2
3
4
5
from unittest.mock import patch

patcher = patch('sys.getdefaultencoding', return_value='sys.getdefaultencoding IS HACKED!!!')
patcher.start()
print("This is sitecustomize.py")
usercustomize.py
1
print("This is usercustomize.py")

sitecustomize.py と usercustomize.py を適切な場所に配置し main.py を実行する。
今回は Windows 上で確認しているので下記に配置した。

  • C:\Python\3.10\x64\Lib\site-packages\sitecustomize.py
  • C:\Users\TAKUYA\AppData\Roaming\Python\Python310\site-packages\usercustomize.py

実行すると下記のような結果になる。

1
2
3
4
5
$ python3 main.py
This is sitecustomize.py
This is usercustomize.py
sys.getdefaultencoding IS HACKED!!!
This is main.py

sitecustomize.py、usercustomize.py の順で実行されていることがわかる。
また unittest.mock.patch によって既存の関数である sys.getdefaultencoding() が改竄されていることも分かる。
(実はこれが mmdetection の挙動変更でやりたかったこと)

仮想環境の場合

venv で作成した環境であれば場所が仮想環境のディレクトリに変化する。
ただし、 usercustomize.py は変化せず、 sitecustomize.py の場所が仮想環境の場所に変化する。

さらに言えば、仮想環境の場合は usercustomize.py は呼ばれない。
これは python -m site を実行すればわかるが、 下記の通り ENABLE_USER_SITE が False になり usercustomize.py が呼ばれなくなっていることからも分かる。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ python3 -m site
sys.path = [
'F:\\',
'C:\\Python\\3.10\\x64\\python310.zip',
'C:\\Python\\3.10\\x64\\DLLs',
'C:\\Python\\3.10\\x64\\lib',
'C:\\Python\\3.10\\x64',
'F:\\.venv',
'F:\\.venv\\lib\\site-packages',
]
USER_BASE: 'C:\\Users\\TAKUYA\\AppData\\Roaming\\Python' (exists)
USER_SITE: 'C:\\Users\\TAKUYA\\AppData\\Roaming\\Python\\Python310\\site-packages' (exists)
ENABLE_USER_SITE: False

このことは usercustomize にも

このあとで、 ENABLE_USER_SITE が真であれば、任意のユーザ固有のカスタマイズを行うことが出来る

と記述があるので仕様通りである (仮想環境がどうかではなく)。