[英]Tox and lib and lib64 and site-packages
I'm using tox
and coverage.py
to run tests of my Python project in my continuous build server. 我正在使用
tox
和coverage.py
在我的连续构建服务器中运行我的Python项目的测试。 I also have a package pkg_x
from a vendor (not available on PyPI) that I've installed using python3.5 setup.py install
, which puts it in /usr/lib/python3.5/site-packages
. 我还有一个来自供应商的包
pkg_x
(在PyPI上不可用),我使用python3.5 setup.py install
它,它将它放在/usr/lib/python3.5/site-packages
。 Now I need to make that package available to the testing code. 现在我需要将该包用于测试代码。
My current tox.ini
looks like this: 我目前的
tox.ini
看起来像这样:
[tox]
envlist = py35
[testenv]
deps = nose
coverage
commands = coverage run -m nose []
sitepackages = True
and I run the tests like so: 我像这样运行测试:
python3.5 -m tox -- --verbose --with-doctest
That fails spectacularly - none of the dependency packages listed in my local setup.py
(eg public stuff like more_itertools
) can be found, even though it does create directories like .tox/py35/lib/python3.5/site-packages/more_itertools
that seem to contain the relevant packages. 这
more_itertools
我的本地setup.py
列出的依赖包(例如,像more_itertools
这样的公共more_itertools
)都没有找到,即使它确实创建了.tox/py35/lib/python3.5/site-packages/more_itertools
似乎包含相关的包。 If I fire up .tox/py35/bin/python3.5
, sys.path
looks like this: 如果我启动
.tox/py35/bin/python3.5
, sys.path
看起来像这样:
>>> [re.compile('.*\\.tox').sub('.tox', x) for x in sys.path]
['',
'.tox/py35/lib64/python35.zip',
'.tox/py35/lib64/python3.5',
'.tox/py35/lib64/python3.5/plat-linux',
'.tox/py35/lib64/python3.5/lib-dynload',
'/usr/lib64/python3.5',
'/usr/lib/python3.5',
'.tox/py35/lib/python3.5/site-packages']
If I remove the sitepackages = True
line from my tox.ini
, then I do get farther, in that packages like more_itertools
and the rest of the stuff in my setup.py
dependencies can now be found, but the vendor package pkg_x
I mentioned above still can't be found. 如果我从我的
tox.ini
删除了sitepackages = True
行,那么我确实得到了更多,在more_itertools
这样的包中,现在可以找到我的setup.py
依赖项中的其他东西了,但是上面提到的供应商包pkg_x
仍然无法找到。 And sys.path
looks like this: sys.path
看起来像这样:
>>> [re.compile('.*\\.tox').sub('.tox', x) for x in sys.path]
['',
'.tox/py35/lib64/python35.zip',
'.tox/py35/lib64/python3.5',
'.tox/py35/lib64/python3.5/plat-linux',
'.tox/py35/lib64/python3.5/lib-dynload',
'/usr/lib64/python3.5',
'/usr/lib/python3.5',
'.tox/py35/lib/python3.5/site-packages',
'/usr/lib64/python3.5/site-packages',
'/usr/lib/python3.5/site-packages']
In neither case does .tox/py35/
seem to contain the vendor package pkg_x
anywhere. 在任何情况下,
.tox/py35/
似乎都不包含供应商包pkg_x
。 And although the directory /usr/lib/python3.5/site-packages
is listed when I fire up .tox/py35/bin/python3.5
manually, pkg_x
isn't actually found when running the tests. 虽然我手动启动
.tox/py35/bin/python3.5
时会列出目录/usr/lib/python3.5/site-packages
, pkg_x
在运行测试时实际上并未找到pkg_x
。
It also looks like sitepackages = True
has the opposite effect from what it's documented to do at http://tox.readthedocs.io/en/latest/config.html#confval-sitepackages=True|False , right? 它看起来像
sitepackages = True
与它在http://tox.readthedocs.io/en/latest/config.html#confval-sitepackages=True|False中记录的内容有相反的效果,对吧?
Advice very appreciated! 建议非常感谢!
Tox
creates a virtualenv , then runs it's tests from inside that environment. Tox
创建了一个virtualenv ,然后从该环境中运行它的测试。
The --sitepackages
argument is a switch determining whether the virtualenv gets access to globally installed packages. --sitepackages
参数是一个开关,用于确定virtualenv是否可以访问全局安装的包。
The 'normal' way to run tox would be to simply say tox
; 运行tox的“正常”方式就是简单地说
tox
; installing it via pip or via an OS package should put it into your path. 通过pip或OS软件包安装它应该把它放到你的路径中。 ie:
即:
$ tox
Which is the same as saying: 这跟说:
$ tox -c tox.ini
Where you invoke tox directly, python -m tox
, it may do something, but this is a red flag to me. 你直接调用tox的地方,
python -m tox
,它可能会做一些事情,但这对我来说是一个红旗。 This command seems unlikely to activate the relevant virtual environment, which would explain your package availability woes. 此命令似乎不太可能激活相关的虚拟环境,这可以解释您的软件包可用性问题。 It fits because when you omit
sitepackages
, it actually adds the global packages because it thinks it is inside a virtualenv and so adds, what it thinks are the local
sitepackages, although they're actually global. 它适合,因为当你省略
sitepackages
,它实际上添加了全局包,因为它认为它在virtualenv中,因此添加了它认为的local
站点包,尽管它们实际上是全局的。 The reverse happens when you make it true because when it goes looking for global packages it can't find them. 当你把它变成真的时会发生相反的情况,因为当它寻找全局包时它找不到它们。 Whatever, because you're not invoking tox as expected it's as confused as we are.
无论如何,因为你没有像预期的那样调用tox,它就像我们一样困惑。
So just use the tox
command provided. 所以只需使用提供的
tox
命令即可。
But wait there's more: You say you have a package which is required, but not available on pypi. 但是等等还有更多:你说你有一个必需的包,但在pypi上没有。 So how is tox going to install it?
那么tox如何安装呢? The tox docs suggest a couple of ways (use a requirements.txt), but the most direct to describe here is to activate the env and install it manually.
tox文档提出了两种方法(使用requirements.txt),但这里最直接的描述是激活env并手动安装。
Also good if you need to debug further: step into the .tox
directory and activate the venv manually. 如果您需要进一步调试也很好:进入
.tox
目录并手动激活venv。 eg: 例如:
$ source .tox/testenv/bin/activate
(where testenv
is the name you used between brackets in the tox.ini
). (其中
testenv
是您在tox.ini
括号之间使用的名称)。
Now install the package however you did it before eg: pip install pkg_x
现在安装包,不过你之前做过,例如:
pip install pkg_x
Deactivate the venv when you're done with it this way: 完成后以这种方式停用venv:
$ deactivate
Try tox
now? 试试
tox
吧?
If we're on the right track learn more about virtualenv here 如果我们在正确的轨道上了解更多关于virtualenv的信息
It looks like the solution to my problem is to change the commands
line in my tox.ini
from this: 看起来我的问题的解决方案是改变我的
tox.ini
的commands
行:
commands = coverage run -m nose []
to this: 对此:
commands = python -m coverage run -m nose []
The effect is that python
is now a virtualenv-mapped command, which loads the correct Python interpreter, loads the coverage
module, and runs it. 结果是
python
现在是一个virtualenv-mapped命令,它加载正确的Python解释器,加载coverage
模块并运行它。 Without python -m
, it just finds whatever coverage
executable is in my PATH
and runs it, with unpredictable results. 如果没有
python -m
,它只是发现任何coverage
可执行文件在我的PATH
并运行它,有不可预知的结果。 whitelist_externals
could be used, but it would only band-aid the problem. 可以使用
whitelist_externals
,但它只会助长问题。
Then if I also add the sitepackages = True
line, it successfully sees the pkg_x
I installed from the vendor, and my tests succeed. 然后,如果我还添加了
sitepackages = True
行,它会成功查看从供应商安装的pkg_x
,并且我的测试成功。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.