Logister
Logister

Reputation: 1904

Python referencing submodules from importing root package

The Problem:

Supposing I have a directory structure like:

root/
    __init__.py
    foo.py
    dir1/
        __init__.py
        bar.py
        dir2/
            __init__.py
            baz.py

where the various python files contain some function called hello_world.

What I want to be able to do is write something like:

import root
root.dir1.foo.hello_world()
root.dir1.dir2.baz.hello_world()

Of course, when I do this, I get a AttributeError: module has no attribute error. This, I think, is due to the "the __init__.py trap" in the docs. How do I manipulate the init files such that I can make the above code run?

Caveats

What I've Tried:

I've tried to get around this by changing the __init__.py files into namespace packages). Unfortunately, this doesn't seem to work. E.g. adding:

__path__ = __import__('pkgutil').extend_path(__path__, __name__)

to the various init files doesn't change anything. Similarly, setting the __path__ attribute directly doesn't solve the problem. E.g. in each init file setting __path__ = ['<string name of child dir>'] doesn't resolve the error.

This is a bit mysterious to me, since the __path__ is supposed to tell python where to look for submodules, and the init files are supposed to be run sequentially, so why cant it figure out where things are?

Notes:

This issue seems to be described in the docs here

Upvotes: 1

Views: 75

Answers (1)

Logister
Logister

Reputation: 1904

One solution was to put a from . import * after defining the __all__ property in each init file. E.g. in the init in dir1 put:

__all__ = ['foo', 'dir2']
from . import *

This solves the use case, but it seems like the wrong way. Open for better answers.

Upvotes: 1

Related Questions