[英]How does a tox environment set its sys.path
我有一個需要編譯的 Python 項目。 tox
使sdist
和bdist_wheel
成功。 但是當tox
運行測試時,源代碼模塊總是被導入的,導致測試失敗(因為那里沒有二進制文件)。 發生這種情況是因為項目的根目錄始終是sys.path
上的第一個文件夾,我無法弄清楚這是如何發生的。
project
├── foo
│ ├── __init__.py
│ └── bar.c <-- turns into bar.so in bdist_wheel
├── tests
│ ├── __init__.py
│ └── test_bar.py
├── tox.ini
└── setup.py
tox.ini
[tox]
envlist =
py37
[testenv]
changedir = {toxinidir}/tests
setenv =
PYTHONPATH = {envsitepackagesdir}
commands = {envpython} -m pytest --cov=bar --cov-report=html
請注意,我設置了changedir
以確保項目根目錄不是工作目錄。 我還將PYTHONPATH
設置為僅 tox 環境的站點包。 我還強制運行 tox 環境的 Python。
盡管如此,這是sys.path
我看看我是否在測試運行期間打印出來:
[
'/home/me/foo', # Bad, bad, bad
'/home/me/foo/tests', # Good, this is the CWD
'/home/me/foo/.tox/py37/lib/python3.7/site-packages', # Good
'/home/me/foo/.tox/py37/lib/python37.zip', # Umm, ok, this doesn't exist
'/home/me/foo/.tox/py37/lib/python3.7', # Good
'/home/me/foo/.tox/py37/lib/python3.7/lib-dynload', # Probably good
'/home/me/anaconda/envs/foo/lib/python3.7', # Bad, why is this here?
]
最大的違規者是/home/me/foo
,它導致加載源模塊foo
而不是安裝在tox
。
另一個有問題的是/home/me/anaconda/envs/foo/lib/python3.7
。 如果在環境中找不到某些東西,我希望tox
不依賴於系統解釋器。
tox 如何選擇這些路徑以及如何控制它以更好地表現?
這不是由毒素引起的; 它是由pytest引起的。 如 pytest 文檔中所述,已知 pytest 與在隔離環境中安裝發行版的工具(如 tox)之間存在不良交互。
這樣做的原因是pytest 修改了sys.path
以便將包含測試包的所有文件夾(其中包含__init__.py
測試文件夾)添加到其中。 因為foo/tests
目錄包含了一個__init__.py
文件,所以 pytest 將foo/
添加到sys.path
這樣tests
包就可以用正常的import
語句import
。
即使刪除__init__.py
可能還不夠。 在foo
目錄中以python -m pytest
運行 pytest 將導致foo
目錄被添加到sys.path
。 使用pytest
命令行工具運行 pytest 將避免這種情況。
推薦的解決方案是將所有源移動到專用的src
目錄。 這確保源包永遠不會在sys.path
即使項目根在。
project
├── src
│ └── foo
│ ├── __init__.py
│ └── bar.c
├── tests
│ ├── __init__.py
│ └── test_bar.py
├── tox.ini
└── setup.py
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.