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