circular import snafu
Gordon McMillan
gmcm at hypernet.com
Thu Aug 10 08:52:29 EDT 2000
[posted and mailed]
Mookie D. wrote:
>Apologies if this is a rookie move, but I have looked for reasons why
>this may be happening and my trusty Python books and FAQ haven't solved
>it.
>
>I have several modules that by necessity are including each other in a
>circular manner. Depending on which module I load first, I get
>different errors but always end in an error such as
>
> ImportError: cannot import name MailList
>See below for the gory details. I appreciate your suggestions for what
>I ought to be trying or doing differently, or HT debug this.
>Traceback (innermost last):
> File "email.py", line 13, in ?
> import mailboxMgr
> File "/usr/lib/python1.5/ihooks.py", line 396, in import_module
> q, tail = self.find_head_package(parent, name)
ihooks! That's not a rookie move!
> File "/usr/local/dm/webapp/mailboxMgr.py", line 12, in ?
> import email
First problem: Looks like your __main__ is email.py. When mailboxMgr
imports email, it's getting a 2nd copy of email.py. Advice - create a top
level script, say runner.py that says "import email; email.run()".
> File "email.py", line 18, in ?
> import dmpost
> File "dmpost.py", line 29, in ?
That's an odd one - no source!
> File "/home/mailman/Mailman/MailList.py", line 49, in ?
> from webapp import subscription, dmconfig
This form of import is a problem in circular situations, because it can't
complete until subscription and dmconfig are actually loaded. If you used:
import webapp.subscription
import webapp.dmconfig
then the import can complete as soon as webapp is available.
> File "/usr/local/dm/webapp/subscription.py", line 16, in ?
> import email
> File "email.py", line 18, in ?
> import dmpost
> File "dmpost.py", line 29, in ?
>ImportError: cannot import name MailList
Don't know how dmpost imports MailList. If it's with "from", that's a
problem. Another thing you can do is delay some of the imports. If
"scrobble" if module A is the only place in A that module B is used, then
you can use:
def scrobble(...):
import B
...
The 2nd and subsequent times that "import" is hit, it won't do anything,
(although it won't be free, either).
- Gordon
More information about the Python-list
mailing list