Skip to content

Commit a6ed80e

Browse files
committed
enum.md: Update according to enum.py.
Signed-off-by: Ihor Nehrutsa <Ihor.Nehrutsa@gmail.com>
1 parent 3610c16 commit a6ed80e

1 file changed

Lines changed: 79 additions & 82 deletions

File tree

python-stdlib/enum/enum.md

Lines changed: 79 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,117 @@
1-
Below is the documentation for your `enum.py` library. This file explains the core concepts of your custom `Enum` implementation and provides practical examples for embedded development and general logic.
1+
# Enum Library
22

3-
---
4-
5-
# Custom Enum Library for Python & MicroPython
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.
64

7-
This library provides a flexible, memory-efficient `Enum` class designed for dynamic usage and seamless mathematical integration. Unlike the standard CPython `Enum`, this version allows for runtime expansion and direct arithmetic operations without needing to access a `.value` property.
5+
---
86

97
## Core Features
10-
* **Transparent Math**: Supports arithmetic (`+`, `-`, `*`, `/`) and bitwise (`&`, `|`, `^`, `<<`, `>>`) operations directly on enum members.
11-
* **Dynamic Expansion**: Add new members at runtime via `.append()` or direct attribute assignment.
12-
* **Memory Efficient**: Uses `__slots__` in the `ValueWrapper` to minimize RAM usage on platforms like the ESP32.
13-
* **Flexible Initialization**: Can be initialized via class inheritance, dictionaries, or keyword arguments.
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.
1415

1516
---
1617

1718
## Usage Examples
1819

19-
### 1. Hardware Pin Configuration (ESP32)
20-
Define your hardware pins using class inheritance. You can skip internal or reserved pins using the `__skipped__` attribute.
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.
2122

2223
```python
2324
from enum import Enum
2425

25-
class Pins(Enum):
26-
# Members defined at class level
27-
LED = 2
28-
BUTTON = 4
29-
# Members to exclude from the enum mapping
30-
__skipped__ = ('RESERVED_PIN',)
31-
RESERVED_PIN = 0
26+
class Color(Enum):
27+
RED = 'red'
28+
GREEN = 'green'
3229

33-
# You can also add pins during instantiation
34-
pins = Pins(SDA=21, SCL=22)
30+
# Initialize the enum to process attributes
31+
c = Color()
3532

36-
print(f"I2C SDA Pin: {pins.SDA}") # Output: 21
37-
print(f"Is pin 21 valid? {pins.is_value(21)}") # Output: True
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
3837
```
3938

40-
### 2. Math and Register Logic
41-
The `ValueWrapper` allows you to perform calculations directly. This is particularly useful for bitmasks and step-based logic.
42-
43-
```python
44-
# Initialize with key-value pairs
45-
brightness = Enum(MIN=0, STEP=25, MAX=255)
4639

47-
# Direct arithmetic (Forward and Reflected)
48-
next_level = brightness.MIN + brightness.STEP // 2
49-
complex_math = 100 + brightness.STEP
40+
### 2. Reverse Lookup
41+
The library provides two ways to find a member based on its raw value.
5042

51-
print(f"Next Level: {next_level}") # Output: 12
52-
print(f"Complex Math: {complex_math}") # Output: 125
53-
54-
# Bitwise operations for register control
55-
flags = Enum(BIT_0=0x01, BIT_1=0x02)
56-
combined = flags.BIT_0 | flags.BIT_1
57-
print(f"Combined Flags: {hex(combined)}") # Output: 0x03
43+
```python
44+
class Status(Enum):
45+
IDLE = 0
46+
RUNNING = 1
47+
48+
# Method A: Via Class (Simulates interpreting hardware/network bytes)
49+
# Uses __new__ logic to return the correct EnumValue
50+
current_status = Status(1)
51+
print(current_status.name) # Output: RUNNING
52+
print(current_status) # Output: RUNNING: 1
53+
print(current_status()) # Output: 1
54+
55+
# Method B: Via Instance Call
56+
s = Status()
57+
print(s(0).name) # Output: IDLE
58+
print(s(0)) # Output: IDLE: 0
59+
print(s(0)()) # Output: 0
5860
```
5961

60-
### 3. Dynamic State Machines
61-
You can expand an `Enum` as your program logic progresses, such as adding states to a connection manager.
62-
63-
```python
64-
status = Enum(IDLE=0, CONNECTING=1)
6562

66-
# Add multiple members via append()
67-
status.append(CONNECTED=2, ERROR=3)
63+
### 3. Functional API (Dynamic Creation)
64+
If you need to create an Enum from external data (like a JSON config), use the functional constructor.
6865

69-
# Add a single member via direct assignment
70-
status.DISCONNECTING = 4
66+
```python
67+
# Create a dynamic Enum instance
68+
State = Enum(name='State', names={'ON': 1, 'OFF': 2})
7169

72-
for name, val in status.items():
73-
print(f"Status {name} has code {val}")
70+
print(State.ON) # Output: ON: 1
71+
assert State.ON == 1 # Comparison with raw value
7472
```
7573

76-
### 4. Working with Different Data Types
77-
Enums are not restricted to integers; they can wrap strings, floats, and booleans.
78-
79-
```python
80-
commands = Enum(
81-
START="CMD_START",
82-
STOP="CMD_STOP",
83-
TIMEOUT=5.5,
84-
IS_ACTIVE=True
85-
)
86-
87-
if commands.IS_ACTIVE:
88-
# Use str() to get the wrapped string value
89-
print(f"Executing: {commands.START}")
90-
```
9174

92-
### 5. Introspection and Utilities
93-
The library provides helper methods to validate values or find keys based on their values.
75+
### 4. Serialization (Repr / Eval)
76+
The library ensures that the string representation can be used to perfectly reconstruct the object.
9477

9578
```python
96-
class ErrorCodes(Enum):
97-
NOT_FOUND = 404
98-
SERVER_ERROR = 500
79+
colors = Color()
80+
# Get serialized string
81+
serialized = repr(colors)
82+
# Reconstruct object
83+
restored_colors = eval(serialized)
9984

100-
# Check if a value exists in the Enum
101-
exists = ErrorCodes.is_value(404) # True
85+
print(f"Original: {colors}") # Output: Original: Color(names={'ON': 1, 'OFF': 2, 'GREEN': 'green', 'RED': 'red'})
86+
print(f"Restored: {restored_colors}") # Output: Restored: Color(names={'ON': 1, 'OFF': 2, 'GREEN': 'green', 'RED': 'red'})
87+
print(colors == restored_colors) # Output: True
10288

103-
# Get the formatted string name from a value
104-
name = ErrorCodes.key_from_value(500)
105-
print(name) # Output: ErrorCodes.SERVER_ERROR
10689
```
10790

91+
10892
---
10993

11094
## API Reference
11195

112-
### `ValueWrapper`
113-
The internal class that wraps values to enable mathematical transparency.
114-
* `.value`: Access the raw value.
115-
* `()`: Calling the object returns the raw value.
96+
### `EnumValue`
97+
The object representing a specific member of an Enum.
98+
* `.name`: The string name of the member.
99+
* `.value`: The raw value associated with the member.
100+
* `()`: Calling the member object returns its raw value (e.g., `c.RED() -> 'red'`).
101+
102+
### `Enum`
103+
The base class for all enumerations.
104+
* `list_members()`: Returns a list of `(name, value)` tuples for all defined members.
105+
* `is_value(value)`: Returns `True` if the provided raw value exists within the Enum.
106+
* `__len__`: Returns the total number of members.
107+
* `__iter__`: Allows looping through members (e.g., `[m.name for m in color_inst]`).
108+
109+
---
116110

117-
### `Enum` (Inherits from `dict`)
118-
* `append(arg=None, **kwargs)`: Adds new members to the Enum.
119-
* `is_value(value)`: Returns `True` if the value exists in the Enum.
120-
* `key_from_value(value)`: Returns the string representation (e.g., `ClassName.KEY`) for a given value.
111+
## Error Handling
112+
* **`AttributeError`**:
113+
* Raised when attempting to modify an `EnumValue`.
114+
* Raised when attempting to add new members to an initialized Enum.
115+
* Raised when a class-level lookup (`Status(999)`) fails.
116+
* **`ValueError`**:
117+
* Raised when an instance-level lookup (`s(999)`) fails.

0 commit comments

Comments
 (0)