/python-enum-import-issue

Python Enums aren't singletons—demo

Primary LanguagePython

A small demo in which Python Enums aren't singletons. This causes subtle bugs because is and == don't work as expected.

This demo refers to the Dog.PHOEBE Enum twice. These references turn out to be two separate instances. The code's imports aren't the cleanest. But imports like these are common when tools help add them, or in projects with many developers of different skill levels.

Tested with Python 3.12.1

To run the demo:

PYTHONPATH=src python src/dog_house/main.py

Output:

The enums are not singletons: Dog.PHOEBE/4307352272 vs. Dog.PHOEBE/4307841440
phoebe_1 == phoebe_2: False
phoebe_1 is phoebe_2: False

The issue seems to be when a module (here, db.py) is imported in different ways. Python seems to consider these different modules. This S.O. post seems to be right.

The three files in the demo

db.py

from enum import Enum


class Dog(Enum):
    PHOEBE = 'Phoebe'
    MARU   = 'Maru'

phoebe_1 = Dog.PHOEBE

logic.py

from db import Dog


phoebe_2 = Dog.PHOEBE

main.py

from dog_house.db import phoebe_1
from logic        import phoebe_2


if id(phoebe_1) != id(phoebe_2):
    print(f'The enums are not singletons: {phoebe_1}/{id(phoebe_1)} vs. {phoebe_2}/{id(phoebe_2)}')
    print(f'phoebe_1 == phoebe_2: {phoebe_1 == phoebe_2}')
    print(f'phoebe_1 is phoebe_2: {phoebe_1 is phoebe_2}')
else:
    print('They are the same object.')