Xavier de Gaye <xdeg...@gmail.com> added the comment:
In msg360620 Serhiy wrote: > When the interpreter encounters "import foo" in bar.py, the import machinery > takes the module foo from sys.modules. > So you break an infinite cycle and can import modules with cyclic > dependencies. The following pdb session that is run when executing the foo.py script, shows that this is not quite accurate. When the interpreter encounters "import foo" in bar.py, the import machinery instead starts executing foo.py once again and detects that at line 9 of foo.py the 'import bar' statement does not have to be executed since the import machinery is already in the process of importing this module. So it is at that point that the infinite cycle is broken. Later on line 12 in foo.py the import machinery detects that the AttributeError is raised because of a circular import and warns that "partially initialized module 'bar' has no attribute 'BAR' (most likely due to a circular import)". $ cat -n foo.py 1 import pdb 2 debug = 1 3 4 # Prevent starting a new pdb session when foo is imported by bar. 5 if debug and not hasattr(pdb, 'is_pdb_started'): 6 pdb.Pdb(skip=['importlib*']).set_trace() 7 pdb.is_pdb_started = True 8 9 import bar 10 FOO = 'foo' 11 try: 12 print(bar.BAR) 13 except AttributeError as e: 14 # The exception is raised with an explicit reason when foo is imported by 15 # bar due to partially initialized module 'bar'. 16 print(e) $ cat -n bar.py 1 import foo 2 BAR = 'bar' 3 print(foo.FOO) $ python foo.py > /tmp/foo.py(7)<module>() -> pdb.is_pdb_started = True (Pdb) step > /tmp/foo.py(9)<module>() -> import bar (Pdb) step --Call-- > /tmp/bar.py(1)<module>() -> import foo (Pdb) step > /tmp/bar.py(1)<module>() -> import foo (Pdb) step --Call-- > /tmp/foo.py(1)<module>() -> import pdb (Pdb) step > /tmp/foo.py(1)<module>() -> import pdb (Pdb) step > /tmp/foo.py(2)<module>() -> debug = 1 (Pdb) step > /tmp/foo.py(5)<module>() -> if debug and not hasattr(pdb, 'is_pdb_started'): (Pdb) step > /tmp/foo.py(9)<module>() -> import bar (Pdb) step > /tmp/foo.py(10)<module>() -> FOO = 'foo' (Pdb) step > /tmp/foo.py(11)<module>() -> try: (Pdb) step > /tmp/foo.py(12)<module>() -> print(bar.BAR) (Pdb) step AttributeError: partially initialized module 'bar' has no attribute 'BAR' (most likely due to a circular import) > /tmp/foo.py(12)<module>() -> print(bar.BAR) (Pdb) step > /tmp/foo.py(13)<module>() -> except AttributeError as e: (Pdb) step > /tmp/foo.py(16)<module>() -> print(e) (Pdb) step partially initialized module 'bar' has no attribute 'BAR' (most likely due to a circular import) --Return-- > /tmp/foo.py(16)<module>()->None -> print(e) (Pdb) step > /tmp/bar.py(2)<module>() -> BAR = 'bar' (Pdb) step > /tmp/bar.py(3)<module>() -> print(foo.FOO) (Pdb) step foo --Return-- > /tmp/bar.py(3)<module>()->None -> print(foo.FOO) (Pdb) step > /tmp/foo.py(10)<module>() -> FOO = 'foo' (Pdb) step > /tmp/foo.py(11)<module>() -> try: (Pdb) step > /tmp/foo.py(12)<module>() -> print(bar.BAR) (Pdb) step bar --Return-- > /tmp/foo.py(12)<module>()->None -> print(bar.BAR) (Pdb) step $ ---------- nosy: +xdegaye _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue39430> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com