By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,263 Members | 1,537 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,263 IT Pros & Developers. It's quick & easy.

Recursive import within packages

P: n/a

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 Søiland 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
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.