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