On 5/23/2020 2:21 PM, Ralf M. wrote:

##### Code of mod1.py #####
import enum, mod2
class En(enum.Enum):
     A = 1
     B = 2
def main():
     a = mod2.getA()
     print("a is En.A:", a is En.A)
     print("a:", repr(a), "    En.A:", repr(En.A))
     print("id(a), id(a.__class__)", id(a), id(a.__class__))
     print("id(En.A), id(En)      ", id(En.A), id(En))
if __name__ == "__main__":
     main()

> ##### Code of mod2.py #####
> import mod1
> def getA():
>     return mod1.En.A

As a couple of people mentioned, the issue is the circular import. When you run mod1 from a command line, its name is __main__. Its execution of mod1 code stops to execute enum code and then mod2 code.

Execution of mod2 stops to execute mod1 code in a new module named 'mod1'. When the second execution of mod1 code does the import of enum and mod2, sys.modules['enum'] and sys.modules['mod2'] exist, are found, and used to satify the import. So enum and mod2 code are not executed again. In the 'mod1' module, 'mod2' is linked to the *incomplete* mod2. This 'works' in your code because the reference to mod2 within def main is not used because the name is 'mod1', not '__main__'. But if in mod1, you had written

import enum
from mod2 import getA

the second execution of mod1 would fail because mod2.getA does not exist because execution of mod2 is paused to import mod1

When the mod1 import in mod2 finishes, the execution of mod2 code for 'mod2' finishes without issue. Then the execution of 'mod1' code in '__main__' finishes with the call to main.

When you instead interactively import mod1, it is executed just once and you have to explicitly call main.

In idlelib, pyshell currently has the IDLE Shell code, the main() function, and a couple of classes used elsewhere. (An atrocious design that I inherited and have only partly fixed.) As a *temporary* fix to an issue due to there being duplicate '__main__' and 'pyshell' modules, I added the following to the top of pyshell.

import sys
if __name__ == "__main__":
    sys.modules['idlelib.pyshell']=sys.modules['__main__']

But doing what others suggested, limiting the main or start module to one-time code, is better.


--
Terry Jan Reedy


--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to