[Python-ideas] Improve import mechanism for circular imports

Victor Varvariuc victor.varvariuc at gmail.com
Tue Apr 10 11:30:34 CEST 2012


Consider the following directory structure (Python 3):

[test]
    main.py
    [tree]
        __init__.py # empty
        branch.py
        root.py

main.py:

print('main: Entered the module')
print('main: from tree import root')from tree import root # this first
finished importing module 'tree.root'# then creates local name 'root'
which references that imported module# Why not creating local name
'root' at the same time when sys.modules['tree.root'] is created?# If
import fails:# - either delete the attribute 'root'# - or leave it -
how it affects the runtime?from tree import branch
print('main: Creating a root and a leaf attached to it')
_root = root.Root()_branch = branch.Branch(_root)


branch.py:

print('tree.branch: Entered the module')
import tree, sysprint("tree.branch: 'root' in dir(tree) ->", 'root' in
dir(tree))print("tree.branch: 'tree.root' in sys.modules ->",
'tree.root' in sys.modules)
print('tree.branch: from tree import root')#from tree import root #
ImportError: cannot import name root import tree.root # workaroundroot
= sys.modules['tree.root'] # though name 'root' does not exist yet in
module 'tree', sys.modules['root.tree'] already does
print('tree.branch: Defining class branch.Branch()')
class Branch():
    def __init__(self, _parent):
        assert isinstance(_parent, root.Root), 'Pass a `Root` instance'


root.py:

print('tree.root: Entered the module')
print('tree.root: from tree import branch')from tree import branch
print('tree.root: Defining class Root()')
class Root():
    def attach(self, _branch):
        assert isinstance(_branch, branch.Branch), 'Pass a `Branch` instance'
        self.branch = _branch


Running it:

vic at wic:~/projects/test$ python3 main.py main: Entered the modulemain:
from tree import roottree.root: Entered the moduletree.root: from tree
import branchtree.branch: Entered the moduletree.branch: 'root' in
dir(tree) -> Falsetree.branch: 'tree.root' in sys.modules ->
Truetree.branch: from tree import roottree.branch: Defining class
branch.Branch()tree.root: Defining class Root()main: Creating a root
and a leaf attached to it


So,
There are circular imports in this example code.
Currently, `root = sys.modules['tree.root']` hack in branch.py works.
Wouldn't it be useful to create attribute `root` in `main` at the same time
`sys.modules['tree.root']` is created when doing `from tree import root` in
main?
This would solve more complex cases with when circular imports are
involved, without applying such hacks.

Thank you
--
*Victor *
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20120410/a3fa28dc/attachment.html>


More information about the Python-ideas mailing list