I have a Bottle webserver module with the following line:
from foobar.formtools import auto_process_form_insert
And the foobar.formtools module contains this line:
from foobar.webserver import redirect, redirect_back
Of course, both result in the following errors (respectively):
ImportError: cannot import name auto_process_form_insert
ImportError: cannot import name redirect
Is it simply a fact that in Python two modules can’t import each other and all module imports must be hierarchical in nature, or am I doing something wrong? Alternatively, is there a workaround short of placing all these nice functions in new modules?
Modules can import each other cyclically, but there’s a catch. In the simple case, it should work by moving the
importstatements to the bottom of the file or not using thefromsyntax.Here’s why that works:
When you import a module, Python first checks
sys.modules. If it’s in there, it just imports from there. If it’s not there, it tries to import it in the normal way; basically, it finds the file and runs the stuff in it.Running a module populates the module’s contents. For example, say we have this module, creatively named
example_opener:At the start, the module is empty. Then Python executes:
After that, the module only contains
webbrowser. Then Python executes this:Python creates
open_example. Now the module containswebbrowserandopen_example.Say
webbrowsercontained this code:Say
example_openeris imported first. This code is executed:webbrowserhas not yet been imported, so Python executes the contents ofwebbrowser:example_openerhas been imported, but not yet fully executed. Python doesn’t care. Python pulls the module out ofsys.modules. At this point,example_openeris still empty. It hasn’t definedopen_exampleyet, nor even completed importingwebbrowser. Python can’t findopen_exampleinexample_opener, so it fails.What if we imported
open_examplefrom the end ofwebbrowserandwebbrowserfrom the end ofexample_opener? Python would start by executing this code:webbrowserdoes not exist yet, but it doesn’t matter untilopen_exampleis called. Nowexample_openercontains onlyopen_example. It then executes:It has not been imported yet, so Python executes
webbrowser. It starts:It defines
open. Then it executes:example_openeris insys.modules, so it uses that.example_openercontainsopen_example, so it succeeds. Python finishes importingwebbrowser. That concludes importingwebbrowserfromexample_opener. That’s the last thing inexample_opener, so the import ofexample_openerfinishes, successful, as well.