Description
The structure of Python namespace packages cannot be determined just by looking at the filesystem. Consider the following directory tree:
src/
core.py
aaa/
test_core.py
bbb/
core.py
test_core.py
If src/
(but nothing underneath it) is in sys.path
, we have the following modules:
core
aaa
aaa.test_core
bbb
bbb.core
bbb.test_core
where aaa
and bbb
are namespace modules. We might also have other parts of the namespace modules outside of this tree, e.g. by adding othersrc/
to sys.path
so that import bbb.other
will work if othersrc/bbb/other.py
exists.)
It's easy to configure pytest to have src
in the path, but when discovering and loading src/aaa/test_core.py
, as described here, it adds src/aaa
to sys.path
and imports src/aaa/test_core.py
using a different module structure than the programmer may have intended: import test_core
. Further, the same thing happens again with src/bbb/test_core.py
and now we get a conflict because there's already a test_core
module.
It would be nice to be able to configure pytest so that we could tell it that src/
may contain namespace packages and, if it does, they are all intended to be rooted at src/
. That is, when discovering src/{aaa,bbb}/test_core.py
do not add anything to sys.path
but instead generate the fully qualified module name based on the file's position in the hierarchy relative to src/
.
Another, more aggressive, option might be to see if the file is under any of the paths already in sys.path
and determine the fully qualified module name by the hierarchy relative to the first path in sys.path
under which the file falls.
The Stack Overflow question How do I Pytest a project using PEP 420 namespace packages? also discusses the issue.
The way I put these here makes this sound pretty simple (at least as far as description, if not implementation), but there may be other subtleties I'm missing here, about which I welcome discussion.