-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
Expand file tree
/
Copy pathargparse.py
More file actions
2577 lines (2136 loc) · 95.5 KB
/
argparse.py
File metadata and controls
2577 lines (2136 loc) · 95.5 KB
Edit and raw actions
OlderNewer
1
# Author: Steven J. Bethard <[email protected]>.
2
# New maintainer as of 29 August 2019: Raymond Hettinger <[email protected]>
3
4
"""Command-line parsing library
5
6
This module is an optparse-inspired command-line parsing library that:
7
8
- handles both optional and positional arguments
9
- produces highly informative usage messages
10
- supports parsers that dispatch to sub-parsers
11
12
The following is a simple usage example that sums integers from the
13
command-line and writes the result to a file::
14
15
parser = argparse.ArgumentParser(
16
description='sum the integers at the command line')
17
parser.add_argument(
18
'integers', metavar='int', nargs='+', type=int,
19
help='an integer to be summed')
20
parser.add_argument(
21
'--log', default=sys.stdout, type=argparse.FileType('w'),
22
help='the file where the sum should be written')
23
args = parser.parse_args()
24
args.log.write('%s' % sum(args.integers))
25
args.log.close()
26
27
The module contains the following public classes:
28
29
- ArgumentParser -- The main entry point for command-line parsing. As the
30
example above shows, the add_argument() method is used to populate
31
the parser with actions for optional and positional arguments. Then
32
the parse_args() method is invoked to convert the args at the
33
command-line into an object with attributes.
34
35
- ArgumentError -- The exception raised by ArgumentParser objects when
36
there are errors with the parser's actions. Errors raised while
37
parsing the command-line are caught by ArgumentParser and emitted
38
as command-line messages.
39
40
- FileType -- A factory for defining types of files to be created. As the
41
example above shows, instances of FileType are typically passed as
42
the type= argument of add_argument() calls.
43
44
- Action -- The base class for parser actions. Typically actions are
45
selected by passing strings like 'store_true' or 'append_const' to
46
the action= argument of add_argument(). However, for greater
47
customization of ArgumentParser actions, subclasses of Action may
48
be defined and passed as the action= argument.
49
50
- HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
51
ArgumentDefaultsHelpFormatter -- Formatter classes which
52
may be passed as the formatter_class= argument to the
53
ArgumentParser constructor. HelpFormatter is the default,
54
RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
55
not to change the formatting for help text, and
56
ArgumentDefaultsHelpFormatter adds information about argument defaults
57
to the help.
58
59
All other classes in this module are considered implementation details.
60
(Also note that HelpFormatter and RawDescriptionHelpFormatter are only
61
considered public as object names -- the API of the formatter objects is
62
still considered an implementation detail.)
63
"""
64
65
__version__ = '1.1'
66
__all__ = [
67
'ArgumentParser',
68
'ArgumentError',
69
'ArgumentTypeError',
70
'BooleanOptionalAction',
71
'FileType',
72
'HelpFormatter',
73
'ArgumentDefaultsHelpFormatter',
74
'RawDescriptionHelpFormatter',
75
'RawTextHelpFormatter',
76
'MetavarTypeHelpFormatter',
77
'Namespace',
78
'Action',
79
'ONE_OR_MORE',
80
'OPTIONAL',
81
'PARSER',
82
'REMAINDER',
83
'SUPPRESS',
84
'ZERO_OR_MORE',
85
]
86
87
88
import os as _os
89
import re as _re
90
import sys as _sys
91
92
from gettext import gettext as _, ngettext
93
94
SUPPRESS = '==SUPPRESS=='
95
96
OPTIONAL = '?'
97
ZERO_OR_MORE = '*'
98
ONE_OR_MORE = '+'
99
PARSER = 'A...'
100
REMAINDER = '...'
101
_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
102
103
# =============================
104
# Utility functions and classes
105
# =============================
106
107
class _AttributeHolder(object):
108
"""Abstract base class that provides __repr__.
109
110
The __repr__ method returns a string in the format::
111
ClassName(attr=name, attr=name, ...)
112
The attributes are determined either by a class-level attribute,
113
'_kwarg_names', or by inspecting the instance __dict__.
114
"""
115
116
def __repr__(self):
117
type_name = type(self).__name__
118
arg_strings = []
119
star_args = {}
120
for arg in self._get_args():
121
arg_strings.append(repr(arg))
122
for name, value in self._get_kwargs():
123
if name.isidentifier():
124
arg_strings.append('%s=%r' % (name, value))
125
else:
126
star_args[name] = value
127
if star_args:
128
arg_strings.append('**%s' % repr(star_args))
129
return '%s(%s)' % (type_name, ', '.join(arg_strings))
130
131
def _get_kwargs(self):
132
return list(self.__dict__.items())
133
134
def _get_args(self):
135
return []
136
137
138
def _copy_items(items):
139
if items is None:
140
return []
141
# The copy module is used only in the 'append' and 'append_const'
142
# actions, and it is needed only when the default value isn't a list.
143
# Delay its import for speeding up the common case.
144
if type(items) is list:
145
return items[:]
146
import copy
147
return copy.copy(items)
148
149
150
# ===============
151
# Formatting Help
152
# ===============
153
154
class HelpFormatter(object):
155
"""Formatter for generating usage messages and argument help strings.
156
157
Only the name of this class is considered a public API. All the methods
158
provided by the class are considered an implementation detail.
159
"""
160
161
def __init__(self,
162
prog,
163
indent_increment=2,
164
max_help_position=24,
165
width=None):
166
167
# default setting for width
168
if width is None:
169
import shutil
170
width = shutil.get_terminal_size().columns
171
width -= 2
172
173
self._prog = prog
174
self._indent_increment = indent_increment
175
self._max_help_position = min(max_help_position,
176
max(width - 20, indent_increment * 2))
177
self._width = width
178
179
self._current_indent = 0
180
self._level = 0
181
self._action_max_length = 0
182
183
self._root_section = self._Section(self, None)
184
self._current_section = self._root_section
185
186
self._whitespace_matcher = _re.compile(r'\s+', _re.ASCII)
187
self._long_break_matcher = _re.compile(r'\n\n\n+')
188
189
# ===============================
190
# Section and indentation methods
191
# ===============================
192
def _indent(self):
193
self._current_indent += self._indent_increment
194
self._level += 1
195
196
def _dedent(self):
197
self._current_indent -= self._indent_increment
198
assert self._current_indent >= 0, 'Indent decreased below 0.'
199
self._level -= 1
200
201
class _Section(object):
202
203
def __init__(self, formatter, parent, heading=None):
204
self.formatter = formatter
205
self.parent = parent
206
self.heading = heading
207
self.items = []
208
209
def format_help(self):
210
# format the indented section
211
if self.parent is not None:
212
self.formatter._indent()
213
join = self.formatter._join_parts
214
item_help = join([func(*args) for func, args in self.items])
215
if self.parent is not None:
216
self.formatter._dedent()
217
218
# return nothing if the section was empty
219
if not item_help:
220
return ''
221
222
# add the heading if the section was non-empty
223
if self.heading is not SUPPRESS and self.heading is not None:
224
current_indent = self.formatter._current_indent
225
heading = '%*s%s:\n' % (current_indent, '', self.heading)
226
else:
227
heading = ''
228
229
# join the section-initial newline, the heading and the help
230
return join(['\n', heading, item_help, '\n'])
231
232
def _add_item(self, func, args):
233
self._current_section.items.append((func, args))
234
235
# ========================
236
# Message building methods
237
# ========================
238
def start_section(self, heading):
239
self._indent()
240
section = self._Section(self, self._current_section, heading)
241
self._add_item(section.format_help, [])
242
self._current_section = section
243
244
def end_section(self):
245
self._current_section = self._current_section.parent
246
self._dedent()
247
248
def add_text(self, text):
249
if text is not SUPPRESS and text is not None:
250
self._add_item(self._format_text, [text])
251
252
def add_usage(self, usage, actions, groups, prefix=None):
253
if usage is not SUPPRESS:
254
args = usage, actions, groups, prefix
255
self._add_item(self._format_usage, args)
256
257
def add_argument(self, action):
258
if action.help is not SUPPRESS:
259
260
# find all invocations
261
get_invocation = self._format_action_invocation
262
invocations = [get_invocation(action)]
263
for subaction in self._iter_indented_subactions(action):
264
invocations.append(get_invocation(subaction))
265
266
# update the maximum item length
267
invocation_length = max(map(len, invocations))
268
action_length = invocation_length + self._current_indent
269
self._action_max_length = max(self._action_max_length,
270
action_length)
271
272
# add the item to the list
273
self._add_item(self._format_action, [action])
274
275
def add_arguments(self, actions):
276
for action in actions:
277
self.add_argument(action)
278
279
# =======================
280
# Help-formatting methods
281
# =======================
282
def format_help(self):
283
help = self._root_section.format_help()
284
if help:
285
help = self._long_break_matcher.sub('\n\n', help)
286
help = help.strip('\n') + '\n'
287
return help
288
289
def _join_parts(self, part_strings):
290
return ''.join([part
291
for part in part_strings
292
if part and part is not SUPPRESS])
293
294
def _format_usage(self, usage, actions, groups, prefix):
295
if prefix is None:
296
prefix = _('usage: ')
297
298
# if usage is specified, use that
299
if usage is not None:
300
usage = usage % dict(prog=self._prog)
301
302
# if no optionals or positionals are available, usage is just prog
303
elif usage is None and not actions:
304
usage = '%(prog)s' % dict(prog=self._prog)
305
306
# if optionals and positionals are available, calculate usage
307
elif usage is None:
308
prog = '%(prog)s' % dict(prog=self._prog)
309
310
# split optionals from positionals
311
optionals = []
312
positionals = []
313
for action in actions:
314
if action.option_strings:
315
optionals.append(action)
316
else:
317
positionals.append(action)
318
319
# build full usage string
320
format = self._format_actions_usage
321
action_usage = format(optionals + positionals, groups)
322
usage = ' '.join([s for s in [prog, action_usage] if s])
323
324
# wrap the usage parts if it's too long
325
text_width = self._width - self._current_indent
326
if len(prefix) + len(usage) > text_width:
327
328
# break usage into wrappable parts
329
part_regexp = (
330
r'\(.*?\)+(?=\s|$)|'
331
r'\[.*?\]+(?=\s|$)|'
332
r'\S+'
333
)
334
opt_usage = format(optionals, groups)
335
pos_usage = format(positionals, groups)
336
opt_parts = _re.findall(part_regexp, opt_usage)
337
pos_parts = _re.findall(part_regexp, pos_usage)
338
assert ' '.join(opt_parts) == opt_usage
339
assert ' '.join(pos_parts) == pos_usage
340
341
# helper for wrapping lines
342
def get_lines(parts, indent, prefix=None):
343
lines = []
344
line = []
345
if prefix is not None:
346
line_len = len(prefix) - 1
347
else:
348
line_len = len(indent) - 1
349
for part in parts:
350
if line_len + 1 + len(part) > text_width and line:
351
lines.append(indent + ' '.join(line))
352
line = []
353
line_len = len(indent) - 1
354
line.append(part)
355
line_len += len(part) + 1
356
if line:
357
lines.append(indent + ' '.join(line))
358
if prefix is not None:
359
lines[0] = lines[0][len(indent):]
360
return lines
361
362
# if prog is short, follow it with optionals or positionals
363
if len(prefix) + len(prog) <= 0.75 * text_width:
364
indent = ' ' * (len(prefix) + len(prog) + 1)
365
if opt_parts:
366
lines = get_lines([prog] + opt_parts, indent, prefix)
367
lines.extend(get_lines(pos_parts, indent))
368
elif pos_parts:
369
lines = get_lines([prog] + pos_parts, indent, prefix)
370
else:
371
lines = [prog]
372
373
# if prog is long, put it on its own line
374
else:
375
indent = ' ' * len(prefix)
376
parts = opt_parts + pos_parts
377
lines = get_lines(parts, indent)
378
if len(lines) > 1:
379
lines = []
380
lines.extend(get_lines(opt_parts, indent))
381
lines.extend(get_lines(pos_parts, indent))
382
lines = [prog] + lines
383
384
# join lines into usage
385
usage = '\n'.join(lines)
386
387
# prefix with 'usage:'
388
return '%s%s\n\n' % (prefix, usage)
389
390
def _format_actions_usage(self, actions, groups):
391
# find group indices and identify actions in groups
392
group_actions = set()
393
inserts = {}
394
for group in groups:
395
try:
396
start = actions.index(group._group_actions[0])
397
except ValueError:
398
continue
399
else:
400
end = start + len(group._group_actions)
401
if actions[start:end] == group._group_actions:
402
for action in group._group_actions:
403
group_actions.add(action)
404
if not group.required:
405
if start in inserts:
406
inserts[start] += ' ['
407
else:
408
inserts[start] = '['
409
if end in inserts:
410
inserts[end] += ']'
411
else:
412
inserts[end] = ']'
413
else:
414
if start in inserts:
415
inserts[start] += ' ('
416
else:
417
inserts[start] = '('
418
if end in inserts:
419
inserts[end] += ')'
420
else:
421
inserts[end] = ')'
422
for i in range(start + 1, end):
423
inserts[i] = '|'
424
425
# collect all actions format strings
426
parts = []
427
for i, action in enumerate(actions):
428
429
# suppressed arguments are marked with None
430
# remove | separators for suppressed arguments
431
if action.help is SUPPRESS:
432
parts.append(None)
433
if inserts.get(i) == '|':
434
inserts.pop(i)
435
elif inserts.get(i + 1) == '|':
436
inserts.pop(i + 1)
437
438
# produce all arg strings
439
elif not action.option_strings:
440
default = self._get_default_metavar_for_positional(action)
441
part = self._format_args(action, default)
442
443
# if it's in a group, strip the outer []
444
if action in group_actions:
445
if part[0] == '[' and part[-1] == ']':
446
part = part[1:-1]
447
448
# add the action string to the list
449
parts.append(part)
450
451
# produce the first way to invoke the option in brackets
452
else:
453
option_string = action.option_strings[0]
454
455
# if the Optional doesn't take a value, format is:
456
# -s or --long
457
if action.nargs == 0:
458
part = action.format_usage()
459
460
# if the Optional takes a value, format is:
461
# -s ARGS or --long ARGS
462
else:
463
default = self._get_default_metavar_for_optional(action)
464
args_string = self._format_args(action, default)
465
part = '%s %s' % (option_string, args_string)
466
467
# make it look optional if it's not required or in a group
468
if not action.required and action not in group_actions:
469
part = '[%s]' % part
470
471
# add the action string to the list
472
parts.append(part)
473
474
# insert things at the necessary indices
475
for i in sorted(inserts, reverse=True):
476
parts[i:i] = [inserts[i]]
477
478
# join all the action items with spaces
479
text = ' '.join([item for item in parts if item is not None])
480
481
# clean up separators for mutually exclusive groups
482
open = r'[\[(]'
483
close = r'[\])]'
484
text = _re.sub(r'(%s) ' % open, r'\1', text)
485
text = _re.sub(r' (%s)' % close, r'\1', text)
486
text = _re.sub(r'%s *%s' % (open, close), r'', text)
487
text = _re.sub(r'\(([^|]*)\)', r'\1', text)
488
text = text.strip()
489
490
# return the text
491
return text
492
493
def _format_text(self, text):
494
if '%(prog)' in text:
495
text = text % dict(prog=self._prog)
496
text_width = max(self._width - self._current_indent, 11)
497
indent = ' ' * self._current_indent
498
return self._fill_text(text, text_width, indent) + '\n\n'
499
500
def _format_action(self, action):
501
# determine the required width and the entry label
502
help_position = min(self._action_max_length + 2,
503
self._max_help_position)
504
help_width = max(self._width - help_position, 11)
505
action_width = help_position - self._current_indent - 2
506
action_header = self._format_action_invocation(action)
507
508
# no help; start on same line and add a final newline
509
if not action.help:
510
tup = self._current_indent, '', action_header
511
action_header = '%*s%s\n' % tup
512
513
# short action name; start on the same line and pad two spaces
514
elif len(action_header) <= action_width:
515
tup = self._current_indent, '', action_width, action_header
516
action_header = '%*s%-*s ' % tup
517
indent_first = 0
518
519
# long action name; start on the next line
520
else:
521
tup = self._current_indent, '', action_header
522
action_header = '%*s%s\n' % tup
523
indent_first = help_position
524
525
# collect the pieces of the action help
526
parts = [action_header]
527
528
# if there was help for the action, add lines of help text
529
if action.help:
530
help_text = self._expand_help(action)
531
help_lines = self._split_lines(help_text, help_width)
532
parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))
533
for line in help_lines[1:]:
534
parts.append('%*s%s\n' % (help_position, '', line))
535
536
# or add a newline if the description doesn't end with one
537
elif not action_header.endswith('\n'):
538
parts.append('\n')
539
540
# if there are any sub-actions, add their help as well
541
for subaction in self._iter_indented_subactions(action):
542
parts.append(self._format_action(subaction))
543
544
# return a single string
545
return self._join_parts(parts)
546
547
def _format_action_invocation(self, action):
548
if not action.option_strings:
549
default = self._get_default_metavar_for_positional(action)
550
metavar, = self._metavar_formatter(action, default)(1)
551
return metavar
552
553
else:
554
parts = []
555
556
# if the Optional doesn't take a value, format is:
557
# -s, --long
558
if action.nargs == 0:
559
parts.extend(action.option_strings)
560
561
# if the Optional takes a value, format is:
562
# -s ARGS, --long ARGS
563
else:
564
default = self._get_default_metavar_for_optional(action)
565
args_string = self._format_args(action, default)
566
for option_string in action.option_strings:
567
parts.append('%s %s' % (option_string, args_string))
568
569
return ', '.join(parts)
570
571
def _metavar_formatter(self, action, default_metavar):
572
if action.metavar is not None:
573
result = action.metavar
574
elif action.choices is not None:
575
choice_strs = [str(choice) for choice in action.choices]
576
result = '{%s}' % ','.join(choice_strs)
577
else:
578
result = default_metavar
579
580
def format(tuple_size):
581
if isinstance(result, tuple):
582
return result
583
else:
584
return (result, ) * tuple_size
585
return format
586
587
def _format_args(self, action, default_metavar):
588
get_metavar = self._metavar_formatter(action, default_metavar)
589
if action.nargs is None:
590
result = '%s' % get_metavar(1)
591
elif action.nargs == OPTIONAL:
592
result = '[%s]' % get_metavar(1)
593
elif action.nargs == ZERO_OR_MORE:
594
metavar = get_metavar(1)
595
if len(metavar) == 2:
596
result = '[%s [%s ...]]' % metavar
597
else:
598
result = '[%s ...]' % metavar
599
elif action.nargs == ONE_OR_MORE:
600
result = '%s [%s ...]' % get_metavar(2)
601
elif action.nargs == REMAINDER:
602
result = '...'
603
elif action.nargs == PARSER:
604
result = '%s ...' % get_metavar(1)
605
elif action.nargs == SUPPRESS:
606
result = ''
607
else:
608
try:
609
formats = ['%s' for _ in range(action.nargs)]
610
except TypeError:
611
raise ValueError("invalid nargs value") from None
612
result = ' '.join(formats) % get_metavar(action.nargs)
613
return result
614
615
def _expand_help(self, action):
616
params = dict(vars(action), prog=self._prog)
617
for name in list(params):
618
if params[name] is SUPPRESS:
619
del params[name]
620
for name in list(params):
621
if hasattr(params[name], '__name__'):
622
params[name] = params[name].__name__
623
if params.get('choices') is not None:
624
choices_str = ', '.join([str(c) for c in params['choices']])
625
params['choices'] = choices_str
626
return self._get_help_string(action) % params
627
628
def _iter_indented_subactions(self, action):
629
try:
630
get_subactions = action._get_subactions
631
except AttributeError:
632
pass
633
else:
634
self._indent()
635
yield from get_subactions()
636
self._dedent()
637
638
def _split_lines(self, text, width):
639
text = self._whitespace_matcher.sub(' ', text).strip()
640
# The textwrap module is used only for formatting help.
641
# Delay its import for speeding up the common usage of argparse.
642
import textwrap
643
return textwrap.wrap(text, width)
644
645
def _fill_text(self, text, width, indent):
646
text = self._whitespace_matcher.sub(' ', text).strip()
647
import textwrap
648
return textwrap.fill(text, width,
649
initial_indent=indent,
650
subsequent_indent=indent)
651
652
def _get_help_string(self, action):
653
return action.help
654
655
def _get_default_metavar_for_optional(self, action):
656
return action.dest.upper()
657
658
def _get_default_metavar_for_positional(self, action):
659
return action.dest
660
661
662
class RawDescriptionHelpFormatter(HelpFormatter):
663
"""Help message formatter which retains any formatting in descriptions.
664
665
Only the name of this class is considered a public API. All the methods
666
provided by the class are considered an implementation detail.
667
"""
668
669
def _fill_text(self, text, width, indent):
670
return ''.join(indent + line for line in text.splitlines(keepends=True))
671
672
673
class RawTextHelpFormatter(RawDescriptionHelpFormatter):
674
"""Help message formatter which retains formatting of all help text.
675
676
Only the name of this class is considered a public API. All the methods
677
provided by the class are considered an implementation detail.
678
"""
679
680
def _split_lines(self, text, width):
681
return text.splitlines()
682
683
684
class ArgumentDefaultsHelpFormatter(HelpFormatter):
685
"""Help message formatter which adds default values to argument help.
686
687
Only the name of this class is considered a public API. All the methods
688
provided by the class are considered an implementation detail.
689
"""
690
691
def _get_help_string(self, action):
692
help = action.help
693
if '%(default)' not in action.help:
694
if action.default is not SUPPRESS:
695
defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
696
if action.option_strings or action.nargs in defaulting_nargs:
697
help += ' (default: %(default)s)'
698
return help
699
700
701
class MetavarTypeHelpFormatter(HelpFormatter):
702
"""Help message formatter which uses the argument 'type' as the default
703
metavar value (instead of the argument 'dest')
704
705
Only the name of this class is considered a public API. All the methods
706
provided by the class are considered an implementation detail.
707
"""
708
709
def _get_default_metavar_for_optional(self, action):
710
return action.type.__name__
711
712
def _get_default_metavar_for_positional(self, action):
713
return action.type.__name__
714
715
716
717
# =====================
718
# Options and Arguments
719
# =====================
720
721
def _get_action_name(argument):
722
if argument is None:
723
return None
724
elif argument.option_strings:
725
return '/'.join(argument.option_strings)
726
elif argument.metavar not in (None, SUPPRESS):
727
return argument.metavar
728
elif argument.dest not in (None, SUPPRESS):
729
return argument.dest
730
elif argument.choices:
731
return '{' + ','.join(argument.choices) + '}'
732
else:
733
return None
734
735
736
class ArgumentError(Exception):
737
"""An error from creating or using an argument (optional or positional).
738
739
The string value of this exception is the message, augmented with
740
information about the argument that caused it.
741
"""
742
743
def __init__(self, argument, message):
744
self.argument_name = _get_action_name(argument)
745
self.message = message
746
747
def __str__(self):
748
if self.argument_name is None:
749
format = '%(message)s'
750
else:
751
format = 'argument %(argument_name)s: %(message)s'
752
return format % dict(message=self.message,
753
argument_name=self.argument_name)
754
755
756
class ArgumentTypeError(Exception):
757
"""An error from trying to convert a command line string to a type."""
758
pass
759
760
761
# ==============
762
# Action classes
763
# ==============
764
765
class Action(_AttributeHolder):
766
"""Information about how to convert command line strings to Python objects.
767
768
Action objects are used by an ArgumentParser to represent the information
769
needed to parse a single argument from one or more strings from the
770
command line. The keyword arguments to the Action constructor are also
771
all attributes of Action instances.
772
773
Keyword Arguments:
774
775
- option_strings -- A list of command-line option strings which
776
should be associated with this action.
777
778
- dest -- The name of the attribute to hold the created object(s)
779
780
- nargs -- The number of command-line arguments that should be
781
consumed. By default, one argument will be consumed and a single
782
value will be produced. Other values include:
783
- N (an integer) consumes N arguments (and produces a list)
784
- '?' consumes zero or one arguments
785
- '*' consumes zero or more arguments (and produces a list)
786
- '+' consumes one or more arguments (and produces a list)
787
Note that the difference between the default and nargs=1 is that
788
with the default, a single value will be produced, while with
789
nargs=1, a list containing a single value will be produced.
790
791
- const -- The value to be produced if the option is specified and the
792
option uses an action that takes no values.
793
794
- default -- The value to be produced if the option is not specified.
795
796
- type -- A callable that accepts a single string argument, and
797
returns the converted value. The standard Python types str, int,
798
float, and complex are useful examples of such callables. If None,
799
str is used.
800
801
- choices -- A container of values that should be allowed. If not None,
802
after a command-line argument has been converted to the appropriate
803
type, an exception will be raised if it is not a member of this
804
collection.
805
806
- required -- True if the action must always be specified at the
807
command line. This is only meaningful for optional command-line
808
arguments.
809
810
- help -- The help string describing the argument.
811
812
- metavar -- The name to be used for the option's argument with the
813
help string. If None, the 'dest' value will be used as the name.
814
"""
815
816
def __init__(self,
817
option_strings,
818
dest,
819
nargs=None,
820
const=None,
821
default=None,
822
type=None,
823
choices=None,
824
required=False,
825
help=None,
826
metavar=None):
827
self.option_strings = option_strings
828
self.dest = dest
829
self.nargs = nargs
830
self.const = const
831
self.default = default
832
self.type = type
833
self.choices = choices
834
self.required = required
835
self.help = help
836
self.metavar = metavar
837
838
def _get_kwargs(self):
839
names = [
840
'option_strings',
841
'dest',
842
'nargs',
843
'const',
844
'default',
845
'type',
846
'choices',
847
'help',
848
'metavar',
849
]
850
return [(name, getattr(self, name)) for name in names]
851
852
def format_usage(self):
853
return self.option_strings[0]
854
855
def __call__(self, parser, namespace, values, option_string=None):
856
raise NotImplementedError(_('.__call__() not defined'))
857
858
class BooleanOptionalAction(Action):
859
def __init__(self,
860
option_strings,
861
dest,
862
default=None,
863
type=None,
864
choices=None,
865
required=False,
866
help=None,
867
metavar=None):
868
869
_option_strings = []
870
for option_string in option_strings:
871
_option_strings.append(option_string)
872
873
if option_string.startswith('--'):
874
option_string = '--no-' + option_string[2:]
875
_option_strings.append(option_string)
876
877
if help is not None and default is not None:
878
help += f" (default: {default})"
879
880
super().__init__(
881
option_strings=_option_strings,
882
dest=dest,
883
nargs=0,
884
default=default,
885
type=type,
886
choices=choices,
887
required=required,
888
help=help,
889
metavar=metavar)
890
891
def __call__(self, parser, namespace, values, option_string=None):
892
if option_string in self.option_strings:
893
setattr(namespace, self.dest, not option_string.startswith('--no-'))
894
895
def format_usage(self):
896
return ' | '.join(self.option_strings)
897
898
899
class _StoreAction(Action):
900
901
def __init__(self,
902
option_strings,
903
dest,
904
nargs=None,
905
const=None,
906
default=None,
907
type=None,
908
choices=None,
909
required=False,
910
help=None,
911
metavar=None):
912
if nargs == 0:
913
raise ValueError('nargs for store actions must be != 0; if you '
914
'have nothing to store, actions such as store '
915
'true or store const may be more appropriate')
916
if const is not None and nargs != OPTIONAL:
917
raise ValueError('nargs must be %r to supply const' % OPTIONAL)
918
super(_StoreAction, self).__init__(
919
option_strings=option_strings,
920
dest=dest,
921
nargs=nargs,
922
const=const,
923
default=default,
924
type=type,
925
choices=choices,
926
required=required,
927
help=help,
928
metavar=metavar)
929
930
def __call__(self, parser, namespace, values, option_string=None):
931
setattr(namespace, self.dest, values)
932
933
934
class _StoreConstAction(Action):
935
936
def __init__(self,
937
option_strings,
938
dest,
939
const,
940
default=None,
941
required=False,
942
help=None,
943
metavar=None):
944
super(_StoreConstAction, self).__init__(
945
option_strings=option_strings,
946
dest=dest,
947
nargs=0,
948
const=const,
949
default=default,
950
required=required,
951
help=help)
952
953
def __call__(self, parser, namespace, values, option_string=None):
954
setattr(namespace, self.dest, self.const)
955
956
957
class _StoreTrueAction(_StoreConstAction):
958
959
def __init__(self,
960
option_strings,
961
dest,
962
default=False,
963
required=False,
964
help=None):
965
super(_StoreTrueAction, self).__init__(
966
option_strings=option_strings,
967
dest=dest,
968
const=True,
969
default=default,
970
required=required,
971
help=help)
972
973
974
class _StoreFalseAction(_StoreConstAction):
975
976
def __init__(self,
977
option_strings,
978
dest,
979
default=True,
980
required=False,
981
help=None):
982
super(_StoreFalseAction, self).__init__(
983
option_strings=option_strings,
984
dest=dest,
985
const=False,
986
default=default,
987
required=required,
988
help=help)
989
990
991
class _AppendAction(Action):
992
993
def __init__(self,
994
option_strings,
995
dest,
996
nargs=None,
997
const=None,
998
default=None,
999
type=None,
1000
choices=None,