我克隆了这个演示命名空间包如何工作的玩具存储库:
C:\workspace>git clone https://github.com/pypa/sample-namespace-packages.git
具体来说,我将使用它的 pkg_resources 目录,该目录具有以下结构
pkg_a/
setup.py
example_pkg/
__init__.py
a/
__init__.py
pkg_b/
setup.py
example_pkg/
__init__.py
b/
__init__.py
该example_pkg
包是一个 pkg_resources 样式的命名空间包(在此处解释)。
我设置了我的python环境:
C:\workspace>\Python35\python.exe -m venv localpython
C:\workspace>localpython\Scripts\activate.bat
(localpython) C:\workspace>python -m pip install --upgrade pip setuptools
我从玩具存储库安装 pkg_a:
(localpython) C:\workspace>python -m pip install c:\workspace\sample-namespace-packages\pkg_resources\pkg_a
我将 pkg_b 从玩具存储库放在我的 PYTHONPATH 上:
(localpython) C:\workspace>set PYTHONPATH=c:\workspace\sample-namespace-packages\pkg_resources\pkg_b
我为 pkg_b 编写了一个测试套件,由一行组成:
(localpython) C:\workspace>echo import example_pkg.b > test_b.py
现在,如果我在 pytest 4.5 或更低版本中运行该测试套件,它会成功:
(localpython) C:\workspace>python -m pip install pytest==4.5.0
Collecting pytest==4.5.0
...
(localpython) C:\workspace>pytest test_b.py
================================================= test session starts =================================================
platform win32 -- Python 3.5.2, pytest-4.5.0, py-1.8.0, pluggy-0.12.0
rootdir: C:\workspace
collected 0 items
============================================ no tests ran in 0.02 seconds =============================================
但是如果我在 pytest 4.6 或更高版本中运行它,它会出错:
(localpython) C:\workspace>python -m pip install pytest==4.6.0
Collecting pytest==4.6.0
...
(localpython) C:\workspace>pytest test_b.py
================================================= test session starts =================================================
platform win32 -- Python 3.5.2, pytest-4.6.0, py-1.8.0, pluggy-0.12.0
rootdir: C:\workspace
collected 0 items / 1 errors
======================================================= ERRORS ========================================================
_____________________________________________ ERROR collecting test_b.py ______________________________________________
ImportError while importing test module 'C:\workspace\test_b.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
test_b.py:1: in <module>
import example_pkg.b
E ImportError: No module named 'example_pkg.b'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
=============================================== 1 error in 0.08 seconds ===============================================
导入错误是可以理解的:它可能是example_pkg
在站点包中查找,因此没有找到位于 PYTHONPATHb
下的包。example_pkg
然而 pytest 4.5 或更早版本设法找到example_pkg.b
.
编辑:根据评论,相关的区别是 pytest 4.5 和更早的导入pkg_resources
. 确实,如果我添加该行
import pkg_resources
在我的测试文件 test_b.py 的顶部,即使在 pytest 4.6 或更高版本中,测试也会成功。此外,如果我有多个尝试导入的测试文件example_pkg.b
,那么导入pkg_resources
其中的任何一个 pytest 碰巧首先运行都是必要且足够的。
这意味着导入的一些副作用pkg_resources
使得example_pkg.b
可导入。究竟是pkg_resources
做什么来达到这种效果的,我可以直接做到这一点,而不是将其作为看似未使用的导入的副作用吗?我需要这种副作用是否意味着设置无效?