Skip to content

Commit cebb7c0

Browse files
committed
python-stdlib\enum: Version="1.4.0"
Signed-off-by: Ihor Nehrutsa <Ihor.Nehrutsa@gmail.com>
1 parent ca814f2 commit cebb7c0

6 files changed

Lines changed: 559 additions & 435 deletions

File tree

‎python-stdlib/enum/README.md‎

Lines changed: 48 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -1,201 +1,75 @@
1-
# Enum Library
1+
# Lightweight Python Enum (No Metaclasses)
22

3-
This library provides a lightweight, memory-efficient `Enum` implementation designed for MicroPython environments. It focuses on immutability, reverse lookup capabilities, and serialization support without the complexity of metaclasses.
3+
A lightweight Python implementation of enumerations (`Enum`, `IntEnum`, `StrEnum`) created without using metaclasses. Supports class syntax, functional API, strict value type checking, and immutability.
44

5-
---
5+
## ?? Features
66

7-
## Core Features
8-
* **Immutability**: Enum members (`EnumValue`) are protected against modification. Any attempt to change their name or value raises an `AttributeError`.
9-
* **Static Design**: Once an Enum instance is initialized, it is "frozen." You cannot add new attributes or delete existing members.
10-
* **Dual Reverse Lookup**:
11-
* **Class Constructor**: Retrieve a member by value using the class name (e.g., `Status(1)`).
12-
* **Instance Call**: Retrieve a member by value by calling the instance (e.g., `s(1)`).
13-
* **Serialization Support**: Implements `__repr__` such that `obj == eval(repr(obj))`, allowing easy restoration of Enum states.
14-
* **Functional API**: Supports dynamic creation of Enums at runtime.
7+
* **No Metaclasses**: Dynamic type construction using standard `type()`.
8+
* **Types**: Base `Enum`, as well as strictly typed `IntEnum` and `StrEnum`.
9+
* **Dual Syntax**: Declaration via standard `class` statements or functional API calls.
10+
* **Immutability**: Attribute mutation guard preventing changes after member creation.
11+
* **Serialization**: `.dump()` method for easy string representation and reconstruction via `eval()`.
1512

16-
---
13+
## ?? Usage
1714

18-
## Usage Examples
19-
20-
### 1. Standard Class Definition
21-
Define your enumeration by inheriting from the `Enum` class. Class-level constants are automatically converted into `EnumValue` objects upon initialization.
15+
### 1. Class Syntax Declaration
2216

2317
```python
24-
from enum import Enum
18+
from enum import Enum, IntEnum, StrEnum
2519

2620
class Color(Enum):
27-
RED = 'red'
28-
GREEN = 'green'
29-
30-
# Initialize the enum to process attributes
31-
c = Color()
32-
33-
print(c.RED) # Output: RED: red
34-
print(c.RED.name) # Output: RED
35-
print(c.RED.value) # Output: red
36-
print(c.RED()) # Output: red
37-
print(c.is_value("RED")) # Output: true
38-
print(c.is_value(Color.RED)) # Output: true
39-
print(c.is_value('red')) # Output: true
40-
print(c.list()) # Output: [Color.RED: red, Color.GREEN: green]
41-
print([m for m in c]) # Output: [Color.RED: red, Color.GREEN: green]
42-
print([m.name for m in c]) # Output: ['RED', 'GREEN']
43-
print([m.value for m in c]) # Output: ['red', 'green']
44-
```
45-
46-
47-
### 2. Reverse Lookup
48-
The library provides two ways to find a member based on its raw value.
49-
50-
```python
51-
class Status(Enum):
52-
IDLE = 0
53-
RUNNING = 1
54-
55-
# Method A: Via Class (Simulates interpreting hardware/network bytes)
56-
# Uses __new__ logic to return the correct EnumValue
57-
current_status = Status(1)
58-
print(current_status.name) # Output: RUNNING
59-
print(current_status.value) # Output: 1
60-
print(current_status) # Output: Status.RUNNING: 1
61-
print(current_status()) # Output: 1
62-
63-
# Method B: Via Instance Call
64-
s = Status()
65-
print(s(0).name) # Output: IDLE
66-
print(s(0).value) # Output: 0
67-
print(s(0)) # Output: Status.IDLE: 0
68-
print(s(0)()) # Output: 0
69-
```
70-
21+
RED = 1
22+
GREEN = 2
23+
BLUE = 3
7124

72-
### 3. Functional API (Dynamic Creation)
73-
If you need to create an Enum from external data (like a JSON config), use the functional constructor.
25+
class Status(StrEnum):
26+
PENDING = "pending"
27+
DONE = "done"
7428

75-
```python
76-
# Create a dynamic Enum instance
77-
State = Enum(name='State', names={'ON': 1, 'OFF': 2})
78-
79-
print(State) # Output: Enum(name='State', names={'ON': 1, 'OFF': 2})
80-
print(State.ON) # Output: State.ON: 1
81-
print(State.ON.name) # Output: ON
82-
print(State.ON.value) # Output: 1
83-
print(State.ON()) # Output: 1
84-
assert State.ON == 1 # Comparison
85-
assert State.ON() == 1 #
86-
assert State.ON.value == 1 #
87-
assert State.ON.name == "ON" #
29+
# Accessing members
30+
print(Color.RED) # <Color.RED: 1>
31+
print(Color.RED.name) # 'RED'
32+
print(Color.RED.value) # 1
33+
print(Status.PENDING) # 'pending' (for StrEnum, string output equals value)
8834
```
8935

