Skip to content

Latest commit

 

History

History
2941 lines (2457 loc) · 110 KB

File metadata and controls

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