Skip to content

Conversation

@andrewleech
Copy link
Contributor

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

Implements PEP 435 (Enum) and PEP 663 (Flag) with modular structure:
- Enum, IntEnum with member management and value lookup
- Flag, IntFlag with bitwise operations and combination membership
- StrEnum for string-valued enums (Python 3.11+)
- auto() for automatic value assignment
- @unique decorator for duplicate value prevention

Uses lazy loading to minimize memory footprint (~1.5KB core, ~2.5KB
when all features loaded).

Requires metaclass support:
* MICROPY_PY_METACLASS_INIT for basic enums.
* MICROPY_PY_METACLASS_PREPARE for auto() support.

99.3% compatible with CPython 3.13 enum test suite (445/448 tests pass).
Includes CPython's official test_enum.py for validation.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants