467,161 Members | 1,011 Online
Bytes | Developer Community
Ask Question

Home New Posts Topics Members FAQ

Post your question to a community of 467,161 developers. It's quick & easy.

Recursive import within packages


all examples performed with:

Python 2.3+ (#2, Aug 10 2003, 11:09:33)
[GCC 3.3.1 20030728 (Debian prerelease)] on linux2
(2, 3, 0, 'final', 1)

This is a recursive import:

-- blapp.py --
print "Blapp start"
import blupp
print "Blapp end"

-- blupp.py --
print "Blupp start"
import blapp
print "Blupp end"
This works like a charm:
import blapp Blapp start
Blupp start
Blupp end
Blapp end
The same files with a directory thing with __init__:
from thing import blapp Blapp start
Blupp start
Blupp end
Blapp end

Changing the imports to import thing.blupp and import thing.blapp:
from thing import blapp Blapp start
Blupp start
Blupp end
Blapp end

Adding a print of the module with:

print "Blapp end", blupp
results in:
import blapp Blapp start
Blupp start
Blupp end <module 'blapp' from 'blapp.py'>
Blapp end <module 'blupp' from 'blupp.py'>


Changing to:

import thing.blapp as blapp

and vice versa

from thing import blapp Blapp start
Blupp start
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "thing/blapp.py", line 2, in ?
import thing.blupp as blupp
File "thing/blupp.py", line 2, in ?
import thing.blapp as blapp
AttributeError: 'module' object has no attribute 'blapp'

Changing to:

from thing import blapp

and vice versa

from thing import blapp Blapp start
Blupp start
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "thing/blapp.py", line 2, in ?
from thing.blupp import blupp
File "thing/blupp.py", line 2, in ?
from thing import blapp
ImportError: cannot import name blapp


And finally:

print "Blapp start"
import thing.blupp
print "Blapp end", thing.blupp
(and vice versa)

from thing import blapp Blapp start
Blupp start
Blupp end
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "thing/blapp.py", line 2, in ?
import thing.blupp
File "thing/blupp.py", line 3, in ?
print "Blupp end", thing.blapp
AttributeError: 'module' object has no attribute 'blapp'
Adding a print of dir(thing) verifies this:

-- blapp.py -- (and vice versa)
print "Blapp start"
import thing.blupp
print dir(thing)
print "Blapp end"

import thing.blupp Blupp start
Blapp start
['__builtins__', '__doc__', '__file__', '__name__', '__path__']
Blapp end
['__builtins__', '__doc__', '__file__', '__name__', '__path__', 'blapp']
Blupp end

-- blapp.py --

print "Blapp start"
import thing.blupp
import thing.notexisting
print "Blapp end", thing.blupp
from thing import blupp

Blupp start
Blapp start
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "thing/blupp.py", line 2, in ?
import thing.blapp
File "thing/blapp.py", line 3, in ?
import thing.notexisting
ImportError: No module named notexisting

Now, could anyone please explain to me the logic involved here?

Why is circular import only valid when accessing them without package
name? It clearly works by not using full references, even to print the
module while the other module is being loaded.

The user-fix to the problem is of course:

a) Don't use circular references
b) delay circular import until module usage
(ie. within class/function)
c) Use relative modulenames (works only within the same package)
d) import thing.blapp - but don't expect thing.blapp to be there
until module usage (ie. within class/function)
But my question is why this works outside packages, but not inside
packages. This must be a bug, but I can't find it anywhere in the bugs
section on SourceForge.

(A google search for 'circular import' on Google seems impossible =) Way
too many circle-square-shape-examples!)

The FAQ says:

Circular imports are fine where both modules use the "import <module>"
form of import. They fail when the 2nd module wants to grab a name
out of the first ("from module import name") and the import is at
the top level. That's because names in the 1st are not yet available,
(the first module is busy importing the 2nd).

However that is not correct in this case, the "thing" module is loaded
and works fine, it is the name thing.blapp that is not registered until
after blapp is loaded. In my opinion thing.blapp should be bound before
the actuall import of thing.blapp.

Actually, thing.blapp gets registered into sys.modules right away.
--
Stian Siland Being able to break security doesn't make
Trondheim, Norway you a hacker more than being able to hotwire
http://stain.portveien.to/ cars makes you an automotive engineer. [ESR]
Jul 18 '05 #1
  • viewed: 6548
Share:

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

16 posts views Thread by Manlio Perillo | last post: by
5 posts views Thread by Steve Holden | last post: by
1 post views Thread by mirandacascade@yahoo.com | last post: by
reply views Thread by Anders J. Munch | last post: by
5 posts views Thread by Jandre | last post: by
12 posts views Thread by =?Utf-8?B?am9uaWdy?= | last post: by
2 posts views Thread by sebastien.abeille@gmail.com | last post: by
5 posts views Thread by luca72 | last post: by
3 posts views Thread by jrh | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.