This repository contains three small nearly identical Python source packages. All three provide a simple main
program installed as pds-experiment
that prints a "hello world" message and then lists each name found in the pds.api_client
package. They differ as follows:
Package | Difference | Works |
---|---|---|
non-pds |
Has a top-level pds2 namespace package |
✓ |
without |
Has a top-level pds module, but it's not a namespace package |
✗ |
with |
Has a top level pds module, and is a namespace package |
✗ |
All three depend on pds.api_client==0.6.0
(although 0.6.0 suffers from a separate bug).
All three ought to work okay, except only the non-pds
seems to function. As of this writing, this behavior appears with Python 3.9.5, setuptools
57.0.0, and pip
21.1.3.
In each directory, do the following:
python3 -m venv venv
venv/bin/pip install --quiet --upgrade setuptools pip wheel
venv/bin/pip install --editable .
venv/bin/pds-experiment
With the non-pds
package, the experiment works because the top-level module is pds2
; this does not conflict with the top-level module pds
of pds.client_api
. (pds2
is also a namespace package, but that's orthogonal to this demonstraion.)
With the without
package, the experiment fails with the error ModuleNotFoundError: No module named 'pds.experiment'
. This seems to be caused by Python discovering that the pds
module exists in site-packages
and sets its __path__
attribute as the root for all future lookups of pds
submodules. This is fine for pds.client_api
but prevents the console script from finding pds.experiment.main
.
The with
package has a top-level module pds
but also declares it as a namespace package, which is the ideal case. However, pds.client_api
is an issue here, too. The error message is ModuleNotFoundError: No module named 'pds.api_client'
. In this case, Python seems to know now that pds
is strictly a namespace, but then cannot resolve any non-namespace usage of pds
, as in the case for pds.client_api
.
pds.client_api
should declare pds
as a namespace package.
Note: it's possible that even if pds
were a namespace package in pds.client_api
, the without
example might not work. But seriously, an organization as large as PDS should be using namespace packages anyway 😄