Python Enumerations Through Modules

Why is the Python 3 rule not evenly checking that the boundaries of a module are uniform if the enumeration was defined in the main module? Here is an example:

moduleA.py:

#!/usr/bin/python3 import moduleB from enum import Enum, unique @unique class MyEnum(Enum): A = 1 B = 2 # def __eq__(self,other): # assert isinstance(other,self.__class__) # return self.value == other.value if __name__ == "__main__": myVar = MyEnum.B moduleB.doStuff(myVar) 

moduleB.py:

 #!/usr/bin/python3 import moduleA def doStuff(aVariable): bVariable = moduleA.MyEnum.B assert aVariable == bVariable 

Calling "./moduleA.py" on the command line gives:

 Traceback (most recent call last): File "./moduleA.py", line 17, in <module> moduleB.doStuff(myVar) File "/home/ruedi/Dropbox/Reps/stuffed/sosy/testing/moduleB.py", line 7, in doStuff assert aVariable == bVariable AssertionError 

Uncommenting the user equality operator in an enumeration results in an assertion error. I found that the class module is not the same in both cases, since it is "__main__" in one case.

What is the most "pythonic way" to solve this problem (other than moving the enumeration to its own module)?

EDIT: Switching to "aVariable is bVariable" also does not work:

 Traceback (most recent call last): File "./moduleA.py", line 17, in <module> moduleB.doStuff(myVar) File "/home/ruedi/Dropbox/Reps/stuffed/sosy/testing/moduleB.py", line 7, in doStuff assert aVariable is bVariable AssertionError 
+6
source share
1 answer

As for Python, you have three modules:

  • __main__
  • moduleA
  • moduleB

The file that you run from the command line, the main entry point, is always saved as the __main__ module. If you import moduleA anywhere in the code, Python sees this as separate from the __main__ module and creates a new module object instead. Thus, you have two separate MyEnum classes:

  • __main__.MyEnum
  • moduleA.MyEnum

Their members are different and therefore cannot be equal.

Your test passes if, instead of import moduleA you used import __main__ as moduleA or you used a separate script file to manage the test; this separate file will become __main__ :

 #!/usr/bin/python3 # test.py, separate from moduleA.py and moduleB.py import moduleA import moduleB if __name__ == "__main__": myVar = moduleA.MyEnum.B moduleB.doStuff(myVar) 

Another workaround would be to tell Python that __main__ and moduleA are the same thing; before importing moduleA (or moduleB , which imports moduleA ), you can add another entry to sys.modules :

 if __name__ == '__main__': import sys sys.modules['moduleA'] = sys.modules['__main__'] import moduleB 

I would not consider this Pythonic.

+10
source

Source: https://habr.com/ru/post/977279/


All Articles