pythonsys.pathnamespace-package

How to load implicit namespace package by adding the package egg to sys.path?


Since python 3.3, implicit namespace packages are supported, so that I can have two packages:

a
├── b
    ├── __init__.py

a
├── c
    ├── __init__.py

and import a.b and a.c without problems. But it seems that I can only do it with pip install; if I only create an egg of either package and add the egg path into sys.path, the module cannot be loaded:

import sys
sys.path.append('./a-b.egg')

import a.b # ModuleNotFoundError: No module named 'a.b'

Solution

  • There are three ways to create namespace packages:

    1. native namespace packages
    2. pkgutil-style namespace packages
    3. pkg_resources-style namespace packages

    The former two are not zip-safe, and that's why the egg doesn't work. The third one is zip-safe.

    Basically, the __init__.py file for the namespace package needs to contain only the following:

    __import__('pkg_resources').declare_namespace(__name__)
    

    and every distribution must provide the namespace_packages argument to setup() in setup.py:

    from setuptools import find_packages, setup
    
    setup(
        name='mynamespace-subpackage-a',
        ...
        packages=find_packages()
        namespace_packages=['mynamespace']
    )