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