1 # Author: Steven J. Bethard <steven.bethard@gmail.com>.
2 # New maintainer as of 29 August 2019: Raymond Hettinger <raymond.hettinger@gmail.com>
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 import warnings
93
94 from gettext import gettext as _, ngettext
95
96 SUPPRESS = '==SUPPRESS=='
97
98 OPTIONAL = '?'
99 ZERO_OR_MORE = '*'
100 ONE_OR_MORE = '+'
101 PARSER = 'A...'
102 REMAINDER = '...'
103 _UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
104
105 # =============================
106 # Utility functions and classes
107 # =============================
108
109 class ESC[4;38;5;81m_AttributeHolder(ESC[4;38;5;149mobject):
110 """Abstract base class that provides __repr__.
111
112 The __repr__ method returns a string in the format::
113 ClassName(attr=name, attr=name, ...)
114 The attributes are determined either by a class-level attribute,
115 '_kwarg_names', or by inspecting the instance __dict__.
116 """
117
118 def __repr__(self):
119 type_name = type(self).__name__
120 arg_strings = []
121 star_args = {}
122 for arg in self._get_args():
123 arg_strings.append(repr(arg))
124 for name, value in self._get_kwargs():
125 if name.isidentifier():
126 arg_strings.append('%s=%r' % (name, value))
127 else:
128 star_args[name] = value
129 if star_args:
130 arg_strings.append('**%s' % repr(star_args))
131 return '%s(%s)' % (type_name, ', '.join(arg_strings))
132
133 def _get_kwargs(self):
134 return list(self.__dict__.items())
135
136 def _get_args(self):
137 return []
138
139
140 def _copy_items(items):
141 if items is None:
142 return []
143 # The copy module is used only in the 'append' and 'append_const'
144 # actions, and it is needed only when the default value isn't a list.
145 # Delay its import for speeding up the common case.
146 if type(items) is list:
147 return items[:]
148 import copy
149 return copy.copy(items)
150
151
152 # ===============
153 # Formatting Help
154 # ===============
155
156
157 class ESC[4;38;5;81mHelpFormatter(ESC[4;38;5;149mobject):
158 """Formatter for generating usage messages and argument help strings.
159
160 Only the name of this class is considered a public API. All the methods
161 provided by the class are considered an implementation detail.
162 """
163
164 def __init__(self,
165 prog,
166 indent_increment=2,
167 max_help_position=24,
168 width=None):
169
170 # default setting for width
171 if width is None:
172 import shutil
173 width = shutil.get_terminal_size().columns
174 width -= 2
175
176 self._prog = prog
177 self._indent_increment = indent_increment
178 self._max_help_position = min(max_help_position,
179 max(width - 20, indent_increment * 2))
180 self._width = width
181
182 self._current_indent = 0
183 self._level = 0
184 self._action_max_length = 0
185
186 self._root_section = self._Section(self, None)
187 self._current_section = self._root_section
188
189 self._whitespace_matcher = _re.compile(r'\s+', _re.ASCII)
190 self._long_break_matcher = _re.compile(r'\n\n\n+')
191
192 # ===============================
193 # Section and indentation methods
194 # ===============================
195 def _indent(self):
196 self._current_indent += self._indent_increment
197 self._level += 1
198
199 def _dedent(self):
200 self._current_indent -= self._indent_increment
201 assert self._current_indent >= 0, 'Indent decreased below 0.'
202 self._level -= 1
203
204 class ESC[4;38;5;81m_Section(ESC[4;38;5;149mobject):
205
206 def __init__(self, formatter, parent, heading=None):
207 self.formatter = formatter
208 self.parent = parent
209 self.heading = heading
210 self.items = []
211
212 def format_help(self):
213 # format the indented section
214 if self.parent is not None:
215 self.formatter._indent()
216 join = self.formatter._join_parts
217 item_help = join([func(*args) for func, args in self.items])
218 if self.parent is not None:
219 self.formatter._dedent()
220
221 # return nothing if the section was empty
222 if not item_help:
223 return ''
224
225 # add the heading if the section was non-empty
226 if self.heading is not SUPPRESS and self.heading is not None:
227 current_indent = self.formatter._current_indent
228 heading = '%*s%s:\n' % (current_indent, '', self.heading)
229 else:
230 heading = ''
231
232 # join the section-initial newline, the heading and the help
233 return join(['\n', heading, item_help, '\n'])
234
235 def _add_item(self, func, args):
236 self._current_section.items.append((func, args))
237
238 # ========================
239 # Message building methods
240 # ========================
241 def start_section(self, heading):
242 self._indent()
243 section = self._Section(self, self._current_section, heading)
244 self._add_item(section.format_help, [])
245 self._current_section = section
246
247 def end_section(self):
248 self._current_section = self._current_section.parent
249 self._dedent()
250
251 def add_text(self, text):
252 if text is not SUPPRESS and text is not None:
253 self._add_item(self._format_text, [text])
254
255 def add_usage(self, usage, actions, groups, prefix=None):
256 if usage is not SUPPRESS:
257 args = usage, actions, groups, prefix
258 self._add_item(self._format_usage, args)
259
260 def add_argument(self, action):
261 if action.help is not SUPPRESS:
262
263 # find all invocations
264 get_invocation = self._format_action_invocation
265 invocations = [get_invocation(action)]
266 for subaction in self._iter_indented_subactions(action):
267 invocations.append(get_invocation(subaction))
268
269 # update the maximum item length
270 invocation_length = max(map(len, invocations))
271 action_length = invocation_length + self._current_indent
272 self._action_max_length = max(self._action_max_length,
273 action_length)
274
275 # add the item to the list
276 self._add_item(self._format_action, [action])
277
278 def add_arguments(self, actions):
279 for action in actions:
280 self.add_argument(action)
281
282 # =======================
283 # Help-formatting methods
284 # =======================
285 def format_help(self):
286 help = self._root_section.format_help()
287 if help:
288 help = self._long_break_matcher.sub('\n\n', help)
289 help = help.strip('\n') + '\n'
290 return help
291
292 def _join_parts(self, part_strings):
293 return ''.join([part
294 for part in part_strings
295 if part and part is not SUPPRESS])
296
297 def _format_usage(self, usage, actions, groups, prefix):
298 if prefix is None:
299 prefix = _('usage: ')
300
301 # if usage is specified, use that
302 if usage is not None:
303 usage = usage % dict(prog=self._prog)
304
305 # if no optionals or positionals are available, usage is just prog
306 elif usage is None and not actions:
307 usage = '%(prog)s' % dict(prog=self._prog)
308
309 # if optionals and positionals are available, calculate usage
310 elif usage is None:
311 prog = '%(prog)s' % dict(prog=self._prog)
312
313 # split optionals from positionals
314 optionals = []
315 positionals = []
316 for action in actions:
317 if action.option_strings:
318 optionals.append(action)
319 else:
320 positionals.append(action)
321
322 # build full usage string
323 format = self._format_actions_usage
324 action_usage = format(optionals + positionals, groups)
325 usage = ' '.join([s for s in [prog, action_usage] if s])
326
327 # wrap the usage parts if it's too long
328 text_width = self._width - self._current_indent
329 if len(prefix) + len(usage) > text_width:
330
331 # break usage into wrappable parts
332 part_regexp = (
333 r'\(.*?\)+(?=\s|$)|'
334 r'\[.*?\]+(?=\s|$)|'
335 r'\S+'
336 )
337 opt_usage = format(optionals, groups)
338 pos_usage = format(positionals, groups)
339 opt_parts = _re.findall(part_regexp, opt_usage)
340 pos_parts = _re.findall(part_regexp, pos_usage)
341 assert ' '.join(opt_parts) == opt_usage
342 assert ' '.join(pos_parts) == pos_usage
343
344 # helper for wrapping lines
345 def get_lines(parts, indent, prefix=None):
346 lines = []
347 line = []
348 indent_length = len(indent)
349 if prefix is not None:
350 line_len = len(prefix) - 1
351 else:
352 line_len = indent_length - 1
353 for part in parts:
354 if line_len + 1 + len(part) > text_width and line:
355 lines.append(indent + ' '.join(line))
356 line = []
357 line_len = indent_length - 1
358 line.append(part)
359 line_len += len(part) + 1
360 if line:
361 lines.append(indent + ' '.join(line))
362 if prefix is not None:
363 lines[0] = lines[0][indent_length:]
364 return lines
365
366 # if prog is short, follow it with optionals or positionals
367 if len(prefix) + len(prog) <= 0.75 * text_width:
368 indent = ' ' * (len(prefix) + len(prog) + 1)
369 if opt_parts:
370 lines = get_lines([prog] + opt_parts, indent, prefix)
371 lines.extend(get_lines(pos_parts, indent))
372 elif pos_parts:
373 lines = get_lines([prog] + pos_parts, indent, prefix)
374 else:
375 lines = [prog]
376
377 # if prog is long, put it on its own line
378 else:
379 indent = ' ' * len(prefix)
380 parts = opt_parts + pos_parts
381 lines = get_lines(parts, indent)
382 if len(lines) > 1:
383 lines = []
384 lines.extend(get_lines(opt_parts, indent))
385 lines.extend(get_lines(pos_parts, indent))
386 lines = [prog] + lines
387
388 # join lines into usage
389 usage = '\n'.join(lines)
390
391 # prefix with 'usage:'
392 return '%s%s\n\n' % (prefix, usage)
393
394 def _format_actions_usage(self, actions, groups):
395 # find group indices and identify actions in groups
396 group_actions = set()
397 inserts = {}
398 for group in groups:
399 if not group._group_actions:
400 raise ValueError(f'empty group {group}')
401
402 try:
403 start = actions.index(group._group_actions[0])
404 except ValueError:
405 continue
406 else:
407 group_action_count = len(group._group_actions)
408 end = start + group_action_count
409 if actions[start:end] == group._group_actions:
410
411 suppressed_actions_count = 0
412 for action in group._group_actions:
413 group_actions.add(action)
414 if action.help is SUPPRESS:
415 suppressed_actions_count += 1
416
417 exposed_actions_count = group_action_count - suppressed_actions_count
418
419 if not group.required:
420 if start in inserts:
421 inserts[start] += ' ['
422 else:
423 inserts[start] = '['
424 if end in inserts:
425 inserts[end] += ']'
426 else:
427 inserts[end] = ']'
428 elif exposed_actions_count > 1:
429 if start in inserts:
430 inserts[start] += ' ('
431 else:
432 inserts[start] = '('
433 if end in inserts:
434 inserts[end] += ')'
435 else:
436 inserts[end] = ')'
437 for i in range(start + 1, end):
438 inserts[i] = '|'
439
440 # collect all actions format strings
441 parts = []
442 for i, action in enumerate(actions):
443
444 # suppressed arguments are marked with None
445 # remove | separators for suppressed arguments
446 if action.help is SUPPRESS:
447 parts.append(None)
448 if inserts.get(i) == '|':
449 inserts.pop(i)
450 elif inserts.get(i + 1) == '|':
451 inserts.pop(i + 1)
452
453 # produce all arg strings
454 elif not action.option_strings:
455 default = self._get_default_metavar_for_positional(action)
456 part = self._format_args(action, default)
457
458 # if it's in a group, strip the outer []
459 if action in group_actions:
460 if part[0] == '[' and part[-1] == ']':
461 part = part[1:-1]
462
463 # add the action string to the list
464 parts.append(part)
465
466 # produce the first way to invoke the option in brackets
467 else:
468 option_string = action.option_strings[0]
469
470 # if the Optional doesn't take a value, format is:
471 # -s or --long
472 if action.nargs == 0:
473 part = action.format_usage()
474
475 # if the Optional takes a value, format is:
476 # -s ARGS or --long ARGS
477 else:
478 default = self._get_default_metavar_for_optional(action)
479 args_string = self._format_args(action, default)
480 part = '%s %s' % (option_string, args_string)
481
482 # make it look optional if it's not required or in a group
483 if not action.required and action not in group_actions:
484 part = '[%s]' % part
485
486 # add the action string to the list
487 parts.append(part)
488
489 # insert things at the necessary indices
490 for i in sorted(inserts, reverse=True):
491 parts[i:i] = [inserts[i]]
492
493 # join all the action items with spaces
494 text = ' '.join([item for item in parts if item is not None])
495
496 # clean up separators for mutually exclusive groups
497 open = r'[\[(]'
498 close = r'[\])]'
499 text = _re.sub(r'(%s) ' % open, r'\1', text)
500 text = _re.sub(r' (%s)' % close, r'\1', text)
501 text = _re.sub(r'%s *%s' % (open, close), r'', text)
502 text = text.strip()
503
504 # return the text
505 return text
506
507 def _format_text(self, text):
508 if '%(prog)' in text:
509 text = text % dict(prog=self._prog)
510 text_width = max(self._width - self._current_indent, 11)
511 indent = ' ' * self._current_indent
512 return self._fill_text(text, text_width, indent) + '\n\n'
513
514 def _format_action(self, action):
515 # determine the required width and the entry label
516 help_position = min(self._action_max_length + 2,
517 self._max_help_position)
518 help_width = max(self._width - help_position, 11)
519 action_width = help_position - self._current_indent - 2
520 action_header = self._format_action_invocation(action)
521
522 # no help; start on same line and add a final newline
523 if not action.help:
524 tup = self._current_indent, '', action_header
525 action_header = '%*s%s\n' % tup
526
527 # short action name; start on the same line and pad two spaces
528 elif len(action_header) <= action_width:
529 tup = self._current_indent, '', action_width, action_header
530 action_header = '%*s%-*s ' % tup
531 indent_first = 0
532
533 # long action name; start on the next line
534 else:
535 tup = self._current_indent, '', action_header
536 action_header = '%*s%s\n' % tup
537 indent_first = help_position
538
539 # collect the pieces of the action help
540 parts = [action_header]
541
542 # if there was help for the action, add lines of help text
543 if action.help and action.help.strip():
544 help_text = self._expand_help(action)
545 if help_text:
546 help_lines = self._split_lines(help_text, help_width)
547 parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))
548 for line in help_lines[1:]:
549 parts.append('%*s%s\n' % (help_position, '', line))
550
551 # or add a newline if the description doesn't end with one
552 elif not action_header.endswith('\n'):
553 parts.append('\n')
554
555 # if there are any sub-actions, add their help as well
556 for subaction in self._iter_indented_subactions(action):
557 parts.append(self._format_action(subaction))
558
559 # return a single string
560 return self._join_parts(parts)
561
562 def _format_action_invocation(self, action):
563 if not action.option_strings:
564 default = self._get_default_metavar_for_positional(action)
565 metavar, = self._metavar_formatter(action, default)(1)
566 return metavar
567
568 else:
569 parts = []
570
571 # if the Optional doesn't take a value, format is:
572 # -s, --long
573 if action.nargs == 0:
574 parts.extend(action.option_strings)
575
576 # if the Optional takes a value, format is:
577 # -s ARGS, --long ARGS
578 else:
579 default = self._get_default_metavar_for_optional(action)
580 args_string = self._format_args(action, default)
581 for option_string in action.option_strings:
582 parts.append('%s %s' % (option_string, args_string))
583
584 return ', '.join(parts)
585
586 def _metavar_formatter(self, action, default_metavar):
587 if action.metavar is not None:
588 result = action.metavar
589 elif action.choices is not None:
590 choice_strs = [str(choice) for choice in action.choices]
591 result = '{%s}' % ','.join(choice_strs)
592 else:
593 result = default_metavar
594
595 def format(tuple_size):
596 if isinstance(result, tuple):
597 return result
598 else:
599 return (result, ) * tuple_size
600 return format
601
602 def _format_args(self, action, default_metavar):
603 get_metavar = self._metavar_formatter(action, default_metavar)
604 if action.nargs is None:
605 result = '%s' % get_metavar(1)
606 elif action.nargs == OPTIONAL:
607 result = '[%s]' % get_metavar(1)
608 elif action.nargs == ZERO_OR_MORE:
609 metavar = get_metavar(1)
610 if len(metavar) == 2:
611 result = '[%s [%s ...]]' % metavar
612 else:
613 result = '[%s ...]' % metavar
614 elif action.nargs == ONE_OR_MORE:
615 result = '%s [%s ...]' % get_metavar(2)
616 elif action.nargs == REMAINDER:
617 result = '...'
618 elif action.nargs == PARSER:
619 result = '%s ...' % get_metavar(1)
620 elif action.nargs == SUPPRESS:
621 result = ''
622 else:
623 try:
624 formats = ['%s' for _ in range(action.nargs)]
625 except TypeError:
626 raise ValueError("invalid nargs value") from None
627 result = ' '.join(formats) % get_metavar(action.nargs)
628 return result
629
630 def _expand_help(self, action):
631 params = dict(vars(action), prog=self._prog)
632 for name in list(params):
633 if params[name] is SUPPRESS:
634 del params[name]
635 for name in list(params):
636 if hasattr(params[name], '__name__'):
637 params[name] = params[name].__name__
638 if params.get('choices') is not None:
639 choices_str = ', '.join([str(c) for c in params['choices']])
640 params['choices'] = choices_str
641 return self._get_help_string(action) % params
642
643 def _iter_indented_subactions(self, action):
644 try:
645 get_subactions = action._get_subactions
646 except AttributeError:
647 pass
648 else:
649 self._indent()
650 yield from get_subactions()
651 self._dedent()
652
653 def _split_lines(self, text, width):
654 text = self._whitespace_matcher.sub(' ', text).strip()
655 # The textwrap module is used only for formatting help.
656 # Delay its import for speeding up the common usage of argparse.
657 import textwrap
658 return textwrap.wrap(text, width)
659
660 def _fill_text(self, text, width, indent):
661 text = self._whitespace_matcher.sub(' ', text).strip()
662 import textwrap
663 return textwrap.fill(text, width,
664 initial_indent=indent,
665 subsequent_indent=indent)
666
667 def _get_help_string(self, action):
668 return action.help
669
670 def _get_default_metavar_for_optional(self, action):
671 return action.dest.upper()
672
673 def _get_default_metavar_for_positional(self, action):
674 return action.dest
675
676
677 class ESC[4;38;5;81mRawDescriptionHelpFormatter(ESC[4;38;5;149mHelpFormatter):
678 """Help message formatter which retains any formatting in descriptions.
679
680 Only the name of this class is considered a public API. All the methods
681 provided by the class are considered an implementation detail.
682 """
683
684 def _fill_text(self, text, width, indent):
685 return ''.join(indent + line for line in text.splitlines(keepends=True))
686
687
688 class ESC[4;38;5;81mRawTextHelpFormatter(ESC[4;38;5;149mRawDescriptionHelpFormatter):
689 """Help message formatter which retains formatting of all help text.
690
691 Only the name of this class is considered a public API. All the methods
692 provided by the class are considered an implementation detail.
693 """
694
695 def _split_lines(self, text, width):
696 return text.splitlines()
697
698
699 class ESC[4;38;5;81mArgumentDefaultsHelpFormatter(ESC[4;38;5;149mHelpFormatter):
700 """Help message formatter which adds default values to argument help.
701
702 Only the name of this class is considered a public API. All the methods
703 provided by the class are considered an implementation detail.
704 """
705
706 def _get_help_string(self, action):
707 """
708 Add the default value to the option help message.
709
710 ArgumentDefaultsHelpFormatter and BooleanOptionalAction when it isn't
711 already present. This code will do that, detecting cornercases to
712 prevent duplicates or cases where it wouldn't make sense to the end
713 user.
714 """
715 help = action.help
716 if help is None:
717 help = ''
718
719 if '%(default)' not in help:
720 if action.default is not SUPPRESS:
721 defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
722 if action.option_strings or action.nargs in defaulting_nargs:
723 help += ' (default: %(default)s)'
724 return help
725
726
727
728 class ESC[4;38;5;81mMetavarTypeHelpFormatter(ESC[4;38;5;149mHelpFormatter):
729 """Help message formatter which uses the argument 'type' as the default
730 metavar value (instead of the argument 'dest')
731
732 Only the name of this class is considered a public API. All the methods
733 provided by the class are considered an implementation detail.
734 """
735
736 def _get_default_metavar_for_optional(self, action):
737 return action.type.__name__
738
739 def _get_default_metavar_for_positional(self, action):
740 return action.type.__name__
741
742
743 # =====================
744 # Options and Arguments
745 # =====================
746
747 def _get_action_name(argument):
748 if argument is None:
749 return None
750 elif argument.option_strings:
751 return '/'.join(argument.option_strings)
752 elif argument.metavar not in (None, SUPPRESS):
753 return argument.metavar
754 elif argument.dest not in (None, SUPPRESS):
755 return argument.dest
756 elif argument.choices:
757 return '{' + ','.join(argument.choices) + '}'
758 else:
759 return None
760
761
762 class ESC[4;38;5;81mArgumentError(ESC[4;38;5;149mException):
763 """An error from creating or using an argument (optional or positional).
764
765 The string value of this exception is the message, augmented with
766 information about the argument that caused it.
767 """
768
769 def __init__(self, argument, message):
770 self.argument_name = _get_action_name(argument)
771 self.message = message
772
773 def __str__(self):
774 if self.argument_name is None:
775 format = '%(message)s'
776 else:
777 format = _('argument %(argument_name)s: %(message)s')
778 return format % dict(message=self.message,
779 argument_name=self.argument_name)
780
781
782 class ESC[4;38;5;81mArgumentTypeError(ESC[4;38;5;149mException):
783 """An error from trying to convert a command line string to a type."""
784 pass
785
786
787 # ==============
788 # Action classes
789 # ==============
790
791 class ESC[4;38;5;81mAction(ESC[4;38;5;149m_AttributeHolder):
792 """Information about how to convert command line strings to Python objects.
793
794 Action objects are used by an ArgumentParser to represent the information
795 needed to parse a single argument from one or more strings from the
796 command line. The keyword arguments to the Action constructor are also
797 all attributes of Action instances.
798
799 Keyword Arguments:
800
801 - option_strings -- A list of command-line option strings which
802 should be associated with this action.
803
804 - dest -- The name of the attribute to hold the created object(s)
805
806 - nargs -- The number of command-line arguments that should be
807 consumed. By default, one argument will be consumed and a single
808 value will be produced. Other values include:
809 - N (an integer) consumes N arguments (and produces a list)
810 - '?' consumes zero or one arguments
811 - '*' consumes zero or more arguments (and produces a list)
812 - '+' consumes one or more arguments (and produces a list)
813 Note that the difference between the default and nargs=1 is that
814 with the default, a single value will be produced, while with
815 nargs=1, a list containing a single value will be produced.
816
817 - const -- The value to be produced if the option is specified and the
818 option uses an action that takes no values.
819
820 - default -- The value to be produced if the option is not specified.
821
822 - type -- A callable that accepts a single string argument, and
823 returns the converted value. The standard Python types str, int,
824 float, and complex are useful examples of such callables. If None,
825 str is used.
826
827 - choices -- A container of values that should be allowed. If not None,
828 after a command-line argument has been converted to the appropriate
829 type, an exception will be raised if it is not a member of this
830 collection.
831
832 - required -- True if the action must always be specified at the
833 command line. This is only meaningful for optional command-line
834 arguments.
835
836 - help -- The help string describing the argument.
837
838 - metavar -- The name to be used for the option's argument with the
839 help string. If None, the 'dest' value will be used as the name.
840 """
841
842 def __init__(self,
843 option_strings,
844 dest,
845 nargs=None,
846 const=None,
847 default=None,
848 type=None,
849 choices=None,
850 required=False,
851 help=None,
852 metavar=None):
853 self.option_strings = option_strings
854 self.dest = dest
855 self.nargs = nargs
856 self.const = const
857 self.default = default
858 self.type = type
859 self.choices = choices
860 self.required = required
861 self.help = help
862 self.metavar = metavar
863
864 def _get_kwargs(self):
865 names = [
866 'option_strings',
867 'dest',
868 'nargs',
869 'const',
870 'default',
871 'type',
872 'choices',
873 'required',
874 'help',
875 'metavar',
876 ]
877 return [(name, getattr(self, name)) for name in names]
878
879 def format_usage(self):
880 return self.option_strings[0]
881
882 def __call__(self, parser, namespace, values, option_string=None):
883 raise NotImplementedError(_('.__call__() not defined'))
884
885
886 # FIXME: remove together with `BooleanOptionalAction` deprecated arguments.
887 _deprecated_default = object()
888
889 class ESC[4;38;5;81mBooleanOptionalAction(ESC[4;38;5;149mAction):
890 def __init__(self,
891 option_strings,
892 dest,
893 default=None,
894 type=_deprecated_default,
895 choices=_deprecated_default,
896 required=False,
897 help=None,
898 metavar=_deprecated_default):
899
900 _option_strings = []
901 for option_string in option_strings:
902 _option_strings.append(option_string)
903
904 if option_string.startswith('--'):
905 option_string = '--no-' + option_string[2:]
906 _option_strings.append(option_string)
907
908 # We need `_deprecated` special value to ban explicit arguments that
909 # match default value. Like:
910 # parser.add_argument('-f', action=BooleanOptionalAction, type=int)
911 for field_name in ('type', 'choices', 'metavar'):
912 if locals()[field_name] is not _deprecated_default:
913 warnings._deprecated(
914 field_name,
915 "{name!r} is deprecated as of Python 3.12 and will be "
916 "removed in Python {remove}.",
917 remove=(3, 14))
918
919 if type is _deprecated_default:
920 type = None
921 if choices is _deprecated_default:
922 choices = None
923 if metavar is _deprecated_default:
924 metavar = None
925
926 super().__init__(
927 option_strings=_option_strings,
928 dest=dest,
929 nargs=0,
930 default=default,
931 type=type,
932 choices=choices,
933 required=required,
934 help=help,
935 metavar=metavar)
936
937
938 def __call__(self, parser, namespace, values, option_string=None):
939 if option_string in self.option_strings:
940 setattr(namespace, self.dest, not option_string.startswith('--no-'))
941
942 def format_usage(self):
943 return ' | '.join(self.option_strings)
944
945
946 class ESC[4;38;5;81m_StoreAction(ESC[4;38;5;149mAction):
947
948 def __init__(self,
949 option_strings,
950 dest,
951 nargs=None,
952 const=None,
953 default=None,
954 type=None,
955 choices=None,
956 required=False,
957 help=None,
958 metavar=None):
959 if nargs == 0:
960 raise ValueError('nargs for store actions must be != 0; if you '
961 'have nothing to store, actions such as store '
962 'true or store const may be more appropriate')
963 if const is not None and nargs != OPTIONAL:
964 raise ValueError('nargs must be %r to supply const' % OPTIONAL)
965 super(_StoreAction, self).__init__(
966 option_strings=option_strings,
967 dest=dest,
968 nargs=nargs,
969 const=const,
970 default=default,
971 type=type,
972 choices=choices,
973 required=required,
974 help=help,
975 metavar=metavar)
976
977 def __call__(self, parser, namespace, values, option_string=None):
978 setattr(namespace, self.dest, values)
979
980
981 class ESC[4;38;5;81m_StoreConstAction(ESC[4;38;5;149mAction):
982
983 def __init__(self,
984 option_strings,
985 dest,
986 const=None,
987 default=None,
988 required=False,
989 help=None,
990 metavar=None):
991 super(_StoreConstAction, self).__init__(
992 option_strings=option_strings,
993 dest=dest,
994 nargs=0,
995 const=const,
996 default=default,
997 required=required,
998 help=help)
999
1000 def __call__(self, parser, namespace, values, option_string=None):
1001 setattr(namespace, self.dest, self.const)
1002
1003
1004 class ESC[4;38;5;81m_StoreTrueAction(ESC[4;38;5;149m_StoreConstAction):
1005
1006 def __init__(self,
1007 option_strings,
1008 dest,
1009 default=False,
1010 required=False,
1011 help=None):
1012 super(_StoreTrueAction, self).__init__(
1013 option_strings=option_strings,
1014 dest=dest,
1015 const=True,
1016 default=default,
1017 required=required,
1018 help=help)
1019
1020
1021 class ESC[4;38;5;81m_StoreFalseAction(ESC[4;38;5;149m_StoreConstAction):
1022
1023 def __init__(self,
1024 option_strings,
1025 dest,
1026 default=True,
1027 required=False,
1028 help=None):
1029 super(_StoreFalseAction, self).__init__(
1030 option_strings=option_strings,
1031 dest=dest,
1032 const=False,
1033 default=default,
1034 required=required,
1035 help=help)
1036
1037
1038 class ESC[4;38;5;81m_AppendAction(ESC[4;38;5;149mAction):
1039
1040 def __init__(self,
1041 option_strings,
1042 dest,
1043 nargs=None,
1044 const=None,
1045 default=None,
1046 type=None,
1047 choices=None,
1048 required=False,
1049 help=None,
1050 metavar=None):
1051 if nargs == 0:
1052 raise ValueError('nargs for append actions must be != 0; if arg '
1053 'strings are not supplying the value to append, '
1054 'the append const action may be more appropriate')
1055 if const is not None and nargs != OPTIONAL:
1056 raise ValueError('nargs must be %r to supply const' % OPTIONAL)
1057 super(_AppendAction, self).__init__(
1058 option_strings=option_strings,
1059 dest=dest,
1060 nargs=nargs,
1061 const=const,
1062 default=default,
1063 type=type,
1064 choices=choices,
1065 required=required,
1066 help=help,
1067 metavar=metavar)
1068
1069 def __call__(self, parser, namespace, values, option_string=None):
1070 items = getattr(namespace, self.dest, None)
1071 items = _copy_items(items)
1072 items.append(values)
1073 setattr(namespace, self.dest, items)
1074
1075
1076 class ESC[4;38;5;81m_AppendConstAction(ESC[4;38;5;149mAction):
1077
1078 def __init__(self,
1079 option_strings,
1080 dest,
1081 const=None,
1082 default=None,
1083 required=False,
1084 help=None,
1085 metavar=None):
1086 super(_AppendConstAction, self).__init__(
1087 option_strings=option_strings,
1088 dest=dest,
1089 nargs=0,
1090 const=const,
1091 default=default,
1092 required=required,
1093 help=help,
1094 metavar=metavar)
1095
1096 def __call__(self, parser, namespace, values, option_string=None):
1097 items = getattr(namespace, self.dest, None)
1098 items = _copy_items(items)
1099 items.append(self.const)
1100 setattr(namespace, self.dest, items)
1101
1102
1103 class ESC[4;38;5;81m_CountAction(ESC[4;38;5;149mAction):
1104
1105 def __init__(self,
1106 option_strings,
1107 dest,
1108 default=None,
1109 required=False,
1110 help=None):
1111 super(_CountAction, self).__init__(
1112 option_strings=option_strings,
1113 dest=dest,
1114 nargs=0,
1115 default=default,
1116 required=required,
1117 help=help)
1118
1119 def __call__(self, parser, namespace, values, option_string=None):
1120 count = getattr(namespace, self.dest, None)
1121 if count is None:
1122 count = 0
1123 setattr(namespace, self.dest, count + 1)
1124
1125
1126 class ESC[4;38;5;81m_HelpAction(ESC[4;38;5;149mAction):
1127
1128 def __init__(self,
1129 option_strings,
1130 dest=SUPPRESS,
1131 default=SUPPRESS,
1132 help=None):
1133 super(_HelpAction, self).__init__(
1134 option_strings=option_strings,
1135 dest=dest,
1136 default=default,
1137 nargs=0,
1138 help=help)
1139
1140 def __call__(self, parser, namespace, values, option_string=None):
1141 parser.print_help()
1142 parser.exit()
1143
1144
1145 class ESC[4;38;5;81m_VersionAction(ESC[4;38;5;149mAction):
1146
1147 def __init__(self,
1148 option_strings,
1149 version=None,
1150 dest=SUPPRESS,
1151 default=SUPPRESS,
1152 help="show program's version number and exit"):
1153 super(_VersionAction, self).__init__(
1154 option_strings=option_strings,
1155 dest=dest,
1156 default=default,
1157 nargs=0,
1158 help=help)
1159 self.version = version
1160
1161 def __call__(self, parser, namespace, values, option_string=None):
1162 version = self.version
1163 if version is None:
1164 version = parser.version
1165 formatter = parser._get_formatter()
1166 formatter.add_text(version)
1167 parser._print_message(formatter.format_help(), _sys.stdout)
1168 parser.exit()
1169
1170
1171 class ESC[4;38;5;81m_SubParsersAction(ESC[4;38;5;149mAction):
1172
1173 class ESC[4;38;5;81m_ChoicesPseudoAction(ESC[4;38;5;149mAction):
1174
1175 def __init__(self, name, aliases, help):
1176 metavar = dest = name
1177 if aliases:
1178 metavar += ' (%s)' % ', '.join(aliases)
1179 sup = super(_SubParsersAction._ChoicesPseudoAction, self)
1180 sup.__init__(option_strings=[], dest=dest, help=help,
1181 metavar=metavar)
1182
1183 def __init__(self,
1184 option_strings,
1185 prog,
1186 parser_class,
1187 dest=SUPPRESS,
1188 required=False,
1189 help=None,
1190 metavar=None):
1191
1192 self._prog_prefix = prog
1193 self._parser_class = parser_class
1194 self._name_parser_map = {}
1195 self._choices_actions = []
1196
1197 super(_SubParsersAction, self).__init__(
1198 option_strings=option_strings,
1199 dest=dest,
1200 nargs=PARSER,
1201 choices=self._name_parser_map,
1202 required=required,
1203 help=help,
1204 metavar=metavar)
1205
1206 def add_parser(self, name, **kwargs):
1207 # set prog from the existing prefix
1208 if kwargs.get('prog') is None:
1209 kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
1210
1211 aliases = kwargs.pop('aliases', ())
1212
1213 if name in self._name_parser_map:
1214 raise ArgumentError(self, _('conflicting subparser: %s') % name)
1215 for alias in aliases:
1216 if alias in self._name_parser_map:
1217 raise ArgumentError(
1218 self, _('conflicting subparser alias: %s') % alias)
1219
1220 # create a pseudo-action to hold the choice help
1221 if 'help' in kwargs:
1222 help = kwargs.pop('help')
1223 choice_action = self._ChoicesPseudoAction(name, aliases, help)
1224 self._choices_actions.append(choice_action)
1225
1226 # create the parser and add it to the map
1227 parser = self._parser_class(**kwargs)
1228 self._name_parser_map[name] = parser
1229
1230 # make parser available under aliases also
1231 for alias in aliases:
1232 self._name_parser_map[alias] = parser
1233
1234 return parser
1235
1236 def _get_subactions(self):
1237 return self._choices_actions
1238
1239 def __call__(self, parser, namespace, values, option_string=None):
1240 parser_name = values[0]
1241 arg_strings = values[1:]
1242
1243 # set the parser name if requested
1244 if self.dest is not SUPPRESS:
1245 setattr(namespace, self.dest, parser_name)
1246
1247 # select the parser
1248 try:
1249 parser = self._name_parser_map[parser_name]
1250 except KeyError:
1251 args = {'parser_name': parser_name,
1252 'choices': ', '.join(self._name_parser_map)}
1253 msg = _('unknown parser %(parser_name)r (choices: %(choices)s)') % args
1254 raise ArgumentError(self, msg)
1255
1256 # parse all the remaining options into the namespace
1257 # store any unrecognized options on the object, so that the top
1258 # level parser can decide what to do with them
1259
1260 # In case this subparser defines new defaults, we parse them
1261 # in a new namespace object and then update the original
1262 # namespace for the relevant parts.
1263 subnamespace, arg_strings = parser.parse_known_args(arg_strings, None)
1264 for key, value in vars(subnamespace).items():
1265 setattr(namespace, key, value)
1266
1267 if arg_strings:
1268 vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
1269 getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
1270
1271 class ESC[4;38;5;81m_ExtendAction(ESC[4;38;5;149m_AppendAction):
1272 def __call__(self, parser, namespace, values, option_string=None):
1273 items = getattr(namespace, self.dest, None)
1274 items = _copy_items(items)
1275 items.extend(values)
1276 setattr(namespace, self.dest, items)
1277
1278 # ==============
1279 # Type classes
1280 # ==============
1281
1282 class ESC[4;38;5;81mFileType(ESC[4;38;5;149mobject):
1283 """Factory for creating file object types
1284
1285 Instances of FileType are typically passed as type= arguments to the
1286 ArgumentParser add_argument() method.
1287
1288 Keyword Arguments:
1289 - mode -- A string indicating how the file is to be opened. Accepts the
1290 same values as the builtin open() function.
1291 - bufsize -- The file's desired buffer size. Accepts the same values as
1292 the builtin open() function.
1293 - encoding -- The file's encoding. Accepts the same values as the
1294 builtin open() function.
1295 - errors -- A string indicating how encoding and decoding errors are to
1296 be handled. Accepts the same value as the builtin open() function.
1297 """
1298
1299 def __init__(self, mode='r', bufsize=-1, encoding=None, errors=None):
1300 self._mode = mode
1301 self._bufsize = bufsize
1302 self._encoding = encoding
1303 self._errors = errors
1304
1305 def __call__(self, string):
1306 # the special argument "-" means sys.std{in,out}
1307 if string == '-':
1308 if 'r' in self._mode:
1309 return _sys.stdin.buffer if 'b' in self._mode else _sys.stdin
1310 elif any(c in self._mode for c in 'wax'):
1311 return _sys.stdout.buffer if 'b' in self._mode else _sys.stdout
1312 else:
1313 msg = _('argument "-" with mode %r') % self._mode
1314 raise ValueError(msg)
1315
1316 # all other arguments are used as file names
1317 try:
1318 return open(string, self._mode, self._bufsize, self._encoding,
1319 self._errors)
1320 except OSError as e:
1321 args = {'filename': string, 'error': e}
1322 message = _("can't open '%(filename)s': %(error)s")
1323 raise ArgumentTypeError(message % args)
1324
1325 def __repr__(self):
1326 args = self._mode, self._bufsize
1327 kwargs = [('encoding', self._encoding), ('errors', self._errors)]
1328 args_str = ', '.join([repr(arg) for arg in args if arg != -1] +
1329 ['%s=%r' % (kw, arg) for kw, arg in kwargs
1330 if arg is not None])
1331 return '%s(%s)' % (type(self).__name__, args_str)
1332
1333 # ===========================
1334 # Optional and Positional Parsing
1335 # ===========================
1336
1337 class ESC[4;38;5;81mNamespace(ESC[4;38;5;149m_AttributeHolder):
1338 """Simple object for storing attributes.
1339
1340 Implements equality by attribute names and values, and provides a simple
1341 string representation.
1342 """
1343
1344 def __init__(self, **kwargs):
1345 for name in kwargs:
1346 setattr(self, name, kwargs[name])
1347
1348 def __eq__(self, other):
1349 if not isinstance(other, Namespace):
1350 return NotImplemented
1351 return vars(self) == vars(other)
1352
1353 def __contains__(self, key):
1354 return key in self.__dict__
1355
1356
1357 class ESC[4;38;5;81m_ActionsContainer(ESC[4;38;5;149mobject):
1358
1359 def __init__(self,
1360 description,
1361 prefix_chars,
1362 argument_default,
1363 conflict_handler):
1364 super(_ActionsContainer, self).__init__()
1365
1366 self.description = description
1367 self.argument_default = argument_default
1368 self.prefix_chars = prefix_chars
1369 self.conflict_handler = conflict_handler
1370
1371 # set up registries
1372 self._registries = {}
1373
1374 # register actions
1375 self.register('action', None, _StoreAction)
1376 self.register('action', 'store', _StoreAction)
1377 self.register('action', 'store_const', _StoreConstAction)
1378 self.register('action', 'store_true', _StoreTrueAction)
1379 self.register('action', 'store_false', _StoreFalseAction)
1380 self.register('action', 'append', _AppendAction)
1381 self.register('action', 'append_const', _AppendConstAction)
1382 self.register('action', 'count', _CountAction)
1383 self.register('action', 'help', _HelpAction)
1384 self.register('action', 'version', _VersionAction)
1385 self.register('action', 'parsers', _SubParsersAction)
1386 self.register('action', 'extend', _ExtendAction)
1387
1388 # raise an exception if the conflict handler is invalid
1389 self._get_handler()
1390
1391 # action storage
1392 self._actions = []
1393 self._option_string_actions = {}
1394
1395 # groups
1396 self._action_groups = []
1397 self._mutually_exclusive_groups = []
1398
1399 # defaults storage
1400 self._defaults = {}
1401
1402 # determines whether an "option" looks like a negative number
1403 self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')
1404
1405 # whether or not there are any optionals that look like negative
1406 # numbers -- uses a list so it can be shared and edited
1407 self._has_negative_number_optionals = []
1408
1409 # ====================
1410 # Registration methods
1411 # ====================
1412 def register(self, registry_name, value, object):
1413 registry = self._registries.setdefault(registry_name, {})
1414 registry[value] = object
1415
1416 def _registry_get(self, registry_name, value, default=None):
1417 return self._registries[registry_name].get(value, default)
1418
1419 # ==================================
1420 # Namespace default accessor methods
1421 # ==================================
1422 def set_defaults(self, **kwargs):
1423 self._defaults.update(kwargs)
1424
1425 # if these defaults match any existing arguments, replace
1426 # the previous default on the object with the new one
1427 for action in self._actions:
1428 if action.dest in kwargs:
1429 action.default = kwargs[action.dest]
1430
1431 def get_default(self, dest):
1432 for action in self._actions:
1433 if action.dest == dest and action.default is not None:
1434 return action.default
1435 return self._defaults.get(dest, None)
1436
1437
1438 # =======================
1439 # Adding argument actions
1440 # =======================
1441 def add_argument(self, *args, **kwargs):
1442 """
1443 add_argument(dest, ..., name=value, ...)
1444 add_argument(option_string, option_string, ..., name=value, ...)
1445 """
1446
1447 # if no positional args are supplied or only one is supplied and
1448 # it doesn't look like an option string, parse a positional
1449 # argument
1450 chars = self.prefix_chars
1451 if not args or len(args) == 1 and args[0][0] not in chars:
1452 if args and 'dest' in kwargs:
1453 raise ValueError('dest supplied twice for positional argument')
1454 kwargs = self._get_positional_kwargs(*args, **kwargs)
1455
1456 # otherwise, we're adding an optional argument
1457 else:
1458 kwargs = self._get_optional_kwargs(*args, **kwargs)
1459
1460 # if no default was supplied, use the parser-level default
1461 if 'default' not in kwargs:
1462 dest = kwargs['dest']
1463 if dest in self._defaults:
1464 kwargs['default'] = self._defaults[dest]
1465 elif self.argument_default is not None:
1466 kwargs['default'] = self.argument_default
1467
1468 # create the action object, and add it to the parser
1469 action_class = self._pop_action_class(kwargs)
1470 if not callable(action_class):
1471 raise ValueError('unknown action "%s"' % (action_class,))
1472 action = action_class(**kwargs)
1473
1474 # raise an error if the action type is not callable
1475 type_func = self._registry_get('type', action.type, action.type)
1476 if not callable(type_func):
1477 raise ValueError('%r is not callable' % (type_func,))
1478
1479 if type_func is FileType:
1480 raise ValueError('%r is a FileType class object, instance of it'
1481 ' must be passed' % (type_func,))
1482
1483 # raise an error if the metavar does not match the type
1484 if hasattr(self, "_get_formatter"):
1485 try:
1486 self._get_formatter()._format_args(action, None)
1487 except TypeError:
1488 raise ValueError("length of metavar tuple does not match nargs")
1489
1490 return self._add_action(action)
1491
1492 def add_argument_group(self, *args, **kwargs):
1493 group = _ArgumentGroup(self, *args, **kwargs)
1494 self._action_groups.append(group)
1495 return group
1496
1497 def add_mutually_exclusive_group(self, **kwargs):
1498 group = _MutuallyExclusiveGroup(self, **kwargs)
1499 self._mutually_exclusive_groups.append(group)
1500 return group
1501
1502 def _add_action(self, action):
1503 # resolve any conflicts
1504 self._check_conflict(action)
1505
1506 # add to actions list
1507 self._actions.append(action)
1508 action.container = self
1509
1510 # index the action by any option strings it has
1511 for option_string in action.option_strings:
1512 self._option_string_actions[option_string] = action
1513
1514 # set the flag if any option strings look like negative numbers
1515 for option_string in action.option_strings:
1516 if self._negative_number_matcher.match(option_string):
1517 if not self._has_negative_number_optionals:
1518 self._has_negative_number_optionals.append(True)
1519
1520 # return the created action
1521 return action
1522
1523 def _remove_action(self, action):
1524 self._actions.remove(action)
1525
1526 def _add_container_actions(self, container):
1527 # collect groups by titles
1528 title_group_map = {}
1529 for group in self._action_groups:
1530 if group.title in title_group_map:
1531 msg = _('cannot merge actions - two groups are named %r')
1532 raise ValueError(msg % (group.title))
1533 title_group_map[group.title] = group
1534
1535 # map each action to its group
1536 group_map = {}
1537 for group in container._action_groups:
1538
1539 # if a group with the title exists, use that, otherwise
1540 # create a new group matching the container's group
1541 if group.title not in title_group_map:
1542 title_group_map[group.title] = self.add_argument_group(
1543 title=group.title,
1544 description=group.description,
1545 conflict_handler=group.conflict_handler)
1546
1547 # map the actions to their new group
1548 for action in group._group_actions:
1549 group_map[action] = title_group_map[group.title]
1550
1551 # add container's mutually exclusive groups
1552 # NOTE: if add_mutually_exclusive_group ever gains title= and
1553 # description= then this code will need to be expanded as above
1554 for group in container._mutually_exclusive_groups:
1555 mutex_group = self.add_mutually_exclusive_group(
1556 required=group.required)
1557
1558 # map the actions to their new mutex group
1559 for action in group._group_actions:
1560 group_map[action] = mutex_group
1561
1562 # add all actions to this container or their group
1563 for action in container._actions:
1564 group_map.get(action, self)._add_action(action)
1565
1566 def _get_positional_kwargs(self, dest, **kwargs):
1567 # make sure required is not specified
1568 if 'required' in kwargs:
1569 msg = _("'required' is an invalid argument for positionals")
1570 raise TypeError(msg)
1571
1572 # mark positional arguments as required if at least one is
1573 # always required
1574 if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
1575 kwargs['required'] = True
1576 if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
1577 kwargs['required'] = True
1578
1579 # return the keyword arguments with no option strings
1580 return dict(kwargs, dest=dest, option_strings=[])
1581
1582 def _get_optional_kwargs(self, *args, **kwargs):
1583 # determine short and long option strings
1584 option_strings = []
1585 long_option_strings = []
1586 for option_string in args:
1587 # error on strings that don't start with an appropriate prefix
1588 if not option_string[0] in self.prefix_chars:
1589 args = {'option': option_string,
1590 'prefix_chars': self.prefix_chars}
1591 msg = _('invalid option string %(option)r: '
1592 'must start with a character %(prefix_chars)r')
1593 raise ValueError(msg % args)
1594
1595 # strings starting with two prefix characters are long options
1596 option_strings.append(option_string)
1597 if len(option_string) > 1 and option_string[1] in self.prefix_chars:
1598 long_option_strings.append(option_string)
1599
1600 # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
1601 dest = kwargs.pop('dest', None)
1602 if dest is None:
1603 if long_option_strings:
1604 dest_option_string = long_option_strings[0]
1605 else:
1606 dest_option_string = option_strings[0]
1607 dest = dest_option_string.lstrip(self.prefix_chars)
1608 if not dest:
1609 msg = _('dest= is required for options like %r')
1610 raise ValueError(msg % option_string)
1611 dest = dest.replace('-', '_')
1612
1613 # return the updated keyword arguments
1614 return dict(kwargs, dest=dest, option_strings=option_strings)
1615
1616 def _pop_action_class(self, kwargs, default=None):
1617 action = kwargs.pop('action', default)
1618 return self._registry_get('action', action, action)
1619
1620 def _get_handler(self):
1621 # determine function from conflict handler string
1622 handler_func_name = '_handle_conflict_%s' % self.conflict_handler
1623 try:
1624 return getattr(self, handler_func_name)
1625 except AttributeError:
1626 msg = _('invalid conflict_resolution value: %r')
1627 raise ValueError(msg % self.conflict_handler)
1628
1629 def _check_conflict(self, action):
1630
1631 # find all options that conflict with this option
1632 confl_optionals = []
1633 for option_string in action.option_strings:
1634 if option_string in self._option_string_actions:
1635 confl_optional = self._option_string_actions[option_string]
1636 confl_optionals.append((option_string, confl_optional))
1637
1638 # resolve any conflicts
1639 if confl_optionals:
1640 conflict_handler = self._get_handler()
1641 conflict_handler(action, confl_optionals)
1642
1643 def _handle_conflict_error(self, action, conflicting_actions):
1644 message = ngettext('conflicting option string: %s',
1645 'conflicting option strings: %s',
1646 len(conflicting_actions))
1647 conflict_string = ', '.join([option_string
1648 for option_string, action
1649 in conflicting_actions])
1650 raise ArgumentError(action, message % conflict_string)
1651
1652 def _handle_conflict_resolve(self, action, conflicting_actions):
1653
1654 # remove all conflicting options
1655 for option_string, action in conflicting_actions:
1656
1657 # remove the conflicting option
1658 action.option_strings.remove(option_string)
1659 self._option_string_actions.pop(option_string, None)
1660
1661 # if the option now has no option string, remove it from the
1662 # container holding it
1663 if not action.option_strings:
1664 action.container._remove_action(action)
1665
1666
1667 class ESC[4;38;5;81m_ArgumentGroup(ESC[4;38;5;149m_ActionsContainer):
1668
1669 def __init__(self, container, title=None, description=None, **kwargs):
1670 # add any missing keyword arguments by checking the container
1671 update = kwargs.setdefault
1672 update('conflict_handler', container.conflict_handler)
1673 update('prefix_chars', container.prefix_chars)
1674 update('argument_default', container.argument_default)
1675 super_init = super(_ArgumentGroup, self).__init__
1676 super_init(description=description, **kwargs)
1677
1678 # group attributes
1679 self.title = title
1680 self._group_actions = []
1681
1682 # share most attributes with the container
1683 self._registries = container._registries
1684 self._actions = container._actions
1685 self._option_string_actions = container._option_string_actions
1686 self._defaults = container._defaults
1687 self._has_negative_number_optionals = \
1688 container._has_negative_number_optionals
1689 self._mutually_exclusive_groups = container._mutually_exclusive_groups
1690
1691 def _add_action(self, action):
1692 action = super(_ArgumentGroup, self)._add_action(action)
1693 self._group_actions.append(action)
1694 return action
1695
1696 def _remove_action(self, action):
1697 super(_ArgumentGroup, self)._remove_action(action)
1698 self._group_actions.remove(action)
1699
1700 def add_argument_group(self, *args, **kwargs):
1701 warnings.warn(
1702 "Nesting argument groups is deprecated.",
1703 category=DeprecationWarning,
1704 stacklevel=2
1705 )
1706 return super().add_argument_group(*args, **kwargs)
1707
1708
1709 class ESC[4;38;5;81m_MutuallyExclusiveGroup(ESC[4;38;5;149m_ArgumentGroup):
1710
1711 def __init__(self, container, required=False):
1712 super(_MutuallyExclusiveGroup, self).__init__(container)
1713 self.required = required
1714 self._container = container
1715
1716 def _add_action(self, action):
1717 if action.required:
1718 msg = _('mutually exclusive arguments must be optional')
1719 raise ValueError(msg)
1720 action = self._container._add_action(action)
1721 self._group_actions.append(action)
1722 return action
1723
1724 def _remove_action(self, action):
1725 self._container._remove_action(action)
1726 self._group_actions.remove(action)
1727
1728 def add_mutually_exclusive_group(self, *args, **kwargs):
1729 warnings.warn(
1730 "Nesting mutually exclusive groups is deprecated.",
1731 category=DeprecationWarning,
1732 stacklevel=2
1733 )
1734 return super().add_mutually_exclusive_group(*args, **kwargs)
1735
1736
1737 class ESC[4;38;5;81mArgumentParser(ESC[4;38;5;149m_AttributeHolder, ESC[4;38;5;149m_ActionsContainer):
1738 """Object for parsing command line strings into Python objects.
1739
1740 Keyword Arguments:
1741 - prog -- The name of the program (default:
1742 ``os.path.basename(sys.argv[0])``)
1743 - usage -- A usage message (default: auto-generated from arguments)
1744 - description -- A description of what the program does
1745 - epilog -- Text following the argument descriptions
1746 - parents -- Parsers whose arguments should be copied into this one
1747 - formatter_class -- HelpFormatter class for printing help messages
1748 - prefix_chars -- Characters that prefix optional arguments
1749 - fromfile_prefix_chars -- Characters that prefix files containing
1750 additional arguments
1751 - argument_default -- The default value for all arguments
1752 - conflict_handler -- String indicating how to handle conflicts
1753 - add_help -- Add a -h/-help option
1754 - allow_abbrev -- Allow long options to be abbreviated unambiguously
1755 - exit_on_error -- Determines whether or not ArgumentParser exits with
1756 error info when an error occurs
1757 """
1758
1759 def __init__(self,
1760 prog=None,
1761 usage=None,
1762 description=None,
1763 epilog=None,
1764 parents=[],
1765 formatter_class=HelpFormatter,
1766 prefix_chars='-',
1767 fromfile_prefix_chars=None,
1768 argument_default=None,
1769 conflict_handler='error',
1770 add_help=True,
1771 allow_abbrev=True,
1772 exit_on_error=True):
1773
1774 superinit = super(ArgumentParser, self).__init__
1775 superinit(description=description,
1776 prefix_chars=prefix_chars,
1777 argument_default=argument_default,
1778 conflict_handler=conflict_handler)
1779
1780 # default setting for prog
1781 if prog is None:
1782 prog = _os.path.basename(_sys.argv[0])
1783
1784 self.prog = prog
1785 self.usage = usage
1786 self.epilog = epilog
1787 self.formatter_class = formatter_class
1788 self.fromfile_prefix_chars = fromfile_prefix_chars
1789 self.add_help = add_help
1790 self.allow_abbrev = allow_abbrev
1791 self.exit_on_error = exit_on_error
1792
1793 add_group = self.add_argument_group
1794 self._positionals = add_group(_('positional arguments'))
1795 self._optionals = add_group(_('options'))
1796 self._subparsers = None
1797
1798 # register types
1799 def identity(string):
1800 return string
1801 self.register('type', None, identity)
1802
1803 # add help argument if necessary
1804 # (using explicit default to override global argument_default)
1805 default_prefix = '-' if '-' in prefix_chars else prefix_chars[0]
1806 if self.add_help:
1807 self.add_argument(
1808 default_prefix+'h', default_prefix*2+'help',
1809 action='help', default=SUPPRESS,
1810 help=_('show this help message and exit'))
1811
1812 # add parent arguments and defaults
1813 for parent in parents:
1814 self._add_container_actions(parent)
1815 try:
1816 defaults = parent._defaults
1817 except AttributeError:
1818 pass
1819 else:
1820 self._defaults.update(defaults)
1821
1822 # =======================
1823 # Pretty __repr__ methods
1824 # =======================
1825 def _get_kwargs(self):
1826 names = [
1827 'prog',
1828 'usage',
1829 'description',
1830 'formatter_class',
1831 'conflict_handler',
1832 'add_help',
1833 ]
1834 return [(name, getattr(self, name)) for name in names]
1835
1836 # ==================================
1837 # Optional/Positional adding methods
1838 # ==================================
1839 def add_subparsers(self, **kwargs):
1840 if self._subparsers is not None:
1841 self.error(_('cannot have multiple subparser arguments'))
1842
1843 # add the parser class to the arguments if it's not present
1844 kwargs.setdefault('parser_class', type(self))
1845
1846 if 'title' in kwargs or 'description' in kwargs:
1847 title = _(kwargs.pop('title', 'subcommands'))
1848 description = _(kwargs.pop('description', None))
1849 self._subparsers = self.add_argument_group(title, description)
1850 else:
1851 self._subparsers = self._positionals
1852
1853 # prog defaults to the usage message of this parser, skipping
1854 # optional arguments and with no "usage:" prefix
1855 if kwargs.get('prog') is None:
1856 formatter = self._get_formatter()
1857 positionals = self._get_positional_actions()
1858 groups = self._mutually_exclusive_groups
1859 formatter.add_usage(self.usage, positionals, groups, '')
1860 kwargs['prog'] = formatter.format_help().strip()
1861
1862 # create the parsers action and add it to the positionals list
1863 parsers_class = self._pop_action_class(kwargs, 'parsers')
1864 action = parsers_class(option_strings=[], **kwargs)
1865 self._subparsers._add_action(action)
1866
1867 # return the created parsers action
1868 return action
1869
1870 def _add_action(self, action):
1871 if action.option_strings:
1872 self._optionals._add_action(action)
1873 else:
1874 self._positionals._add_action(action)
1875 return action
1876
1877 def _get_optional_actions(self):
1878 return [action
1879 for action in self._actions
1880 if action.option_strings]
1881
1882 def _get_positional_actions(self):
1883 return [action
1884 for action in self._actions
1885 if not action.option_strings]
1886
1887 # =====================================
1888 # Command line argument parsing methods
1889 # =====================================
1890 def parse_args(self, args=None, namespace=None):
1891 args, argv = self.parse_known_args(args, namespace)
1892 if argv:
1893 msg = _('unrecognized arguments: %s')
1894 self.error(msg % ' '.join(argv))
1895 return args
1896
1897 def parse_known_args(self, args=None, namespace=None):
1898 if args is None:
1899 # args default to the system args
1900 args = _sys.argv[1:]
1901 else:
1902 # make sure that args are mutable
1903 args = list(args)
1904
1905 # default Namespace built from parser defaults
1906 if namespace is None:
1907 namespace = Namespace()
1908
1909 # add any action defaults that aren't present
1910 for action in self._actions:
1911 if action.dest is not SUPPRESS:
1912 if not hasattr(namespace, action.dest):
1913 if action.default is not SUPPRESS:
1914 setattr(namespace, action.dest, action.default)
1915
1916 # add any parser defaults that aren't present
1917 for dest in self._defaults:
1918 if not hasattr(namespace, dest):
1919 setattr(namespace, dest, self._defaults[dest])
1920
1921 # parse the arguments and exit if there are any errors
1922 if self.exit_on_error:
1923 try:
1924 namespace, args = self._parse_known_args(args, namespace)
1925 except ArgumentError as err:
1926 self.error(str(err))
1927 else:
1928 namespace, args = self._parse_known_args(args, namespace)
1929
1930 if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
1931 args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR))
1932 delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)
1933 return namespace, args
1934
1935 def _parse_known_args(self, arg_strings, namespace):
1936 # replace arg strings that are file references
1937 if self.fromfile_prefix_chars is not None:
1938 arg_strings = self._read_args_from_files(arg_strings)
1939
1940 # map all mutually exclusive arguments to the other arguments
1941 # they can't occur with
1942 action_conflicts = {}
1943 for mutex_group in self._mutually_exclusive_groups:
1944 group_actions = mutex_group._group_actions
1945 for i, mutex_action in enumerate(mutex_group._group_actions):
1946 conflicts = action_conflicts.setdefault(mutex_action, [])
1947 conflicts.extend(group_actions[:i])
1948 conflicts.extend(group_actions[i + 1:])
1949
1950 # find all option indices, and determine the arg_string_pattern
1951 # which has an 'O' if there is an option at an index,
1952 # an 'A' if there is an argument, or a '-' if there is a '--'
1953 option_string_indices = {}
1954 arg_string_pattern_parts = []
1955 arg_strings_iter = iter(arg_strings)
1956 for i, arg_string in enumerate(arg_strings_iter):
1957
1958 # all args after -- are non-options
1959 if arg_string == '--':
1960 arg_string_pattern_parts.append('-')
1961 for arg_string in arg_strings_iter:
1962 arg_string_pattern_parts.append('A')
1963
1964 # otherwise, add the arg to the arg strings
1965 # and note the index if it was an option
1966 else:
1967 option_tuple = self._parse_optional(arg_string)
1968 if option_tuple is None:
1969 pattern = 'A'
1970 else:
1971 option_string_indices[i] = option_tuple
1972 pattern = 'O'
1973 arg_string_pattern_parts.append(pattern)
1974
1975 # join the pieces together to form the pattern
1976 arg_strings_pattern = ''.join(arg_string_pattern_parts)
1977
1978 # converts arg strings to the appropriate and then takes the action
1979 seen_actions = set()
1980 seen_non_default_actions = set()
1981
1982 def take_action(action, argument_strings, option_string=None):
1983 seen_actions.add(action)
1984 argument_values = self._get_values(action, argument_strings)
1985
1986 # error if this argument is not allowed with other previously
1987 # seen arguments, assuming that actions that use the default
1988 # value don't really count as "present"
1989 if argument_values is not action.default:
1990 seen_non_default_actions.add(action)
1991 for conflict_action in action_conflicts.get(action, []):
1992 if conflict_action in seen_non_default_actions:
1993 msg = _('not allowed with argument %s')
1994 action_name = _get_action_name(conflict_action)
1995 raise ArgumentError(action, msg % action_name)
1996
1997 # take the action if we didn't receive a SUPPRESS value
1998 # (e.g. from a default)
1999 if argument_values is not SUPPRESS:
2000 action(self, namespace, argument_values, option_string)
2001
2002 # function to convert arg_strings into an optional action
2003 def consume_optional(start_index):
2004
2005 # get the optional identified at this index
2006 option_tuple = option_string_indices[start_index]
2007 action, option_string, explicit_arg = option_tuple
2008
2009 # identify additional optionals in the same arg string
2010 # (e.g. -xyz is the same as -x -y -z if no args are required)
2011 match_argument = self._match_argument
2012 action_tuples = []
2013 while True:
2014
2015 # if we found no optional action, skip it
2016 if action is None:
2017 extras.append(arg_strings[start_index])
2018 return start_index + 1
2019
2020 # if there is an explicit argument, try to match the
2021 # optional's string arguments to only this
2022 if explicit_arg is not None:
2023 arg_count = match_argument(action, 'A')
2024
2025 # if the action is a single-dash option and takes no
2026 # arguments, try to parse more single-dash options out
2027 # of the tail of the option string
2028 chars = self.prefix_chars
2029 if (
2030 arg_count == 0
2031 and option_string[1] not in chars
2032 and explicit_arg != ''
2033 ):
2034 action_tuples.append((action, [], option_string))
2035 char = option_string[0]
2036 option_string = char + explicit_arg[0]
2037 new_explicit_arg = explicit_arg[1:] or None
2038 optionals_map = self._option_string_actions
2039 if option_string in optionals_map:
2040 action = optionals_map[option_string]
2041 explicit_arg = new_explicit_arg
2042 else:
2043 msg = _('ignored explicit argument %r')
2044 raise ArgumentError(action, msg % explicit_arg)
2045
2046 # if the action expect exactly one argument, we've
2047 # successfully matched the option; exit the loop
2048 elif arg_count == 1:
2049 stop = start_index + 1
2050 args = [explicit_arg]
2051 action_tuples.append((action, args, option_string))
2052 break
2053
2054 # error if a double-dash option did not use the
2055 # explicit argument
2056 else:
2057 msg = _('ignored explicit argument %r')
2058 raise ArgumentError(action, msg % explicit_arg)
2059
2060 # if there is no explicit argument, try to match the
2061 # optional's string arguments with the following strings
2062 # if successful, exit the loop
2063 else:
2064 start = start_index + 1
2065 selected_patterns = arg_strings_pattern[start:]
2066 arg_count = match_argument(action, selected_patterns)
2067 stop = start + arg_count
2068 args = arg_strings[start:stop]
2069 action_tuples.append((action, args, option_string))
2070 break
2071
2072 # add the Optional to the list and return the index at which
2073 # the Optional's string args stopped
2074 assert action_tuples
2075 for action, args, option_string in action_tuples:
2076 take_action(action, args, option_string)
2077 return stop
2078
2079 # the list of Positionals left to be parsed; this is modified
2080 # by consume_positionals()
2081 positionals = self._get_positional_actions()
2082
2083 # function to convert arg_strings into positional actions
2084 def consume_positionals(start_index):
2085 # match as many Positionals as possible
2086 match_partial = self._match_arguments_partial
2087 selected_pattern = arg_strings_pattern[start_index:]
2088 arg_counts = match_partial(positionals, selected_pattern)
2089
2090 # slice off the appropriate arg strings for each Positional
2091 # and add the Positional and its args to the list
2092 for action, arg_count in zip(positionals, arg_counts):
2093 args = arg_strings[start_index: start_index + arg_count]
2094 start_index += arg_count
2095 take_action(action, args)
2096
2097 # slice off the Positionals that we just parsed and return the
2098 # index at which the Positionals' string args stopped
2099 positionals[:] = positionals[len(arg_counts):]
2100 return start_index
2101
2102 # consume Positionals and Optionals alternately, until we have
2103 # passed the last option string
2104 extras = []
2105 start_index = 0
2106 if option_string_indices:
2107 max_option_string_index = max(option_string_indices)
2108 else:
2109 max_option_string_index = -1
2110 while start_index <= max_option_string_index:
2111
2112 # consume any Positionals preceding the next option
2113 next_option_string_index = min([
2114 index
2115 for index in option_string_indices
2116 if index >= start_index])
2117 if start_index != next_option_string_index:
2118 positionals_end_index = consume_positionals(start_index)
2119
2120 # only try to parse the next optional if we didn't consume
2121 # the option string during the positionals parsing
2122 if positionals_end_index > start_index:
2123 start_index = positionals_end_index
2124 continue
2125 else:
2126 start_index = positionals_end_index
2127
2128 # if we consumed all the positionals we could and we're not
2129 # at the index of an option string, there were extra arguments
2130 if start_index not in option_string_indices:
2131 strings = arg_strings[start_index:next_option_string_index]
2132 extras.extend(strings)
2133 start_index = next_option_string_index
2134
2135 # consume the next optional and any arguments for it
2136 start_index = consume_optional(start_index)
2137
2138 # consume any positionals following the last Optional
2139 stop_index = consume_positionals(start_index)
2140
2141 # if we didn't consume all the argument strings, there were extras
2142 extras.extend(arg_strings[stop_index:])
2143
2144 # make sure all required actions were present and also convert
2145 # action defaults which were not given as arguments
2146 required_actions = []
2147 for action in self._actions:
2148 if action not in seen_actions:
2149 if action.required:
2150 required_actions.append(_get_action_name(action))
2151 else:
2152 # Convert action default now instead of doing it before
2153 # parsing arguments to avoid calling convert functions
2154 # twice (which may fail) if the argument was given, but
2155 # only if it was defined already in the namespace
2156 if (action.default is not None and
2157 isinstance(action.default, str) and
2158 hasattr(namespace, action.dest) and
2159 action.default is getattr(namespace, action.dest)):
2160 setattr(namespace, action.dest,
2161 self._get_value(action, action.default))
2162
2163 if required_actions:
2164 self.error(_('the following arguments are required: %s') %
2165 ', '.join(required_actions))
2166
2167 # make sure all required groups had one option present
2168 for group in self._mutually_exclusive_groups:
2169 if group.required:
2170 for action in group._group_actions:
2171 if action in seen_non_default_actions:
2172 break
2173
2174 # if no actions were used, report the error
2175 else:
2176 names = [_get_action_name(action)
2177 for action in group._group_actions
2178 if action.help is not SUPPRESS]
2179 msg = _('one of the arguments %s is required')
2180 self.error(msg % ' '.join(names))
2181
2182 # return the updated namespace and the extra arguments
2183 return namespace, extras
2184
2185 def _read_args_from_files(self, arg_strings):
2186 # expand arguments referencing files
2187 new_arg_strings = []
2188 for arg_string in arg_strings:
2189
2190 # for regular arguments, just add them back into the list
2191 if not arg_string or arg_string[0] not in self.fromfile_prefix_chars:
2192 new_arg_strings.append(arg_string)
2193
2194 # replace arguments referencing files with the file content
2195 else:
2196 try:
2197 with open(arg_string[1:],
2198 encoding=_sys.getfilesystemencoding(),
2199 errors=_sys.getfilesystemencodeerrors()) as args_file:
2200 arg_strings = []
2201 for arg_line in args_file.read().splitlines():
2202 for arg in self.convert_arg_line_to_args(arg_line):
2203 arg_strings.append(arg)
2204 arg_strings = self._read_args_from_files(arg_strings)
2205 new_arg_strings.extend(arg_strings)
2206 except OSError as err:
2207 self.error(str(err))
2208
2209 # return the modified argument list
2210 return new_arg_strings
2211
2212 def convert_arg_line_to_args(self, arg_line):
2213 return [arg_line]
2214
2215 def _match_argument(self, action, arg_strings_pattern):
2216 # match the pattern for this action to the arg strings
2217 nargs_pattern = self._get_nargs_pattern(action)
2218 match = _re.match(nargs_pattern, arg_strings_pattern)
2219
2220 # raise an exception if we weren't able to find a match
2221 if match is None:
2222 nargs_errors = {
2223 None: _('expected one argument'),
2224 OPTIONAL: _('expected at most one argument'),
2225 ONE_OR_MORE: _('expected at least one argument'),
2226 }
2227 msg = nargs_errors.get(action.nargs)
2228 if msg is None:
2229 msg = ngettext('expected %s argument',
2230 'expected %s arguments',
2231 action.nargs) % action.nargs
2232 raise ArgumentError(action, msg)
2233
2234 # return the number of arguments matched
2235 return len(match.group(1))
2236
2237 def _match_arguments_partial(self, actions, arg_strings_pattern):
2238 # progressively shorten the actions list by slicing off the
2239 # final actions until we find a match
2240 result = []
2241 for i in range(len(actions), 0, -1):
2242 actions_slice = actions[:i]
2243 pattern = ''.join([self._get_nargs_pattern(action)
2244 for action in actions_slice])
2245 match = _re.match(pattern, arg_strings_pattern)
2246 if match is not None:
2247 result.extend([len(string) for string in match.groups()])
2248 break
2249
2250 # return the list of arg string counts
2251 return result
2252
2253 def _parse_optional(self, arg_string):
2254 # if it's an empty string, it was meant to be a positional
2255 if not arg_string:
2256 return None
2257
2258 # if it doesn't start with a prefix, it was meant to be positional
2259 if not arg_string[0] in self.prefix_chars:
2260 return None
2261
2262 # if the option string is present in the parser, return the action
2263 if arg_string in self._option_string_actions:
2264 action = self._option_string_actions[arg_string]
2265 return action, arg_string, None
2266
2267 # if it's just a single character, it was meant to be positional
2268 if len(arg_string) == 1:
2269 return None
2270
2271 # if the option string before the "=" is present, return the action
2272 if '=' in arg_string:
2273 option_string, explicit_arg = arg_string.split('=', 1)
2274 if option_string in self._option_string_actions:
2275 action = self._option_string_actions[option_string]
2276 return action, option_string, explicit_arg
2277
2278 # search through all possible prefixes of the option string
2279 # and all actions in the parser for possible interpretations
2280 option_tuples = self._get_option_tuples(arg_string)
2281
2282 # if multiple actions match, the option string was ambiguous
2283 if len(option_tuples) > 1:
2284 options = ', '.join([option_string
2285 for action, option_string, explicit_arg in option_tuples])
2286 args = {'option': arg_string, 'matches': options}
2287 msg = _('ambiguous option: %(option)s could match %(matches)s')
2288 self.error(msg % args)
2289
2290 # if exactly one action matched, this segmentation is good,
2291 # so return the parsed action
2292 elif len(option_tuples) == 1:
2293 option_tuple, = option_tuples
2294 return option_tuple
2295
2296 # if it was not found as an option, but it looks like a negative
2297 # number, it was meant to be positional
2298 # unless there are negative-number-like options
2299 if self._negative_number_matcher.match(arg_string):
2300 if not self._has_negative_number_optionals:
2301 return None
2302
2303 # if it contains a space, it was meant to be a positional
2304 if ' ' in arg_string:
2305 return None
2306
2307 # it was meant to be an optional but there is no such option
2308 # in this parser (though it might be a valid option in a subparser)
2309 return None, arg_string, None
2310
2311 def _get_option_tuples(self, option_string):
2312 result = []
2313
2314 # option strings starting with two prefix characters are only
2315 # split at the '='
2316 chars = self.prefix_chars
2317 if option_string[0] in chars and option_string[1] in chars:
2318 if self.allow_abbrev:
2319 if '=' in option_string:
2320 option_prefix, explicit_arg = option_string.split('=', 1)
2321 else:
2322 option_prefix = option_string
2323 explicit_arg = None
2324 for option_string in self._option_string_actions:
2325 if option_string.startswith(option_prefix):
2326 action = self._option_string_actions[option_string]
2327 tup = action, option_string, explicit_arg
2328 result.append(tup)
2329
2330 # single character options can be concatenated with their arguments
2331 # but multiple character options always have to have their argument
2332 # separate
2333 elif option_string[0] in chars and option_string[1] not in chars:
2334 option_prefix = option_string
2335 explicit_arg = None
2336 short_option_prefix = option_string[:2]
2337 short_explicit_arg = option_string[2:]
2338
2339 for option_string in self._option_string_actions:
2340 if option_string == short_option_prefix:
2341 action = self._option_string_actions[option_string]
2342 tup = action, option_string, short_explicit_arg
2343 result.append(tup)
2344 elif option_string.startswith(option_prefix):
2345 action = self._option_string_actions[option_string]
2346 tup = action, option_string, explicit_arg
2347 result.append(tup)
2348
2349 # shouldn't ever get here
2350 else:
2351 self.error(_('unexpected option string: %s') % option_string)
2352
2353 # return the collected option tuples
2354 return result
2355
2356 def _get_nargs_pattern(self, action):
2357 # in all examples below, we have to allow for '--' args
2358 # which are represented as '-' in the pattern
2359 nargs = action.nargs
2360
2361 # the default (None) is assumed to be a single argument
2362 if nargs is None:
2363 nargs_pattern = '(-*A-*)'
2364
2365 # allow zero or one arguments
2366 elif nargs == OPTIONAL:
2367 nargs_pattern = '(-*A?-*)'
2368
2369 # allow zero or more arguments
2370 elif nargs == ZERO_OR_MORE:
2371 nargs_pattern = '(-*[A-]*)'
2372
2373 # allow one or more arguments
2374 elif nargs == ONE_OR_MORE:
2375 nargs_pattern = '(-*A[A-]*)'
2376
2377 # allow any number of options or arguments
2378 elif nargs == REMAINDER:
2379 nargs_pattern = '([-AO]*)'
2380
2381 # allow one argument followed by any number of options or arguments
2382 elif nargs == PARSER:
2383 nargs_pattern = '(-*A[-AO]*)'
2384
2385 # suppress action, like nargs=0
2386 elif nargs == SUPPRESS:
2387 nargs_pattern = '(-*-*)'
2388
2389 # all others should be integers
2390 else:
2391 nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
2392
2393 # if this is an optional action, -- is not allowed
2394 if action.option_strings:
2395 nargs_pattern = nargs_pattern.replace('-*', '')
2396 nargs_pattern = nargs_pattern.replace('-', '')
2397
2398 # return the pattern
2399 return nargs_pattern
2400
2401 # ========================
2402 # Alt command line argument parsing, allowing free intermix
2403 # ========================
2404
2405 def parse_intermixed_args(self, args=None, namespace=None):
2406 args, argv = self.parse_known_intermixed_args(args, namespace)
2407 if argv:
2408 msg = _('unrecognized arguments: %s')
2409 self.error(msg % ' '.join(argv))
2410 return args
2411
2412 def parse_known_intermixed_args(self, args=None, namespace=None):
2413 # returns a namespace and list of extras
2414 #
2415 # positional can be freely intermixed with optionals. optionals are
2416 # first parsed with all positional arguments deactivated. The 'extras'
2417 # are then parsed. If the parser definition is incompatible with the
2418 # intermixed assumptions (e.g. use of REMAINDER, subparsers) a
2419 # TypeError is raised.
2420 #
2421 # positionals are 'deactivated' by setting nargs and default to
2422 # SUPPRESS. This blocks the addition of that positional to the
2423 # namespace
2424
2425 positionals = self._get_positional_actions()
2426 a = [action for action in positionals
2427 if action.nargs in [PARSER, REMAINDER]]
2428 if a:
2429 raise TypeError('parse_intermixed_args: positional arg'
2430 ' with nargs=%s'%a[0].nargs)
2431
2432 if [action.dest for group in self._mutually_exclusive_groups
2433 for action in group._group_actions if action in positionals]:
2434 raise TypeError('parse_intermixed_args: positional in'
2435 ' mutuallyExclusiveGroup')
2436
2437 try:
2438 save_usage = self.usage
2439 try:
2440 if self.usage is None:
2441 # capture the full usage for use in error messages
2442 self.usage = self.format_usage()[7:]
2443 for action in positionals:
2444 # deactivate positionals
2445 action.save_nargs = action.nargs
2446 # action.nargs = 0
2447 action.nargs = SUPPRESS
2448 action.save_default = action.default
2449 action.default = SUPPRESS
2450 namespace, remaining_args = self.parse_known_args(args,
2451 namespace)
2452 for action in positionals:
2453 # remove the empty positional values from namespace
2454 if (hasattr(namespace, action.dest)
2455 and getattr(namespace, action.dest)==[]):
2456 from warnings import warn
2457 warn('Do not expect %s in %s' % (action.dest, namespace))
2458 delattr(namespace, action.dest)
2459 finally:
2460 # restore nargs and usage before exiting
2461 for action in positionals:
2462 action.nargs = action.save_nargs
2463 action.default = action.save_default
2464 optionals = self._get_optional_actions()
2465 try:
2466 # parse positionals. optionals aren't normally required, but
2467 # they could be, so make sure they aren't.
2468 for action in optionals:
2469 action.save_required = action.required
2470 action.required = False
2471 for group in self._mutually_exclusive_groups:
2472 group.save_required = group.required
2473 group.required = False
2474 namespace, extras = self.parse_known_args(remaining_args,
2475 namespace)
2476 finally:
2477 # restore parser values before exiting
2478 for action in optionals:
2479 action.required = action.save_required
2480 for group in self._mutually_exclusive_groups:
2481 group.required = group.save_required
2482 finally:
2483 self.usage = save_usage
2484 return namespace, extras
2485
2486 # ========================
2487 # Value conversion methods
2488 # ========================
2489 def _get_values(self, action, arg_strings):
2490 # for everything but PARSER, REMAINDER args, strip out first '--'
2491 if action.nargs not in [PARSER, REMAINDER]:
2492 try:
2493 arg_strings.remove('--')
2494 except ValueError:
2495 pass
2496
2497 # optional argument produces a default when not present
2498 if not arg_strings and action.nargs == OPTIONAL:
2499 if action.option_strings:
2500 value = action.const
2501 else:
2502 value = action.default
2503 if isinstance(value, str):
2504 value = self._get_value(action, value)
2505 self._check_value(action, value)
2506
2507 # when nargs='*' on a positional, if there were no command-line
2508 # args, use the default if it is anything other than None
2509 elif (not arg_strings and action.nargs == ZERO_OR_MORE and
2510 not action.option_strings):
2511 if action.default is not None:
2512 value = action.default
2513 self._check_value(action, value)
2514 else:
2515 # since arg_strings is always [] at this point
2516 # there is no need to use self._check_value(action, value)
2517 value = arg_strings
2518
2519 # single argument or optional argument produces a single value
2520 elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
2521 arg_string, = arg_strings
2522 value = self._get_value(action, arg_string)
2523 self._check_value(action, value)
2524
2525 # REMAINDER arguments convert all values, checking none
2526 elif action.nargs == REMAINDER:
2527 value = [self._get_value(action, v) for v in arg_strings]
2528
2529 # PARSER arguments convert all values, but check only the first
2530 elif action.nargs == PARSER:
2531 value = [self._get_value(action, v) for v in arg_strings]
2532 self._check_value(action, value[0])
2533
2534 # SUPPRESS argument does not put anything in the namespace
2535 elif action.nargs == SUPPRESS:
2536 value = SUPPRESS
2537
2538 # all other types of nargs produce a list
2539 else:
2540 value = [self._get_value(action, v) for v in arg_strings]
2541 for v in value:
2542 self._check_value(action, v)
2543
2544 # return the converted value
2545 return value
2546
2547 def _get_value(self, action, arg_string):
2548 type_func = self._registry_get('type', action.type, action.type)
2549 if not callable(type_func):
2550 msg = _('%r is not callable')
2551 raise ArgumentError(action, msg % type_func)
2552
2553 # convert the value to the appropriate type
2554 try:
2555 result = type_func(arg_string)
2556
2557 # ArgumentTypeErrors indicate errors
2558 except ArgumentTypeError as err:
2559 msg = str(err)
2560 raise ArgumentError(action, msg)
2561
2562 # TypeErrors or ValueErrors also indicate errors
2563 except (TypeError, ValueError):
2564 name = getattr(action.type, '__name__', repr(action.type))
2565 args = {'type': name, 'value': arg_string}
2566 msg = _('invalid %(type)s value: %(value)r')
2567 raise ArgumentError(action, msg % args)
2568
2569 # return the converted value
2570 return result
2571
2572 def _check_value(self, action, value):
2573 # converted value must be one of the choices (if specified)
2574 if action.choices is not None and value not in action.choices:
2575 args = {'value': value,
2576 'choices': ', '.join(map(repr, action.choices))}
2577 msg = _('invalid choice: %(value)r (choose from %(choices)s)')
2578 raise ArgumentError(action, msg % args)
2579
2580 # =======================
2581 # Help-formatting methods
2582 # =======================
2583 def format_usage(self):
2584 formatter = self._get_formatter()
2585 formatter.add_usage(self.usage, self._actions,
2586 self._mutually_exclusive_groups)
2587 return formatter.format_help()
2588
2589 def format_help(self):
2590 formatter = self._get_formatter()
2591
2592 # usage
2593 formatter.add_usage(self.usage, self._actions,
2594 self._mutually_exclusive_groups)
2595
2596 # description
2597 formatter.add_text(self.description)
2598
2599 # positionals, optionals and user-defined groups
2600 for action_group in self._action_groups:
2601 formatter.start_section(action_group.title)
2602 formatter.add_text(action_group.description)
2603 formatter.add_arguments(action_group._group_actions)
2604 formatter.end_section()
2605
2606 # epilog
2607 formatter.add_text(self.epilog)
2608
2609 # determine help from format above
2610 return formatter.format_help()
2611
2612 def _get_formatter(self):
2613 return self.formatter_class(prog=self.prog)
2614
2615 # =====================
2616 # Help-printing methods
2617 # =====================
2618 def print_usage(self, file=None):
2619 if file is None:
2620 file = _sys.stdout
2621 self._print_message(self.format_usage(), file)
2622
2623 def print_help(self, file=None):
2624 if file is None:
2625 file = _sys.stdout
2626 self._print_message(self.format_help(), file)
2627
2628 def _print_message(self, message, file=None):
2629 if message:
2630 file = file or _sys.stderr
2631 try:
2632 file.write(message)
2633 except (AttributeError, OSError):
2634 pass
2635
2636 # ===============
2637 # Exiting methods
2638 # ===============
2639 def exit(self, status=0, message=None):
2640 if message:
2641 self._print_message(message, _sys.stderr)
2642 _sys.exit(status)
2643
2644 def error(self, message):
2645 """error(message: string)
2646
2647 Prints a usage message incorporating the message to stderr and
2648 exits.
2649
2650 If you override this in a subclass, it should not return -- it
2651 should either exit or raise an exception.
2652 """
2653 self.print_usage(_sys.stderr)
2654 args = {'prog': self.prog, 'message': message}
2655 self.exit(2, _('%(prog)s: error: %(message)s\n') % args)