Request for package: micropython-enum
I would like micropython to have support for IntEnum class. Base Enum would be nice to have, although just bare IntEnum would be enough in my opinion.
python-stdlib/enum: Add enum module
Summary
Adds enum package implementing PEP 435 (Enum) and PEP 663 (Flag) with modular lazy-loading structure.
This package provides CPython-compatible enum support for MicroPython, enabling libraries like python-statemachine and providing standard enum functionality for embedded projects.
Features
Complete enum implementation:
- Enum - Base enumeration with member management and value lookup
- IntEnum - Integer-valued enums with arithmetic operations
- Flag - Bitwise flags with |, &, ^, ~ operators
- IntFlag - Integer-compatible bitwise flags
- StrEnum - String-valued enums (Python 3.11+)
- auto() - Automatic value assignment based on insertion order
- @unique - Decorator to prevent duplicate values
Structure
Modular design with lazy loading to minimize memory footprint:
python-stdlib/enum/
├── enum/
│ ├── __init__.py # Entry point with lazy loader (~200 bytes)
│ ├── core.py # Enum, IntEnum, EnumMeta (~1.5KB frozen)
│ ├── flags.py # Flag, IntFlag (~500 bytes, loaded on demand)
│ └── extras.py # StrEnum, auto, unique (~450 bytes, loaded on demand)
├── manifest.py # Package definition
├── README.md # Documentation
└── test_enum.py # CPython's official enum test suite
Total size when frozen: ~5.4KB (core always loaded: ~1.7KB, features loaded on demand: ~950 bytes)
CPython Compatibility
Tested against CPython 3.13's official test_enum.py:
- 448 tests run
- 445 passed (99.3%)
- 3 tests skipped (functional API not implemented)
Works
- All class-based enum definitions
- auto() value generation (requires MICROPY_PY_METACLASS_PREPARE)
- Explicit and mixed values
- Iteration, lookup, comparison, repr
- Flag bitwise operations and combination membership
- @unique decorator
- Type mixins (int, str, float, date)
- Pickling/unpickling
- __members__, dir(), introspection
- Thread-safe enum creation
Not Implemented
- Functional API:
Enum('Name', 'A B C')- use class syntax instead - _missing_(), _ignore_(), _generate_next_value_() hooks
- Boundary modes (STRICT, CONFORM, EJECT, KEEP)
Known Limitation
IntEnum members fail isinstance(member, int) check in MicroPython due to implementation constraints, but all integer operations work correctly. This is a MicroPython limitation, not an enum package issue.
MicroPython Requirements
Requires metaclass support from main MicroPython repo:
- MICROPY_PY_METACLASS_INIT (CORE level) - For basic enum functionality
- MICROPY_PY_METACLASS_OPS (EXTRA level) - For len(EnumClass) and member in EnumClass
- MICROPY_PY_METACLASS_PREPARE (FULL level) - For auto() support
These features are included in the companion PR to micropython/micropython: #18416
Usage
from enum import Enum, IntEnum, Flag, IntFlag, auto
# Basic enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
print(Color.RED) # Color.RED
print(Color.RED.value) # 1
print(Color(1)) # Color.RED
# With auto()
class Status(Enum):
PENDING = auto() # 1
ACTIVE = auto() # 2
DONE = auto() # 3
# Flags
class Permission(Flag):
READ = 1
WRITE = 2
EXECUTE = 4
perm = Permission.READ | Permission.WRITE
print(perm) # Permission.READ|WRITE
print(Permission.READ in perm) # True
Testing
Includes CPython's official test_enum.py (6000+ lines) for validation. Run on MicroPython Unix port:
micropython test_enum.py
Size Impact
When frozen into firmware:
- Core module (Enum, IntEnum): ~1.7KB
- Optional features (Flag, StrEnum, auto): ~950 bytes (loaded on demand)
- Total: ~2.6KB bytecode
Example for STM32 PYBV10:
- Baseline: 368,648 bytes
- With enum frozen: 374,076 bytes (+5,428 bytes = +1.47%)
Related
Companion PR for MicroPython core: micropython/micropython#18416
Enums are especially useful when it comes to static type-checking. So it would be great if the implementation of this enum type allowed type-checking via mypy. This means all values need to be an instance of the defined enum-type.
I'm also interested by enum in MicroPython.
In the meantime, I found here this workaround:
for type-checking, I'm using the following trick:
This workaround is excellent! I combined it with const for my purposes:
+1 for a real implementation of this
But when have been imported getting "Unresolved attribute reference" warning.
The cpython implementation is surprisingly very complicated and relies heavily on metaclasses which aren't supported in micropython:
https://github.com/python/cpython/blob/f585ed19ad00f78ed99ba44be5e333c056076160/Lib/enum.py#L1051
As such any micropython implementation will need to be completely custom really, at which point we need to clearly define which aspects of Enum we want to support first, before figuring out how to implement them!
There are a number of limitations when subclassing builtins in micropython, especially
intbecause behind the scenes it's particularly optimised. Eg. https://docs.micropython.org/en/latest/genrst/builtin_types.html#no-int-conversion-for-int-derived-types-available+1 for an implementation of this as well.
docs/library/enum.rst: Add Enum class. #16842
Implementation in:
micropython-lib/python-stdlib/enum/enum.py: Add Enum class. #980