0
# Flags and Bitwise Operations
1
2
Flag enumerations that support bitwise operations for combining multiple values. Flags are commonly used for permissions, feature toggles, configuration options, and any scenario where multiple options can be combined.
3
4
## Capabilities
5
6
### Flag
7
8
Base flag enumeration that supports bitwise operations (|, &, ^, ~) to combine and test multiple flag values.
9
10
```python { .api }
11
class Flag(Enum):
12
def __or__(self, other):
13
"""Combine flags using bitwise OR (|)."""
14
15
def __and__(self, other):
16
"""Test flags using bitwise AND (&)."""
17
18
def __xor__(self, other):
19
"""Exclusive OR flags using bitwise XOR (^)."""
20
21
def __invert__(self):
22
"""Invert flags using bitwise NOT (~)."""
23
24
@property
25
def _value_(self):
26
"""The numeric value of the flag."""
27
28
@property
29
def _name_(self):
30
"""The name of the flag."""
31
```
32
33
#### Usage Example
34
35
```python
36
from aenum import Flag, auto
37
38
class Color(Flag):
39
RED = auto()
40
GREEN = auto()
41
BLUE = auto()
42
WHITE = RED | GREEN | BLUE
43
44
# Combining flags
45
purple = Color.RED | Color.BLUE
46
print(purple) # Color.RED|BLUE
47
48
# Testing flags
49
print(Color.RED in purple) # True
50
print(Color.GREEN in purple) # False
51
print(bool(purple & Color.RED)) # True
52
53
# Complex combinations
54
print(Color.WHITE) # Color.WHITE
55
print(Color.WHITE & Color.RED) # Color.RED
56
```
57
58
### IntFlag
59
60
Flag enumeration that subclasses int, allowing flag members to be used in integer operations while maintaining flag behavior.
61
62
```python { .api }
63
class IntFlag(int, Flag):
64
def __init__(self, value):
65
"""
66
Create an integer flag member.
67
68
Args:
69
value (int): Integer value for the flag member
70
"""
71
72
def __new__(cls, value):
73
"""Create and return a new integer flag member."""
74
75
def __or__(self, other):
76
"""Combine with integers or other flags."""
77
78
def __and__(self, other):
79
"""Test with integers or other flags."""
80
```
81
82
#### Usage Example
83
84
```python
85
from aenum import IntFlag
86
87
class Permission(IntFlag):
88
READ = 4
89
WRITE = 2
90
EXECUTE = 1
91
RWX = READ | WRITE | EXECUTE
92
93
# Integer operations
94
user_perms = Permission.READ | Permission.WRITE # 6
95
print(user_perms) # Permission.READ|WRITE
96
print(user_perms == 6) # True
97
print(user_perms + 1) # 7
98
99
# Permission checking
100
def has_permission(user_perms, required_perm):
101
return bool(user_perms & required_perm)
102
103
print(has_permission(user_perms, Permission.READ)) # True
104
print(has_permission(user_perms, Permission.EXECUTE)) # False
105
```
106
107
### FlagBoundary
108
109
Enumeration that defines how flags handle out-of-range values and invalid combinations.
110
111
```python { .api }
112
class FlagBoundary(Enum):
113
STRICT = 'strict' # Raise ValueError for invalid values
114
CONFORM = 'conform' # Discard invalid bits, keep valid ones
115
EJECT = 'eject' # Return plain int for invalid values
116
KEEP = 'keep' # Keep all bits, even invalid ones
117
118
# Boundary constants
119
STRICT: FlagBoundary
120
CONFORM: FlagBoundary
121
EJECT: FlagBoundary
122
KEEP: FlagBoundary
123
```
124
125
#### Usage Example
126
127
```python
128
from aenum import IntFlag, STRICT, CONFORM, EJECT, KEEP
129
130
class StrictColor(IntFlag, boundary=STRICT):
131
RED = 1
132
GREEN = 2
133
BLUE = 4
134
135
class FlexibleColor(IntFlag, boundary=CONFORM):
136
RED = 1
137
GREEN = 2
138
BLUE = 4
139
140
# STRICT: raises ValueError for invalid values
141
try:
142
color = StrictColor(8) # Invalid value
143
except ValueError as e:
144
print(f"Strict mode error: {e}")
145
146
# CONFORM: discards invalid bits
147
color = FlexibleColor(15) # 15 = 1|2|4|8, but 8 is invalid
148
print(color) # FlexibleColor.RED|GREEN|BLUE (8 discarded)
149
```
150
151
### Advanced Flag Patterns
152
153
#### File System Permissions
154
155
```python
156
from aenum import IntFlag
157
158
class FileMode(IntFlag):
159
# Owner permissions
160
OWNER_READ = 0o400
161
OWNER_WRITE = 0o200
162
OWNER_EXECUTE = 0o100
163
164
# Group permissions
165
GROUP_READ = 0o040
166
GROUP_WRITE = 0o020
167
GROUP_EXECUTE = 0o010
168
169
# Other permissions
170
OTHER_READ = 0o004
171
OTHER_WRITE = 0o002
172
OTHER_EXECUTE = 0o001
173
174
# Common combinations
175
OWNER_ALL = OWNER_READ | OWNER_WRITE | OWNER_EXECUTE
176
GROUP_READ_EXECUTE = GROUP_READ | GROUP_EXECUTE
177
OTHER_READ_EXECUTE = OTHER_READ | OTHER_EXECUTE
178
179
# Standard modes
180
MODE_755 = OWNER_ALL | GROUP_READ_EXECUTE | OTHER_READ_EXECUTE
181
MODE_644 = OWNER_READ | OWNER_WRITE | GROUP_READ | OTHER_READ
182
183
# Usage
184
file_mode = FileMode.MODE_755
185
print(oct(file_mode)) # 0o755
186
print(FileMode.OWNER_READ in file_mode) # True
187
```
188
189
#### Feature Toggles
190
191
```python
192
from aenum import Flag, auto
193
194
class Features(Flag):
195
BETA_UI = auto()
196
ADVANCED_SEARCH = auto()
197
REAL_TIME_UPDATES = auto()
198
DARK_MODE = auto()
199
PREMIUM_FEATURES = auto()
200
201
# Feature bundles
202
BASIC = DARK_MODE
203
PREMIUM = BETA_UI | ADVANCED_SEARCH | REAL_TIME_UPDATES | PREMIUM_FEATURES
204
ALL = BETA_UI | ADVANCED_SEARCH | REAL_TIME_UPDATES | DARK_MODE | PREMIUM_FEATURES
205
206
def user_has_feature(user_features, feature):
207
return bool(user_features & feature)
208
209
# User configuration
210
user_features = Features.PREMIUM
211
print(user_has_feature(user_features, Features.BETA_UI)) # True
212
print(user_has_feature(user_features, Features.DARK_MODE)) # False
213
```
214
215
#### HTTP Methods
216
217
```python
218
from aenum import Flag
219
220
class HttpMethod(Flag):
221
GET = 1
222
POST = 2
223
PUT = 4
224
DELETE = 8
225
PATCH = 16
226
HEAD = 32
227
OPTIONS = 64
228
229
# Common combinations
230
SAFE_METHODS = GET | HEAD | OPTIONS
231
IDEMPOTENT_METHODS = GET | PUT | DELETE | HEAD | OPTIONS
232
WRITE_METHODS = POST | PUT | DELETE | PATCH
233
234
def endpoint_supports(allowed_methods, method):
235
return bool(allowed_methods & method)
236
237
# API endpoint configuration
238
api_endpoint_methods = HttpMethod.GET | HttpMethod.POST | HttpMethod.PUT
239
print(endpoint_supports(api_endpoint_methods, HttpMethod.GET)) # True
240
print(endpoint_supports(api_endpoint_methods, HttpMethod.DELETE)) # False
241
```
242
243
### Flag Utilities and Testing
244
245
#### Checking Multiple Flags
246
247
```python
248
from aenum import Flag, auto
249
250
class Status(Flag):
251
ACTIVE = auto()
252
VERIFIED = auto()
253
PREMIUM = auto()
254
ADMIN = auto()
255
256
user_status = Status.ACTIVE | Status.VERIFIED
257
258
# Check if user has all required flags
259
required = Status.ACTIVE | Status.VERIFIED
260
print((user_status & required) == required) # True
261
262
# Check if user has any of the flags
263
any_premium = Status.PREMIUM | Status.ADMIN
264
print(bool(user_status & any_premium)) # False
265
```
266
267
#### Custom Flag Operations
268
269
```python
270
from aenum import Flag, auto
271
272
class NetworkState(Flag):
273
DISCONNECTED = 0
274
CONNECTING = auto()
275
CONNECTED = auto()
276
AUTHENTICATED = auto()
277
ENCRYPTED = auto()
278
279
# Helper methods
280
@classmethod
281
def is_online(cls, state):
282
return bool(state & (cls.CONNECTED | cls.AUTHENTICATED))
283
284
@classmethod
285
def is_secure(cls, state):
286
return bool(state & (cls.AUTHENTICATED | cls.ENCRYPTED))
287
288
# Usage
289
current_state = NetworkState.CONNECTED | NetworkState.AUTHENTICATED
290
print(NetworkState.is_online(current_state)) # True
291
print(NetworkState.is_secure(current_state)) # True
292
```
293
294
## Common Patterns
295
296
### Configuration Systems
297
298
```python
299
from aenum import IntFlag
300
301
class LoggingConfig(IntFlag):
302
CONSOLE = 1
303
FILE = 2
304
SYSLOG = 4
305
EMAIL = 8
306
DATABASE = 16
307
308
# Preset combinations
309
DEVELOPMENT = CONSOLE | FILE
310
PRODUCTION = FILE | SYSLOG | EMAIL
311
DEBUG = CONSOLE | FILE | DATABASE
312
313
logging_config = LoggingConfig.PRODUCTION
314
print(LoggingConfig.EMAIL in logging_config) # True
315
```
316
317
### State Validation
318
319
```python
320
from aenum import Flag, auto
321
322
class ValidationRules(Flag):
323
REQUIRED = auto()
324
NUMERIC = auto()
325
EMAIL_FORMAT = auto()
326
MIN_LENGTH = auto()
327
MAX_LENGTH = auto()
328
CUSTOM_PATTERN = auto()
329
330
def validate_field(value, rules):
331
errors = []
332
333
if ValidationRules.REQUIRED in rules and not value:
334
errors.append("Field is required")
335
336
if ValidationRules.NUMERIC in rules and not value.isdigit():
337
errors.append("Field must be numeric")
338
339
# Additional validation logic...
340
return errors
341
342
# Usage
343
email_rules = ValidationRules.REQUIRED | ValidationRules.EMAIL_FORMAT
344
errors = validate_field("", email_rules)
345
```