qh****@gmail.com wrote:
All of the __init__.py files are empty and I don't know of any
overlapping of names. Like I said this is code that works fine, I'm
just trying to clean up some things as I go.
I see. The problem is that a module in a package is entered into
the parent package only after the import is complete. The sequence
goes like this:
create module aaa.z2
add aaa.z2 to sys.modules
run content aaa.z2
add aaa.z2 to aaa
This procedure is needed for rollback in case of exceptions: if
the code in aaa.z2 fails, the traces of the module object must
be discarded. This currently only undoes the sys.modules change.
Now, with circular imports, you get
create module aaa.z2
add aaa.z2 to sys.modules
run aaa.z2
from aaa import z1
is "aaa.z1" already in sys.modules? no - load it
create aaa.z1
add aaa.z1 to sys.modules
run aaa.z1
from aaa import z2
is aaa.z2 already in sys.modules? yes - skip loading it
fetch z2 from aaa -> NameError, aaa has no z2 yet
The problem here is "import from"; this doesn't work with circular
imports too well. For plain "import", circularity is supported, as
the module is added to sys.modules first, then it is run. So you
can import it while its import is in progress.
As a quick work-around, you can add each module to the package:
# z1.py
if __name__ != '__main__':
import sys, aaa
aaa.z1 = sys.modules['aaa.z1']
from aaa import z2
# z2.py
if __name__ != '__main__':
import sys, aaa
aaa.z2 = sys.modules['aaa.z2']
from aaa import z1
HTH,
Martin
P.S. Notice that running a module as __main__ *and* importing it
circularly is also a problem (and is already in the non-package
case): the module gets loaded twice: once as __main__, and once
as z1.