Skip to content
Latchkey

Python "ModuleNotFoundError" for a Namespace Package Subpackage in CI

A namespace package (PEP 420) spreads one importable name across multiple distributions or directories with no __init__.py at the shared level. The subpackage fails to import when an __init__.py shadows the namespace or only one portion is installed.

What this error means

Importing from acme.plugins import thing fails with ModuleNotFoundError: No module named acme.plugins, even though the acme top level imports. The shared namespace exists, but the specific portion is not visible to the import system.

Python traceback
ModuleNotFoundError: No module named 'acme.plugins'
# but: import acme  -> succeeds (it is a namespace package)

Common causes

An __init__.py turned the namespace into a regular package

A stray acme/__init__.py in one distribution makes acme a regular package, so Python stops merging the other portions and the sibling subpackage disappears.

Only one portion installed

The portion providing acme.plugins was never installed (or installed into a different environment), so the namespace has the top level but not that branch.

How to fix it

Remove the shadowing __init__.py

For a PEP 420 namespace, the shared level must have no __init__.py. Delete it so portions merge.

Terminal
# there must be NO acme/__init__.py in any portion of the namespace
find . -path '*/acme/__init__.py' -print

Install all portions of the namespace

Install every distribution that contributes to the namespace into the same environment.

Terminal
pip install acme-core acme-plugins
python -c "import acme.plugins; print(acme.plugins.__file__)"

Declare the namespace in packaging config

  1. For setuptools, use find_namespace_packages / [tool.setuptools.packages.find] with the namespace included.
  2. Ensure no portion ships an __init__.py at the shared level.
  3. Verify with python -c "import acme; print(acme.__path__)" showing multiple paths.

How to prevent it

  • Never add __init__.py at a PEP 420 namespace’s shared level.
  • Install every portion that contributes to the namespace.
  • Use namespace-aware packaging config so all portions are discoverable.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →