0
# Utilities and Advanced Features
1
2
Helper functions, decorators, and classes for working with enumerations including uniqueness validation, runtime extension, conversion utilities, and named constants.
3
4
## Capabilities
5
6
### Validation and Decorators
7
8
#### unique
9
10
Decorator that ensures all enum members have unique values, preventing duplicate values that would create aliases.
11
12
```python { .api }
13
def unique(enumeration):
14
"""
15
Decorator to ensure enum members have unique values.
16
17
Args:
18
enumeration: Enum class to validate
19
20
Returns:
21
The enum class if all values are unique
22
23
Raises:
24
ValueError: If duplicate values are found
25
"""
26
```
27
28
#### Usage Example
29
30
```python
31
from aenum import Enum, unique
32
33
@unique
34
class Color(Enum):
35
RED = 1
36
GREEN = 2
37
BLUE = 3
38
# CRIMSON = 1 # Would raise ValueError: duplicate value found for 'CRIMSON': 1
39
40
# Without decorator, duplicates create aliases
41
class Status(Enum):
42
ACTIVE = 1
43
RUNNING = 1 # This creates an alias: Status.RUNNING is Status.ACTIVE
44
STOPPED = 2
45
46
print(Status.ACTIVE is Status.RUNNING) # True (alias)
47
```
48
49
### Runtime Enum Modification
50
51
#### extend_enum
52
53
Add new members to an existing enumeration after it has been created.
54
55
```python { .api }
56
def extend_enum(enumeration, name, *args, **kwds):
57
"""
58
Add new members to an existing enumeration.
59
60
Args:
61
enumeration: Existing enum class
62
name (str): Name of the new member
63
*args: Value(s) for the new member
64
**kwds: Additional keyword arguments
65
66
Returns:
67
The new enum member
68
"""
69
```
70
71
#### Usage Example
72
73
```python
74
from aenum import Enum, extend_enum
75
76
class Color(Enum):
77
RED = 1
78
GREEN = 2
79
BLUE = 3
80
81
# Add new member after creation
82
extend_enum(Color, 'YELLOW', 4)
83
print(Color.YELLOW) # Color.YELLOW
84
print(Color.YELLOW.value) # 4
85
86
# Works with any enum type
87
from aenum import Flag
88
class Permission(Flag):
89
READ = 1
90
WRITE = 2
91
92
extend_enum(Permission, 'EXECUTE', 4)
93
combined = Permission.READ | Permission.EXECUTE
94
print(combined) # Permission.READ|EXECUTE
95
```
96
97
98
#### export
99
100
Export enum members to a namespace (typically globals()) for direct access.
101
102
```python { .api }
103
def export(enum_class, namespace=None):
104
"""
105
Export enum members to a namespace.
106
107
Args:
108
enum_class: Enum class whose members to export
109
namespace (dict): Target namespace (defaults to caller's globals)
110
"""
111
```
112
113
#### Usage Example
114
115
```python
116
from aenum import Enum, export
117
118
class Color(Enum):
119
RED = 1
120
GREEN = 2
121
BLUE = 3
122
123
# Export to current namespace
124
export(Color, globals())
125
126
# Now can use directly without Color prefix
127
print(RED) # Color.RED
128
print(GREEN) # Color.GREEN
129
print(BLUE) # Color.BLUE
130
131
# Useful in configuration modules
132
class Settings(Enum):
133
DEBUG = True
134
DATABASE_URL = 'postgresql://localhost/myapp'
135
CACHE_TIMEOUT = 300
136
137
export(Settings, globals())
138
# Now DEBUG, DATABASE_URL, CACHE_TIMEOUT are available directly
139
```
140
141
### Value Generation
142
143
#### auto
144
145
Placeholder for automatic value assignment in enumerations.
146
147
```python { .api }
148
class auto:
149
"""
150
Placeholder class for automatic value assignment.
151
152
Usage:
153
Use as a value in enum definitions to get auto-generated values.
154
"""
155
```
156
157
#### Usage Example
158
159
```python
160
from aenum import Enum, auto
161
162
class Direction(Enum):
163
NORTH = auto() # Gets value 1
164
SOUTH = auto() # Gets value 2
165
EAST = auto() # Gets value 3
166
WEST = auto() # Gets value 4
167
168
print(Direction.NORTH.value) # 1
169
170
# Custom auto value generation
171
class Color(Enum):
172
def _generate_next_value_(name, start, count, last_values):
173
return name.lower()
174
175
RED = auto() # Gets value 'red'
176
GREEN = auto() # Gets value 'green'
177
BLUE = auto() # Gets value 'blue'
178
179
print(Color.RED.value) # 'red'
180
```
181
182
#### enum
183
184
Helper class for creating enum members with keyword arguments.
185
186
```python { .api }
187
class enum:
188
"""
189
Helper class for creating members with keywords.
190
191
Args:
192
*args: Positional arguments for the member
193
**kwargs: Keyword arguments for the member
194
"""
195
```
196
197
#### Usage Example
198
199
```python
200
from aenum import Enum, enum
201
202
class Planet(Enum):
203
MERCURY = enum(3.303e+23, 2.4397e6, name='Mercury')
204
VENUS = enum(4.869e+24, 6.0518e6, name='Venus')
205
EARTH = enum(5.976e+24, 6.37814e6, name='Earth')
206
207
def __init__(self, mass, radius, name=None):
208
self.mass = mass
209
self.radius = radius
210
self.display_name = name or self.name.title()
211
212
print(Planet.EARTH.display_name) # 'Earth'
213
```
214
215
### Named Constants
216
217
#### NamedConstant
218
219
Base class for creating groups of named constants that cannot be changed after creation.
220
221
```python { .api }
222
class NamedConstant:
223
"""
224
Base class for named constants.
225
Members are immutable after class creation.
226
"""
227
228
def __setattr__(self, name, value):
229
"""Prevent modification of constants."""
230
231
def __delattr__(self, name):
232
"""Prevent deletion of constants."""
233
```
234
235
#### Usage Example
236
237
```python
238
from aenum import NamedConstant
239
240
class DatabaseConfig(NamedConstant):
241
HOST = 'localhost'
242
PORT = 5432
243
DATABASE = 'myapp'
244
MAX_CONNECTIONS = 100
245
TIMEOUT = 30
246
247
# Access constants
248
print(DatabaseConfig.HOST) # 'localhost'
249
print(DatabaseConfig.PORT) # 5432
250
251
# Cannot modify
252
try:
253
DatabaseConfig.HOST = 'newhost' # Raises AttributeError
254
except AttributeError as e:
255
print(f"Cannot modify: {e}")
256
257
# Iteration support
258
for name, value in DatabaseConfig.__members__.items():
259
print(f"{name}: {value}")
260
```
261
262
#### Constant (alias for NamedConstant)
263
264
```python { .api }
265
Constant = NamedConstant # Alias for shorter name
266
```
267
268
#### constant
269
270
Descriptor for creating constant values in classes.
271
272
```python { .api }
273
class constant:
274
"""
275
Descriptor for constant values.
276
277
Args:
278
value: The constant value
279
doc (str): Optional documentation
280
"""
281
282
def __init__(self, value, doc=None):
283
self.value = value
284
self.doc = doc
285
286
def __get__(self, obj, objtype=None):
287
return self.value
288
289
def __set__(self, obj, value):
290
raise AttributeError("Cannot modify constant")
291
```
292
293
#### Usage Example
294
295
```python
296
from aenum import constant
297
298
class MathConstants:
299
PI = constant(3.14159, "The ratio of a circle's circumference to its diameter")
300
E = constant(2.71828, "Euler's number")
301
GOLDEN_RATIO = constant(1.61803, "The golden ratio")
302
303
print(MathConstants.PI) # 3.14159
304
305
# Cannot modify
306
try:
307
MathConstants.PI = 3.14 # Raises AttributeError
308
except AttributeError as e:
309
print(f"Cannot modify constant: {e}")
310
```
311
312
### Member Control
313
314
#### member
315
316
Force an item to become an enum member during class creation.
317
318
```python { .api }
319
class member:
320
"""
321
Force item to become an Enum member.
322
323
Args:
324
value: Value to make into a member
325
"""
326
```
327
328
#### skip / nonmember
329
330
Prevent attributes from becoming enum members or constants.
331
332
```python { .api }
333
class skip:
334
"""
335
Prevent attributes from becoming constants/enum members.
336
337
Args:
338
value: Value to skip
339
"""
340
341
nonmember = skip # Alias
342
```
343
344
#### Usage Example
345
346
```python
347
from aenum import Enum, member, skip
348
349
class Status(Enum):
350
ACTIVE = 1
351
INACTIVE = 2
352
353
# Force these to be members even though they might look like methods
354
count = member(lambda self: len(self.__class__))
355
356
# Skip these from becoming members
357
database_connection = skip(None)
358
_private_attr = skip("internal")
359
360
@skip
361
def helper_method(self):
362
return "This won't be an enum member"
363
364
print(Status.count) # Status.count
365
print(Status.ACTIVE.count()) # 2 (number of enum members)
366
print(Status.database_connection) # None (not an enum member)
367
```
368
369
### Advanced Utilities
370
371
#### Properties for Enums
372
373
Enhanced property support for enumeration classes.
374
375
```python { .api }
376
class property:
377
"""
378
Enhanced property for enums.
379
Supports enum-specific behavior.
380
"""
381
382
class enum_property(property):
383
"""
384
Property enabling enum members to have same-named attributes.
385
Deprecated: Use property instead.
386
"""
387
```
388
389
#### Usage Example
390
391
```python
392
from aenum import Enum, property
393
394
class Circle(Enum):
395
SMALL = 1
396
MEDIUM = 5
397
LARGE = 10
398
399
@property
400
def area(self):
401
import math
402
return math.pi * (self.value ** 2)
403
404
@property
405
def circumference(self):
406
import math
407
return 2 * math.pi * self.value
408
409
print(Circle.LARGE.area) # ~314.16
410
print(Circle.SMALL.circumference) # ~6.28
411
```
412
413
### Integration and Compatibility
414
415
#### Stdlib Integration
416
417
```python { .api }
418
def add_stdlib_integration():
419
"""Add integration with Python's standard library enum."""
420
421
def remove_stdlib_integration():
422
"""Remove standard library enum integration."""
423
```
424
425
#### Usage Example
426
427
```python
428
from aenum import add_stdlib_integration, Enum, IntEnum
429
import enum as stdlib_enum
430
431
# Enable stdlib compatibility
432
add_stdlib_integration()
433
434
# Now aenum enums work with stdlib enum functions
435
class Color(IntEnum):
436
RED = 1
437
GREEN = 2
438
BLUE = 3
439
440
print(isinstance(Color.RED, stdlib_enum.Enum)) # True
441
```
442
443
#### Pickle Support
444
445
```python { .api }
446
def _reduce_ex_by_name(self, proto):
447
"""Pickle reducer by name for enum members."""
448
449
def make_class_unpicklable(cls):
450
"""Disable pickling for a class."""
451
```
452
453
### Python Version Compatibility
454
455
#### getargspec
456
457
Function to inspect function signatures in a cross-Python-version compatible way.
458
459
```python { .api }
460
def getargspec(method):
461
"""
462
Get function argument specification.
463
464
Args:
465
method: Function to inspect
466
467
Returns:
468
tuple: (args, varargs, keywords, defaults)
469
"""
470
```
471
472
#### raise_with_traceback
473
474
Raise an exception with a specific traceback in a Python version-compatible way.
475
476
```python { .api }
477
def raise_with_traceback(exc, tb):
478
"""
479
Raise exception with traceback (Python 2/3 compatible).
480
481
Args:
482
exc: Exception instance to raise
483
tb: Traceback object
484
"""
485
```
486
487
#### raise_from_none
488
489
Raise an exception without chaining (Python 3 only).
490
491
```python { .api }
492
def raise_from_none(exc):
493
"""
494
Raise exception from None (Python 3 only).
495
496
Args:
497
exc: Exception instance to raise
498
"""
499
```
500
501
### Utility Functions
502
503
#### Bit Operations
504
505
```python { .api }
506
def bin(num, width=None):
507
"""
508
Binary representation with optional width.
509
510
Args:
511
num (int): Number to convert
512
width (int): Minimum width for output
513
514
Returns:
515
str: Binary representation
516
"""
517
518
def bit_count(num):
519
"""
520
Count the number of bits set in an integer.
521
522
Args:
523
num (int): Integer to count bits in
524
525
Returns:
526
int: Number of set bits
527
"""
528
529
def is_single_bit(value):
530
"""
531
Check if a number represents a single bit.
532
533
Args:
534
value (int): Value to check
535
536
Returns:
537
bool: True if value is a power of 2
538
"""
539
```
540
541
#### Usage Example
542
543
```python
544
from aenum import bin, bit_count, is_single_bit
545
546
print(bin(10)) # '0b1010'
547
print(bin(10, 8)) # '0b00001010'
548
print(bit_count(10)) # 2 (bits set in 1010)
549
print(is_single_bit(8)) # True (8 = 2^3)
550
print(is_single_bit(10)) # False (10 = 1010, multiple bits)
551
```
552
553
### Practical Integration Examples
554
555
#### Configuration Management
556
557
```python
558
from aenum import NamedConstant, convert, export
559
560
# Create constants from environment or config file
561
config_dict = {
562
'DEBUG': True,
563
'DATABASE_URL': 'postgresql://localhost/myapp',
564
'REDIS_URL': 'redis://localhost:6379',
565
'SECRET_KEY': 'your-secret-key',
566
'MAX_UPLOAD_SIZE': 10485760 # 10MB
567
}
568
569
# Convert to named constants
570
AppConfig = convert(config_dict, module=__name__)
571
572
# Export for easy access
573
export(AppConfig, globals())
574
575
# Now use directly
576
if DEBUG:
577
print(f"Database: {DATABASE_URL}")
578
```
579
580
#### Dynamic Enum Creation
581
582
```python
583
from aenum import Enum, extend_enum, auto
584
585
# Start with base permissions
586
class Permission(Enum):
587
READ = auto()
588
WRITE = auto()
589
590
# Dynamically add permissions based on features
591
features = ['admin', 'billing', 'analytics']
592
593
for feature in features:
594
perm_name = f"{feature.upper()}_ACCESS"
595
extend_enum(Permission, perm_name, auto())
596
597
print(list(Permission))
598
# [Permission.READ, Permission.WRITE, Permission.ADMIN_ACCESS,
599
# Permission.BILLING_ACCESS, Permission.ANALYTICS_ACCESS]
600
```
601
602
#### Module Constant Export
603
604
```python
605
from aenum import NamedConstant, export
606
607
class HTTPStatus(NamedConstant):
608
OK = 200
609
CREATED = 201
610
BAD_REQUEST = 400
611
UNAUTHORIZED = 401
612
NOT_FOUND = 404
613
INTERNAL_SERVER_ERROR = 500
614
615
class HTTPMethod(NamedConstant):
616
GET = 'GET'
617
POST = 'POST'
618
PUT = 'PUT'
619
DELETE = 'DELETE'
620
621
# Export all constants to module level
622
export(HTTPStatus, globals())
623
export(HTTPMethod, globals())
624
625
# Now available as module-level constants
626
def handle_request(method, status):
627
if method == GET and status == OK:
628
return "Success"
629
elif status == NOT_FOUND:
630
return "Resource not found"
631
```