0
# Command-Line Flags
1
2
Distributed command-line flag system allowing any Python module to define flags that are automatically integrated into a global flag registry. Supports various flag types, validation, help generation, and complex flag relationships.
3
4
## Global Flag Registry
5
6
```python { .api }
7
FLAGS: FlagValues # Global flag registry instance
8
```
9
10
The global `FLAGS` object contains all defined flags and their current values. Access flag values using dot notation: `FLAGS.flag_name`.
11
12
## Capabilities
13
14
### Basic Flag Definition
15
16
Core functions for defining different types of command-line flags.
17
18
```python { .api }
19
def DEFINE_string(name, default, help, flag_values=FLAGS, **args):
20
"""
21
Define a string flag.
22
23
Args:
24
name (str): Flag name
25
default (str): Default value
26
help (str): Help description
27
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
28
**args: Additional arguments (required, short_name, etc.)
29
"""
30
31
def DEFINE_boolean(name, default, help, flag_values=FLAGS, **args):
32
"""
33
Define a boolean flag.
34
35
Args:
36
name (str): Flag name
37
default (bool): Default value
38
help (str): Help description
39
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
40
**args: Additional arguments
41
"""
42
43
def DEFINE_bool(name, default, help, flag_values=FLAGS, **args):
44
"""Alias for DEFINE_boolean to match C++ API."""
45
46
def DEFINE_integer(name, default, help, flag_values=FLAGS, **args):
47
"""
48
Define an integer flag.
49
50
Args:
51
name (str): Flag name
52
default (int): Default value
53
help (str): Help description
54
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
55
**args: Additional arguments (lower_bound, upper_bound, etc.)
56
"""
57
58
def DEFINE_float(name, default, help, flag_values=FLAGS, **args):
59
"""
60
Define a float flag.
61
62
Args:
63
name (str): Flag name
64
default (float): Default value
65
help (str): Help description
66
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
67
**args: Additional arguments (lower_bound, upper_bound, etc.)
68
"""
69
70
def DEFINE_enum(name, default, enum_values, help, flag_values=FLAGS, **args):
71
"""
72
Define an enum flag that accepts one of a predefined set of values.
73
74
Args:
75
name (str): Flag name
76
default (str): Default value (must be in enum_values)
77
enum_values (List[str]): List of allowed values
78
help (str): Help description
79
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
80
**args: Additional arguments
81
"""
82
83
def DEFINE_enum_class(name, default, enum_class, help, flag_values=FLAGS, **args):
84
"""
85
Define an enum flag using a Python Enum class.
86
87
Args:
88
name (str): Flag name
89
default: Default enum value or string name
90
enum_class: Python Enum class
91
help (str): Help description
92
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
93
**args: Additional arguments
94
"""
95
```
96
97
### List and Multi-Value Flags
98
99
Flags that accept multiple values or lists of values.
100
101
```python { .api }
102
def DEFINE_list(name, default, help, flag_values=FLAGS, **args):
103
"""
104
Define a flag that accepts a comma-separated list of strings.
105
106
Args:
107
name (str): Flag name
108
default (List[str]): Default list value
109
help (str): Help description
110
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
111
**args: Additional arguments
112
"""
113
114
def DEFINE_spaceseplist(name, default, help, flag_values=FLAGS, **args):
115
"""
116
Define a flag that accepts a space-separated list of strings.
117
118
Args:
119
name (str): Flag name
120
default (List[str]): Default list value
121
help (str): Help description
122
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
123
**args: Additional arguments
124
"""
125
126
def DEFINE_multi_string(name, default, help, flag_values=FLAGS, **args):
127
"""
128
Define a flag that can be specified multiple times to build a list.
129
130
Example: --multi_flag=value1 --multi_flag=value2 results in ['value1', 'value2']
131
132
Args:
133
name (str): Flag name
134
default (List[str]): Default list value
135
help (str): Help description
136
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
137
**args: Additional arguments
138
"""
139
140
def DEFINE_multi_integer(name, default, help, flag_values=FLAGS, **args):
141
"""Define a multi-value integer flag."""
142
143
def DEFINE_multi_float(name, default, help, flag_values=FLAGS, **args):
144
"""Define a multi-value float flag."""
145
146
def DEFINE_multi_enum(name, default, enum_values, help, flag_values=FLAGS, **args):
147
"""Define a multi-value enum flag."""
148
149
def DEFINE_multi_enum_class(name, default, enum_class, help, flag_values=FLAGS, **args):
150
"""Define a multi-value enum class flag."""
151
```
152
153
### Advanced Flag Definition
154
155
More sophisticated flag definition capabilities.
156
157
```python { .api }
158
def DEFINE_flag(flag, flag_values=FLAGS, **args):
159
"""
160
Define a flag using a Flag object.
161
162
Args:
163
flag (Flag): Pre-constructed Flag instance
164
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
165
**args: Additional arguments
166
"""
167
168
def DEFINE_alias(name, original_name, flag_values=FLAGS, **args):
169
"""
170
Define an alias for an existing flag.
171
172
Args:
173
name (str): New alias name
174
original_name (str): Original flag name
175
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
176
**args: Additional arguments
177
"""
178
179
def DEFINE(parser, name, default, help, flag_values=FLAGS, serializer=None, **args):
180
"""
181
Generic flag definition using a custom parser.
182
183
Args:
184
parser (ArgumentParser): Parser for the flag value
185
name (str): Flag name
186
default: Default value
187
help (str): Help description
188
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
189
serializer (ArgumentSerializer): Custom serializer for the flag
190
**args: Additional arguments
191
"""
192
```
193
194
### Flag Validation
195
196
Functions for validating flag values and relationships between multiple flags.
197
198
```python { .api }
199
def register_validator(flag_name, checker, message='Flag validation failed', flag_values=FLAGS):
200
"""
201
Register a validator function for a flag.
202
203
Args:
204
flag_name (str): Name of flag to validate
205
checker (callable): Function that takes flag value and returns bool
206
message (str): Error message for validation failure
207
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
208
"""
209
210
def validator(flag_name, message='Flag validation failed', flag_values=FLAGS):
211
"""
212
Decorator to register a flag validator.
213
214
Args:
215
flag_name (str): Name of flag to validate
216
message (str): Error message for validation failure
217
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
218
219
Returns:
220
Decorator function
221
"""
222
223
def register_multi_flags_validator(flag_names, multi_flags_checker, message='Flags validation failed'):
224
"""
225
Register a validator for multiple flags.
226
227
Args:
228
flag_names (List[str]): Names of flags to validate together
229
multi_flags_checker (callable): Function that takes flag dict and returns bool
230
message (str): Error message for validation failure
231
"""
232
233
def multi_flags_validator(flag_names, message='Flags validation failed'):
234
"""
235
Decorator to register a multi-flag validator.
236
237
Args:
238
flag_names (List[str]): Names of flags to validate together
239
message (str): Error message for validation failure
240
241
Returns:
242
Decorator function
243
"""
244
245
def mark_flag_as_required(flag_name, flag_values=FLAGS):
246
"""
247
Mark a flag as required.
248
249
Args:
250
flag_name (str): Name of flag to mark as required
251
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
252
"""
253
254
def mark_flags_as_required(flag_names, flag_values=FLAGS):
255
"""
256
Mark multiple flags as required.
257
258
Args:
259
flag_names (List[str]): Names of flags to mark as required
260
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
261
"""
262
263
def mark_flags_as_mutual_exclusive(flag_names, required=False, flag_values=FLAGS):
264
"""
265
Mark flags as mutually exclusive.
266
267
Args:
268
flag_names (List[str]): Names of flags that are mutually exclusive
269
required (bool): If True, exactly one flag must be specified
270
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
271
"""
272
273
def mark_bool_flags_as_mutual_exclusive(flag_names, required=True, flag_values=FLAGS):
274
"""
275
Mark boolean flags as mutually exclusive.
276
277
Args:
278
flag_names (List[str]): Names of boolean flags that are mutually exclusive
279
required (bool): If True, exactly one flag must be True
280
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
281
"""
282
```
283
284
### Flag Modification
285
286
Functions to modify flag defaults and values at runtime.
287
288
```python { .api }
289
def set_default(flag_holder, value):
290
"""
291
Set the default value for a flag.
292
293
Args:
294
flag_holder (FlagHolder): Flag holder returned by DEFINE_*
295
value: New default value
296
"""
297
298
def override_value(flag_holder, value):
299
"""
300
Override the current value of a flag.
301
302
Args:
303
flag_holder (FlagHolder): Flag holder returned by DEFINE_*
304
value: New value to set
305
"""
306
```
307
308
### Key Flags
309
310
System for managing key flags that are adopted across modules.
311
312
```python { .api }
313
def declare_key_flag(flag_name, flag_values=FLAGS):
314
"""
315
Declare a flag as a key flag for the current module.
316
317
Args:
318
flag_name (str): Name of flag to declare as key
319
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
320
"""
321
322
def adopt_module_key_flags(module, flag_values=FLAGS):
323
"""
324
Adopt key flags from another module.
325
326
Args:
327
module: Module to adopt key flags from
328
flag_values (FlagValues): Flag registry (defaults to global FLAGS)
329
"""
330
331
def disclaim_key_flags():
332
"""Disclaim key flags for the current module."""
333
```
334
335
### Exception Classes
336
337
Exception types for flag-related errors.
338
339
```python { .api }
340
class Error(Exception):
341
"""Base exception for flag errors."""
342
343
class CantOpenFlagFileError(Error):
344
"""Exception when flag file cannot be opened."""
345
346
class DuplicateFlagError(Error):
347
"""Exception when a flag is defined multiple times."""
348
349
class IllegalFlagValueError(Error):
350
"""Exception when a flag is given an illegal value."""
351
352
class UnrecognizedFlagError(Error):
353
"""Exception when an unrecognized flag is encountered."""
354
355
class UnparsedFlagAccessError(Error):
356
"""Exception when accessing flag before parsing."""
357
358
class ValidationError(Error):
359
"""Exception for flag validation failures."""
360
361
class FlagNameConflictsWithMethodError(Error):
362
"""Exception when flag name conflicts with FlagValues method."""
363
```
364
365
### Core Classes
366
367
Core classes for flag system implementation.
368
369
```python { .api }
370
class FlagValues:
371
"""Container for all flag values and parsing state."""
372
373
def __getattr__(self, name):
374
"""Get flag value by name."""
375
376
def __setattr__(self, name, value):
377
"""Set flag value by name."""
378
379
class Flag:
380
"""Base class for all flag types."""
381
382
class FlagHolder:
383
"""Holder object returned by DEFINE_* functions."""
384
385
class ArgumentParser:
386
"""Base class for flag argument parsers."""
387
388
class ArgumentSerializer:
389
"""Base class for flag argument serializers."""
390
391
class BooleanParser(ArgumentParser):
392
"""Parser for boolean flag values."""
393
394
class EnumParser(ArgumentParser):
395
"""Parser for enum flag values."""
396
397
class EnumClassParser(ArgumentParser):
398
"""Parser for enum class flag values."""
399
400
class FloatParser(ArgumentParser):
401
"""Parser for float flag values."""
402
403
class IntegerParser(ArgumentParser):
404
"""Parser for integer flag values."""
405
406
class ListParser(ArgumentParser):
407
"""Parser for list flag values."""
408
409
class WhitespaceSeparatedListParser(ArgumentParser):
410
"""Parser for whitespace-separated list values."""
411
```
412
413
### Utility Functions
414
415
Utility functions for help generation and text formatting.
416
417
```python { .api }
418
def get_help_width():
419
"""Get the width for help text formatting."""
420
421
def text_wrap(text, length=None, indent='', firstline_indent=None):
422
"""
423
Wrap text to specified width with indentation.
424
425
Args:
426
text (str): Text to wrap
427
length (int): Maximum line length
428
indent (str): Indentation for continuation lines
429
firstline_indent (str): Indentation for first line
430
"""
431
432
def flag_dict_to_args(flag_map, multi_flags=None):
433
"""
434
Convert flag dictionary to command line arguments.
435
436
Args:
437
flag_map (dict): Dictionary of flag names to values
438
multi_flags (set): Set of flag names that are multi-valued
439
440
Returns:
441
List[str]: Command line arguments
442
"""
443
444
def doc_to_help(doc):
445
"""
446
Convert docstring to help text.
447
448
Args:
449
doc (str): Docstring to convert
450
451
Returns:
452
str: Formatted help text
453
"""
454
```
455
456
## Usage Examples
457
458
### Basic Flag Usage
459
460
```python
461
from absl import app
462
from absl import flags
463
464
FLAGS = flags.FLAGS
465
466
# Define flags
467
flags.DEFINE_string('input_file', None, 'Path to input file.')
468
flags.DEFINE_integer('max_items', 100, 'Maximum number of items to process.')
469
flags.DEFINE_boolean('verbose', False, 'Enable verbose output.')
470
471
def main(argv):
472
# Access flag values
473
print(f'Processing file: {FLAGS.input_file}')
474
print(f'Max items: {FLAGS.max_items}')
475
print(f'Verbose mode: {FLAGS.verbose}')
476
477
if __name__ == '__main__':
478
app.run(main)
479
```
480
481
### Flag Validation
482
483
```python
484
from absl import flags
485
import os
486
487
FLAGS = flags.FLAGS
488
489
flags.DEFINE_string('input_file', None, 'Input file path.')
490
flags.DEFINE_integer('threads', 1, 'Number of threads.')
491
492
# Simple validator
493
@flags.validator('input_file', 'Input file must exist')
494
def validate_input_file(value):
495
return value is None or os.path.exists(value)
496
497
# Multi-flag validator
498
@flags.multi_flags_validator(['threads', 'input_file'], 'Thread count must be 1 when no input file')
499
def validate_threads_and_file(flags_dict):
500
if flags_dict['input_file'] is None and flags_dict['threads'] > 1:
501
return False
502
return True
503
504
# Mark flags as required
505
flags.mark_flag_as_required('input_file')
506
```
507
508
### Enum Flags
509
510
```python
511
from absl import flags
512
from enum import Enum
513
514
FLAGS = flags.FLAGS
515
516
# String enum
517
flags.DEFINE_enum('mode', 'dev', ['dev', 'test', 'prod'], 'Deployment mode.')
518
519
# Enum class
520
class LogLevel(Enum):
521
DEBUG = 'debug'
522
INFO = 'info'
523
WARNING = 'warning'
524
ERROR = 'error'
525
526
flags.DEFINE_enum_class('log_level', LogLevel.INFO, LogLevel, 'Logging level.')
527
```
528
529
### Multi-Value Flags
530
531
```python
532
from absl import flags
533
534
FLAGS = flags.FLAGS
535
536
# Comma-separated list
537
flags.DEFINE_list('files', [], 'List of files to process.')
538
539
# Multi-occurrence flag
540
flags.DEFINE_multi_string('tag', [], 'Tags to apply (can be specified multiple times).')
541
542
# Usage: --files=file1,file2,file3 --tag=important --tag=urgent
543
```