90-
91-
### 4. Serialization (Repr / Eval)
92-
The library ensures that the string representation can be used to perfectly reconstruct the object.
36+
### 2. Functional API
9337

9438
```python
95-
from enum import Enum
96-
97-
class Color(Enum):
98-
RED = 'red'
99-
GREEN = 'green'
100-
BLUE = 3
39+
# Enum with sequential integer values
40+
Priority = Enum("Priority", "LOW MEDIUM HIGH", start=1)
41+
print(Priority.HIGH.value) # 3
10142

102-
colors = Color()
103-
# Get serialized string
104-
serialized = repr(colors)
105-
# Reconstruct object
106-
restored_colors = eval(serialized)
107-
108-
print(f"Original: {colors}") # Output: Original: Enum(name='Color', names={'BLUE': 3, 'RED': 'red', 'GREEN': 'green'})
109-
print(f"Restored: {restored_colors}") # Output: Restored: Enum(name='Color', names={'BLUE': 3, 'RED': 'red', 'GREEN': 'green'})
110-
print(colors == restored_colors) # Output: True
43+
# Enum from a dictionary mapping
44+
HTTPStatus = IntEnum("HTTPStatus", {"OK": 200, "NOT_FOUND": 404})
45+
print(HTTPStatus.NOT_FOUND.value) # 404
11146
```
11247

113-
114-
---
115-
116-
## API Reference
117-
118-
### `EnumValue`
119-
The object representing a specific member of an Enum.
120-
* `.name`: The string name of the member.
121-
* `.value`: The raw value associated with the member.
122-
* `()`: Calling the member object returns its raw value (e.g., `c.RED() -> 'red'`).
123-
124-
### `Enum`
125-
The base class for all enumerations.
126-
* `list()`: Returns a list of all defined members.
127-
* `is_value(value)`: Returns `True` if the provided raw value exists within the Enum.
128-
* `__len__`: Returns the total number of members.
129-
* `__iter__`: Allows looping through members (e.g., `[m.name for m in color_inst]`).
130-
131-
---
132-
133-
## Error Handling
134-
* **`AttributeError`**:
135-
* Raised when attempting to modify an `EnumValue`.
136-
* Raised when attempting to add new members to an initialized Enum.
137-
* Raised when a class-level lookup (`Status(999)`) fails.
138-
* Raised when an instance-level lookup (`s(999)`) fails.
139-
140-
## Compare with CPython
48+
### 3. Lookup, Iteration, and Type Enforcement
14149

14250
```python
143-
# Run on MicroPython v1.28.0 on 2026-04-06; Generic ESP32 module with ESP32
144-
# Run on Python 3.12.10
145-
from enum import Enum
51+
# Lookup by value or name
52+
item = Color(1) # Color.RED
53+
item = Color("RED") # Color.RED
14654

147-
# class syntax
148-
class Color(Enum):
149-
RED = 1
150-
GREEN = 2
151-
BLUE = 3
55+
# Iteration over members
56+
for member in Color:
57+
print(member.name, member.value)
15258

153-
# OR
154-
# functional syntax
155-
# Color = Enum('Color', {'RED': 1, 'GREEN': 2, 'BLUE': 3})
156-
157-
# List enum members
158-
try:
159-
print(list(Color))
160-
# [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>]
161-
except:
162-
print(Color.list())
163-
# [RED: 1, GREEN: 2, BLUE: 3]
164-
165-
# Accessing enum member by name
166-
print(Color.GREEN, type(Color.GREEN))
167-
# Color.GREEN <enum 'Color'>
168-
# GREEN: 2 <class 'EnumValue'>
169-
170-
# Accessing enum member by name
59+
# Strict type checks in IntEnum / StrEnum
17160
try:
172-
print(Color['GREEN'])
173-
# Color.GREEN
174-
except:
175-
print(Color('GREEN'))
176-
# GREEN: 2
177-
178-
# Accessing enum member by value
179-
print(Color(2))
180-
# Color.GREEN
181-
182-
# Accessing enum member name
183-
print(Color.GREEN.name, type(Color.GREEN.name))
184-
# GREEN <class 'str'>
185-
186-
# Accessing enum member value
187-
print(Color.GREEN.value, type(Color.GREEN.value))
188-
# 2 <class 'int'>
61+
class BadEnum(IntEnum):
62+
INVALID = "not an int" # Raises TypeError
63+
except TypeError as e:
64+
print(e)
18965
```
19066

191-
### Output is:
67+
### 4. Serialization & Evaluation
19268

193-
| MicroPython v1.28.0 | Python 3.12.10 |
194-
| :--- | :--- |
195-
| [Color.RED: 1, Color.GREEN: 2, Color.BLUE: 3] | [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>] |
196-
| Color.GREEN: 2 <class 'EnumValue'> | Color.GREEN <enum 'Color'> |
197-
| Color.GREEN: 2 | Color.GREEN |
198-
| Color.GREEN: 2 | Color.GREEN |
199-
| GREEN <class 'str'> | GREEN <class 'str'> |
200-
| 2 <class 'int'> | 2 <class 'int'> |
69+
```python
70+
dump_str = Color.dump()
71+
print(dump_str) # "Enum('Color', {'RED': 1, 'GREEN': 2, 'BLUE': 3})"
20172

73+
# Reconstructing the Enum class object
74+
RestoredColor = eval(dump_str)
75+
```

0 commit comments

Comments
 (0)