1

If I'm doing interactive work in Python and have an Enum that looks like this

from enum import Enum
class UnsafeColor(Enum):
     RED = 1
     GREEN = 2
     BLUE = 3

I may do

[In]: socks = UnsafeColor.RED
<rerun file>
[In]: shoes = UnsafeColor.RED
[In]: socks == shoes
[Out]: False

This is kind of surprising, but the problem is that rerunning the file has created a new UnsafeColor class with members that is not equal to the old one. I can avoid this by doing something like

from functools import lru_cache
try:
    get_interactive_safe_enum
except NameError as e:
    @lru_cache(maxsize=None)
    def get_interactive_safe_enum(*args, **kwargs):
        return Enum(*args, **kwargs)

SafeColor = get_interactive_safe_enum("SafeColor", "RED GREEN BLUE")

Now the following works as expected:

[In]: hat = SafeColor.RED
<rerun file>
[In]: shirt = SafeColor.RED
[In]: hat == shirt
[Out]: True

This works, but it's not winning any awards. There appears to be lots of singleton and metaclass magic going on with Enum, so I wonder, is there a better way to accomplish this?

kuzzooroo
  • 6,788
  • 11
  • 46
  • 84

1 Answers1

2

The issue you are experiencing is the <rerun file> step. In Python 2 that was a built-in spelled reload() and in Python 3 it was hidden away in a module because it was an attractive nuisance -- for precisely the reasons you state above.

Python is not designed to have any of its modules "rerun", and you will find that every module with singletons that were saved before the rerun (such as your socks above) will have copies in the new, rerun file (your shoes above).

In other words, this is not an Enum problem -- it's the way Python is designed. If you rerun a module, take care to update anything you have previously saved -- module variables, functions, classes, and singletons.


To add some hopefully helpful advice -- keep your constants and things that won't need to be reloaded in their own file; when the <rerun file> get's rerun it will still be importing the already-run-and-not-run-again constants file, and your Enums and other constants will be the same.

Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
  • I do this `` business with `` in Spyder. Your advice sounds like a practical way to deal with this that is less involved than creating a special `Enum` variant. – kuzzooroo Dec 30 '20 at 21:19