毒素环境如何设置其sys.path

时间:2019-04-18 00:44:10

标签: python tox

我有一个需要编译的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不要退回到系统解释器上。

毒物如何选择这些路径,以及如何控制它使其表现更好?

1 个答案:

答案 0 :(得分:1)

这不是由毒素引起的;它是由pytest引起的。 As described in the pytest documentation,在pytest和将Tox发行版安装在隔离环境中的工具之间存在不良的互动。

这样做的原因是将pytest modifies sys.path添加到所有包含测试包的文件夹(其中包含onCreate的测试文件夹)中。由于__init__.py目录包含一个foo/tests文件,因此pytest将__init__.py添加到foo/中,以便可以使用普通的sys.path来导入tests软件包。声明。

Even removing __init__.py may not be enough.import目录中以python -m pytest运行pytest将导致foo目录被添加到foo中。使用sys.path命令行工具运行pytest可以避免这种情况。

推荐的解决方案是将所有源移动到专用的pytest目录。这样可以确保即使项目根目录位于src上,源程序包也永远不会存在。

推荐的项目结构

sys.path