簡體   English   中英

tox 環境如何設置其 sys.path

[英]How does a tox environment set its sys.path

我有一個需要編譯的 Python 項目。 tox使sdistbdist_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM