I clone this toy repository that demonstrates how namespace packages work:
C:\workspace>git clone https://github.com/pypa/sample-namespace-packages.git
Specifically, I'll use its pkg_resources directory, which has the structure
pkg_a/
setup.py
example_pkg/
__init__.py
a/
__init__.py
pkg_b/
setup.py
example_pkg/
__init__.py
b/
__init__.py
The example_pkg
package is a pkg_resources-style namespace package (explained here ).
I set up my python environment:
C:\workspace>\Python35\python.exe -m venv localpython
C:\workspace>localpython\Scripts\activate.bat
(localpython) C:\workspace>python -m pip install --upgrade pip setuptools
I install pkg_a from the toy repository:
(localpython) C:\workspace>python -m pip install c:\workspace\sample-namespace-packages\pkg_resources\pkg_a
I put pkg_b from the toy repository on my PYTHONPATH:
(localpython) C:\workspace>set PYTHONPATH=c:\workspace\sample-namespace-packages\pkg_resources\pkg_b
I write a test suite for pkg_b, consisting of one line:
(localpython) C:\workspace>echo import example_pkg.b > test_b.py
Now, if I run that test suite in pytest 4.5 or less, it succeeds:
(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 =============================================
But if I run it in pytest 4.6 or greater, it errors:
(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 ===============================================
The import error is understandable: It's presumably looking in the example_pkg
in the site-packages and therefore not finding the b
package, which is under the example_pkg
on the PYTHONPATH.
Yet pytest 4.5 or earlier manages to find example_pkg.b
.
Edit: According to a comment, the relevant difference is that pytest 4.5 and earlier imported pkg_resources
. Indeed, if I add the line
import pkg_resources
at the top of my test file, test_b.py, then the test succeeds even in pytest 4.6 or greater. Furthermore, if I have multiple test files that try to import example_pkg.b
, then it's necessary and sufficient to import pkg_resources
in whichever of them pytest happens to run first.
That means that some side effect of importing pkg_resources
makes example_pkg.b
importable. What exactly does pkg_resources
do that achieves that effect, and can I do it directly instead of getting it as a side effect of a seemingly unused import? And does my needing that side effect mean the setup is invalid?
Import your packages through sys as written in this project (using unittest not pytest)
import sys
sys.path.insert(0,"pkg_a")
sys.path.insert(0,"pkg_b")
#Test goes here
My project load test/testSpecie.py
which tests files in src/...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.