##// END OF EJS Templates
Merging upstream changes from trunk->module-reorg->inputhook.
Brian Granger -
r2176:50484ac5 merge
parent child Browse files
Show More
@@ -20,10 +20,10 b" name = 'ipython'"
20 20 # because bdist_rpm does not accept dashes (an RPM) convention, and
21 21 # bdist_deb does not accept underscores (a Debian convention).
22 22
23 development = False # change this to False to do a release
24 version_base = '0.10'
23 development = True # change this to False to do a release
24 version_base = '0.11'
25 25 branch = 'ipython'
26 revision = '1188'
26 revision = '1205'
27 27
28 28 if development:
29 29 if branch == 'ipython':
This diff has been collapsed as it changes many lines, (1081 lines changed) Show them Hide them
@@ -1,22 +1,29 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 # Copyright οΏ½ 2006 Steven J. Bethard <steven.bethard@gmail.com>.
3 # Copyright Β© 2006-2009 Steven J. Bethard <steven.bethard@gmail.com>.
4 4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted under the terms of the 3-clause BSD
7 # license. No warranty expressed or implied.
8 # For details, see the accompanying file LICENSE.txt.
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may not
6 # use this file except in compliance with the License. You may obtain a copy
7 # of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
15 # under the License.
9 16
10 17 """Command-line parsing library
11 18
12 19 This module is an optparse-inspired command-line parsing library that:
13 20
14 * handles both optional and positional arguments
15 * produces highly informative usage messages
16 * supports parsers that dispatch to sub-parsers
21 - handles both optional and positional arguments
22 - produces highly informative usage messages
23 - supports parsers that dispatch to sub-parsers
17 24
18 25 The following is a simple usage example that sums integers from the
19 command-line and writes the result to a file:
26 command-line and writes the result to a file::
20 27
21 28 parser = argparse.ArgumentParser(
22 29 description='sum the integers at the command line')
@@ -32,32 +39,35 b' command-line and writes the result to a file:'
32 39
33 40 The module contains the following public classes:
34 41
35 ArgumentParser -- The main entry point for command-line parsing. As the
42 - ArgumentParser -- The main entry point for command-line parsing. As the
36 43 example above shows, the add_argument() method is used to populate
37 44 the parser with actions for optional and positional arguments. Then
38 45 the parse_args() method is invoked to convert the args at the
39 46 command-line into an object with attributes.
40 47
41 ArgumentError -- The exception raised by ArgumentParser objects when
48 - ArgumentError -- The exception raised by ArgumentParser objects when
42 49 there are errors with the parser's actions. Errors raised while
43 50 parsing the command-line are caught by ArgumentParser and emitted
44 51 as command-line messages.
45 52
46 FileType -- A factory for defining types of files to be created. As the
53 - FileType -- A factory for defining types of files to be created. As the
47 54 example above shows, instances of FileType are typically passed as
48 55 the type= argument of add_argument() calls.
49 56
50 Action -- The base class for parser actions. Typically actions are
57 - Action -- The base class for parser actions. Typically actions are
51 58 selected by passing strings like 'store_true' or 'append_const' to
52 59 the action= argument of add_argument(). However, for greater
53 60 customization of ArgumentParser actions, subclasses of Action may
54 61 be defined and passed as the action= argument.
55 62
56 HelpFormatter, RawDescriptionHelpFormatter -- Formatter classes which
63 - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
64 ArgumentDefaultsHelpFormatter -- Formatter classes which
57 65 may be passed as the formatter_class= argument to the
58 ArgumentParser constructor. HelpFormatter is the default, while
59 RawDescriptionHelpFormatter tells the parser not to perform any
60 line-wrapping on description text.
66 ArgumentParser constructor. HelpFormatter is the default,
67 RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
68 not to change the formatting for help text, and
69 ArgumentDefaultsHelpFormatter adds information about argument defaults
70 to the help.
61 71
62 72 All other classes in this module are considered implementation details.
63 73 (Also note that HelpFormatter and RawDescriptionHelpFormatter are only
@@ -65,8 +75,21 b' considered public as object names -- the API of the formatter objects is'
65 75 still considered an implementation detail.)
66 76 """
67 77
68 __version__ = '0.8.0'
69
78 __version__ = '1.0'
79 __all__ = [
80 'ArgumentParser',
81 'ArgumentError',
82 'Namespace',
83 'Action',
84 'FileType',
85 'HelpFormatter',
86 'RawDescriptionHelpFormatter',
87 'RawTextHelpFormatter'
88 'ArgumentDefaultsHelpFormatter',
89 ]
90
91
92 import copy as _copy
70 93 import os as _os
71 94 import re as _re
72 95 import sys as _sys
@@ -74,6 +97,28 b' import textwrap as _textwrap'
74 97
75 98 from gettext import gettext as _
76 99
100 try:
101 _set = set
102 except NameError:
103 from sets import Set as _set
104
105 try:
106 _basestring = basestring
107 except NameError:
108 _basestring = str
109
110 try:
111 _sorted = sorted
112 except NameError:
113
114 def _sorted(iterable, reverse=False):
115 result = list(iterable)
116 result.sort()
117 if reverse:
118 result.reverse()
119 return result
120
121
77 122 SUPPRESS = '==SUPPRESS=='
78 123
79 124 OPTIONAL = '?'
@@ -88,12 +133,12 b" PARSER = '==PARSER=='"
88 133 class _AttributeHolder(object):
89 134 """Abstract base class that provides __repr__.
90 135
91 The __repr__ method returns a string in the format:
136 The __repr__ method returns a string in the format::
92 137 ClassName(attr=name, attr=name, ...)
93 138 The attributes are determined either by a class-level attribute,
94 139 '_kwarg_names', or by inspecting the instance __dict__.
95 140 """
96
141
97 142 def __repr__(self):
98 143 type_name = type(self).__name__
99 144 arg_strings = []
@@ -104,16 +149,16 b' class _AttributeHolder(object):'
104 149 return '%s(%s)' % (type_name, ', '.join(arg_strings))
105 150
106 151 def _get_kwargs(self):
107 return sorted(self.__dict__.items())
152 return _sorted(self.__dict__.items())
108 153
109 154 def _get_args(self):
110 155 return []
111 156
157
112 158 def _ensure_value(namespace, name, value):
113 159 if getattr(namespace, name, None) is None:
114 160 setattr(namespace, name, value)
115 161 return getattr(namespace, name)
116
117 162
118 163
119 164 # ===============
@@ -121,6 +166,11 b' def _ensure_value(namespace, name, value):'
121 166 # ===============
122 167
123 168 class HelpFormatter(object):
169 """Formatter for generating usage messages and argument help strings.
170
171 Only the name of this class is considered a public API. All the methods
172 provided by the class are considered an implementation detail.
173 """
124 174
125 175 def __init__(self,
126 176 prog,
@@ -135,7 +185,7 b' class HelpFormatter(object):'
135 185 except (KeyError, ValueError):
136 186 width = 80
137 187 width -= 2
138
188
139 189 self._prog = prog
140 190 self._indent_increment = indent_increment
141 191 self._max_help_position = max_help_position
@@ -154,7 +204,6 b' class HelpFormatter(object):'
154 204 # ===============================
155 205 # Section and indentation methods
156 206 # ===============================
157
158 207 def _indent(self):
159 208 self._current_indent += self._indent_increment
160 209 self._level += 1
@@ -165,6 +214,7 b' class HelpFormatter(object):'
165 214 self._level -= 1
166 215
167 216 class _Section(object):
217
168 218 def __init__(self, formatter, parent, heading=None):
169 219 self.formatter = formatter
170 220 self.parent = parent
@@ -178,11 +228,11 b' class HelpFormatter(object):'
178 228 join = self.formatter._join_parts
179 229 for func, args in self.items:
180 230 func(*args)
181 item_help = join(func(*args) for func, args in self.items)
231 item_help = join([func(*args) for func, args in self.items])
182 232 if self.parent is not None:
183 233 self.formatter._dedent()
184 234
185 # return nothing if the section was empty
235 # return nothing if the section was empty
186 236 if not item_help:
187 237 return ''
188 238
@@ -202,7 +252,6 b' class HelpFormatter(object):'
202 252 # ========================
203 253 # Message building methods
204 254 # ========================
205
206 255 def start_section(self, heading):
207 256 self._indent()
208 257 section = self._Section(self, self._current_section, heading)
@@ -217,27 +266,27 b' class HelpFormatter(object):'
217 266 if text is not SUPPRESS and text is not None:
218 267 self._add_item(self._format_text, [text])
219 268
220 def add_usage(self, usage, optionals, positionals, prefix=None):
269 def add_usage(self, usage, actions, groups, prefix=None):
221 270 if usage is not SUPPRESS:
222 args = usage, optionals, positionals, prefix
271 args = usage, actions, groups, prefix
223 272 self._add_item(self._format_usage, args)
224 273
225 274 def add_argument(self, action):
226 275 if action.help is not SUPPRESS:
227 276
228 # find all invocations
277 # find all invocations
229 278 get_invocation = self._format_action_invocation
230 279 invocations = [get_invocation(action)]
231 280 for subaction in self._iter_indented_subactions(action):
232 281 invocations.append(get_invocation(subaction))
233
282
234 283 # update the maximum item length
235 invocation_length = max(len(s) for s in invocations)
284 invocation_length = max([len(s) for s in invocations])
236 285 action_length = invocation_length + self._current_indent
237 286 self._action_max_length = max(self._action_max_length,
238 287 action_length)
239 288
240 # add the item to the list
289 # add the item to the list
241 290 self._add_item(self._format_action, [action])
242 291
243 292 def add_arguments(self, actions):
@@ -247,7 +296,6 b' class HelpFormatter(object):'
247 296 # =======================
248 297 # Help-formatting methods
249 298 # =======================
250
251 299 def format_help(self):
252 300 help = self._root_section.format_help() % dict(prog=self._prog)
253 301 if help:
@@ -256,22 +304,31 b' class HelpFormatter(object):'
256 304 return help
257 305
258 306 def _join_parts(self, part_strings):
259 return ''.join(part
260 for part in part_strings
261 if part and part is not SUPPRESS)
307 return ''.join([part
308 for part in part_strings
309 if part and part is not SUPPRESS])
262 310
263 def _format_usage(self, usage, optionals, positionals, prefix):
311 def _format_usage(self, usage, actions, groups, prefix):
264 312 if prefix is None:
265 313 prefix = _('usage: ')
266 314
267 315 # if no optionals or positionals are available, usage is just prog
268 if usage is None and not optionals and not positionals:
316 if usage is None and not actions:
269 317 usage = '%(prog)s'
270
318
271 319 # if optionals and positionals are available, calculate usage
272 320 elif usage is None:
273 321 usage = '%(prog)s' % dict(prog=self._prog)
274
322
323 # split optionals from positionals
324 optionals = []
325 positionals = []
326 for action in actions:
327 if action.option_strings:
328 optionals.append(action)
329 else:
330 positionals.append(action)
331
275 332 # determine width of "usage: PROG" and width of text
276 333 prefix_width = len(prefix) + len(usage) + 1
277 334 prefix_indent = self._current_indent + prefix_width
@@ -279,19 +336,19 b' class HelpFormatter(object):'
279 336
280 337 # put them on one line if they're short enough
281 338 format = self._format_actions_usage
282 action_usage = format(optionals + positionals)
339 action_usage = format(optionals + positionals, groups)
283 340 if prefix_width + len(action_usage) + 1 < text_width:
284 341 usage = '%s %s' % (usage, action_usage)
285
342
286 343 # if they're long, wrap optionals and positionals individually
287 344 else:
288 optional_usage = format(optionals)
289 positional_usage = format(positionals)
345 optional_usage = format(optionals, groups)
346 positional_usage = format(positionals, groups)
290 347 indent = ' ' * prefix_indent
291 348
292 349 # usage is made of PROG, optionals and positionals
293 350 parts = [usage, ' ']
294
351
295 352 # options always get added right after PROG
296 353 if optional_usage:
297 354 parts.append(_textwrap.fill(
@@ -314,15 +371,53 b' class HelpFormatter(object):'
314 371 # prefix with 'usage:'
315 372 return '%s%s\n\n' % (prefix, usage)
316 373
317 def _format_actions_usage(self, actions):
318 parts = []
319 for action in actions:
320 if action.help is SUPPRESS:
374 def _format_actions_usage(self, actions, groups):
375 # find group indices and identify actions in groups
376 group_actions = _set()
377 inserts = {}
378 for group in groups:
379 try:
380 start = actions.index(group._group_actions[0])
381 except ValueError:
321 382 continue
383 else:
384 end = start + len(group._group_actions)
385 if actions[start:end] == group._group_actions:
386 for action in group._group_actions:
387 group_actions.add(action)
388 if not group.required:
389 inserts[start] = '['
390 inserts[end] = ']'
391 else:
392 inserts[start] = '('
393 inserts[end] = ')'
394 for i in range(start + 1, end):
395 inserts[i] = '|'
322 396
323 # produce all arg strings
324 if not action.option_strings:
325 parts.append(self._format_args(action, action.dest))
397 # collect all actions format strings
398 parts = []
399 for i, action in enumerate(actions):
400
401 # suppressed arguments are marked with None
402 # remove | separators for suppressed arguments
403 if action.help is SUPPRESS:
404 parts.append(None)
405 if inserts.get(i) == '|':
406 inserts.pop(i)
407 elif inserts.get(i + 1) == '|':
408 inserts.pop(i + 1)
409
410 # produce all arg strings
411 elif not action.option_strings:
412 part = self._format_args(action, action.dest)
413
414 # if it's in a group, strip the outer []
415 if action in group_actions:
416 if part[0] == '[' and part[-1] == ']':
417 part = part[1:-1]
418
419 # add the action string to the list
420 parts.append(part)
326 421
327 422 # produce the first way to invoke the option in brackets
328 423 else:
@@ -340,12 +435,31 b' class HelpFormatter(object):'
340 435 args_string = self._format_args(action, default)
341 436 part = '%s %s' % (option_string, args_string)
342 437
343 # make it look optional if it's not required
344 if not action.required:
438 # make it look optional if it's not required or in a group
439 if not action.required and action not in group_actions:
345 440 part = '[%s]' % part
441
442 # add the action string to the list
346 443 parts.append(part)
347 444
348 return ' '.join(parts)
445 # insert things at the necessary indices
446 for i in _sorted(inserts, reverse=True):
447 parts[i:i] = [inserts[i]]
448
449 # join all the action items with spaces
450 text = ' '.join([item for item in parts if item is not None])
451
452 # clean up separators for mutually exclusive groups
453 open = r'[\[(]'
454 close = r'[\])]'
455 text = _re.sub(r'(%s) ' % open, r'\1', text)
456 text = _re.sub(r' (%s)' % close, r'\1', text)
457 text = _re.sub(r'%s *%s' % (open, close), r'', text)
458 text = _re.sub(r'\(([^|]*)\)', r'\1', text)
459 text = text.strip()
460
461 # return the text
462 return text
349 463
350 464 def _format_text(self, text):
351 465 text_width = self._width - self._current_indent
@@ -364,7 +478,7 b' class HelpFormatter(object):'
364 478 if not action.help:
365 479 tup = self._current_indent, '', action_header
366 480 action_header = '%*s%s\n' % tup
367
481
368 482 # short action name; start on the same line and pad two spaces
369 483 elif len(action_header) <= action_width:
370 484 tup = self._current_indent, '', action_width, action_header
@@ -396,12 +510,13 b' class HelpFormatter(object):'
396 510 for subaction in self._iter_indented_subactions(action):
397 511 parts.append(self._format_action(subaction))
398 512
399 # return a single string
513 # return a single string
400 514 return self._join_parts(parts)
401 515
402 516 def _format_action_invocation(self, action):
403 517 if not action.option_strings:
404 return self._format_metavar(action, action.dest)
518 metavar, = self._metavar_formatter(action, action.dest)(1)
519 return metavar
405 520
406 521 else:
407 522 parts = []
@@ -421,41 +536,48 b' class HelpFormatter(object):'
421 536
422 537 return ', '.join(parts)
423 538
424 def _format_metavar(self, action, default_metavar):
539 def _metavar_formatter(self, action, default_metavar):
425 540 if action.metavar is not None:
426 name = action.metavar
541 result = action.metavar
427 542 elif action.choices is not None:
428 choice_strs = (str(choice) for choice in action.choices)
429 name = '{%s}' % ','.join(choice_strs)
543 choice_strs = [str(choice) for choice in action.choices]
544 result = '{%s}' % ','.join(choice_strs)
430 545 else:
431 name = default_metavar
432 return name
546 result = default_metavar
547
548 def format(tuple_size):
549 if isinstance(result, tuple):
550 return result
551 else:
552 return (result, ) * tuple_size
553 return format
433 554
434 555 def _format_args(self, action, default_metavar):
435 name = self._format_metavar(action, default_metavar)
556 get_metavar = self._metavar_formatter(action, default_metavar)
436 557 if action.nargs is None:
437 result = name
558 result = '%s' % get_metavar(1)
438 559 elif action.nargs == OPTIONAL:
439 result = '[%s]' % name
560 result = '[%s]' % get_metavar(1)
440 561 elif action.nargs == ZERO_OR_MORE:
441 result = '[%s [%s ...]]' % (name, name)
562 result = '[%s [%s ...]]' % get_metavar(2)
442 563 elif action.nargs == ONE_OR_MORE:
443 result = '%s [%s ...]' % (name, name)
564 result = '%s [%s ...]' % get_metavar(2)
444 565 elif action.nargs is PARSER:
445 result = '%s ...' % name
566 result = '%s ...' % get_metavar(1)
446 567 else:
447 result = ' '.join([name] * action.nargs)
568 formats = ['%s' for _ in range(action.nargs)]
569 result = ' '.join(formats) % get_metavar(action.nargs)
448 570 return result
449 571
450 572 def _expand_help(self, action):
451 573 params = dict(vars(action), prog=self._prog)
452 for name, value in params.items():
453 if value is SUPPRESS:
574 for name in list(params):
575 if params[name] is SUPPRESS:
454 576 del params[name]
455 577 if params.get('choices') is not None:
456 choices_str = ', '.join(str(c) for c in params['choices'])
578 choices_str = ', '.join([str(c) for c in params['choices']])
457 579 params['choices'] = choices_str
458 return action.help % params
580 return self._get_help_string(action) % params
459 581
460 582 def _iter_indented_subactions(self, action):
461 583 try:
@@ -477,39 +599,75 b' class HelpFormatter(object):'
477 599 return _textwrap.fill(text, width, initial_indent=indent,
478 600 subsequent_indent=indent)
479 601
602 def _get_help_string(self, action):
603 return action.help
604
605
480 606 class RawDescriptionHelpFormatter(HelpFormatter):
481
607 """Help message formatter which retains any formatting in descriptions.
608
609 Only the name of this class is considered a public API. All the methods
610 provided by the class are considered an implementation detail.
611 """
612
482 613 def _fill_text(self, text, width, indent):
483 return ''.join(indent + line for line in text.splitlines(True))
614 return ''.join([indent + line for line in text.splitlines(True)])
615
484 616
485 617 class RawTextHelpFormatter(RawDescriptionHelpFormatter):
486
618 """Help message formatter which retains formatting of all help text.
619
620 Only the name of this class is considered a public API. All the methods
621 provided by the class are considered an implementation detail.
622 """
623
487 624 def _split_lines(self, text, width):
488 625 return text.splitlines()
489 626
627
628 class ArgumentDefaultsHelpFormatter(HelpFormatter):
629 """Help message formatter which adds default values to argument help.
630
631 Only the name of this class is considered a public API. All the methods
632 provided by the class are considered an implementation detail.
633 """
634
635 def _get_help_string(self, action):
636 help = action.help
637 if '%(default)' not in action.help:
638 if action.default is not SUPPRESS:
639 defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
640 if action.option_strings or action.nargs in defaulting_nargs:
641 help += ' (default: %(default)s)'
642 return help
643
644
490 645 # =====================
491 646 # Options and Arguments
492 647 # =====================
493 648
494 class ArgumentError(Exception):
495 """ArgumentError(message, argument)
649 def _get_action_name(argument):
650 if argument is None:
651 return None
652 elif argument.option_strings:
653 return '/'.join(argument.option_strings)
654 elif argument.metavar not in (None, SUPPRESS):
655 return argument.metavar
656 elif argument.dest not in (None, SUPPRESS):
657 return argument.dest
658 else:
659 return None
496 660
497 Raised whenever there was an error creating or using an argument
498 (optional or positional).
661
662 class ArgumentError(Exception):
663 """An error from creating or using an argument (optional or positional).
499 664
500 665 The string value of this exception is the message, augmented with
501 666 information about the argument that caused it.
502 667 """
503
668
504 669 def __init__(self, argument, message):
505 if argument.option_strings:
506 self.argument_name = '/'.join(argument.option_strings)
507 elif argument.metavar not in (None, SUPPRESS):
508 self.argument_name = argument.metavar
509 elif argument.dest not in (None, SUPPRESS):
510 self.argument_name = argument.dest
511 else:
512 self.argument_name = None
670 self.argument_name = _get_action_name(argument)
513 671 self.message = message
514 672
515 673 def __str__(self):
@@ -525,54 +683,55 b' class ArgumentError(Exception):'
525 683 # ==============
526 684
527 685 class Action(_AttributeHolder):
528 """Action(*strings, **options)
686 """Information about how to convert command line strings to Python objects.
529 687
530 Action objects hold the information necessary to convert a
531 set of command-line arguments (possibly including an initial option
532 string) into the desired Python object(s).
688 Action objects are used by an ArgumentParser to represent the information
689 needed to parse a single argument from one or more strings from the
690 command line. The keyword arguments to the Action constructor are also
691 all attributes of Action instances.
533 692
534 693 Keyword Arguments:
535 694
536 option_strings -- A list of command-line option strings which
537 should be associated with this action.
538
539 dest -- The name of the attribute to hold the created object(s)
540
541 nargs -- The number of command-line arguments that should be consumed.
542 By default, one argument will be consumed and a single value will
543 be produced. Other values include:
544 * N (an integer) consumes N arguments (and produces a list)
545 * '?' consumes zero or one arguments
546 * '*' consumes zero or more arguments (and produces a list)
547 * '+' consumes one or more arguments (and produces a list)
548 Note that the difference between the default and nargs=1 is that
549 with the default, a single value will be produced, while with
550 nargs=1, a list containing a single value will be produced.
551
552 const -- The value to be produced if the option is specified and the
553 option uses an action that takes no values.
554
555 default -- The value to be produced if the option is not specified.
556
557 type -- The type which the command-line arguments should be converted
558 to, should be one of 'string', 'int', 'float', 'complex' or a
559 callable object that accepts a single string argument. If None,
560 'string' is assumed.
561
562 choices -- A container of values that should be allowed. If not None,
563 after a command-line argument has been converted to the appropriate
564 type, an exception will be raised if it is not a member of this
565 collection.
566
567 required -- True if the action must always be specified at the command
568 line. This is only meaningful for optional command-line arguments.
569
570 help -- The help string describing the argument.
571
572 metavar -- The name to be used for the option's argument with the help
573 string. If None, the 'dest' value will be used as the name.
574 """
695 - option_strings -- A list of command-line option strings which
696 should be associated with this action.
697
698 - dest -- The name of the attribute to hold the created object(s)
699
700 - nargs -- The number of command-line arguments that should be
701 consumed. By default, one argument will be consumed and a single
702 value will be produced. Other values include:
703 - N (an integer) consumes N arguments (and produces a list)
704 - '?' consumes zero or one arguments
705 - '*' consumes zero or more arguments (and produces a list)
706 - '+' consumes one or more arguments (and produces a list)
707 Note that the difference between the default and nargs=1 is that
708 with the default, a single value will be produced, while with
709 nargs=1, a list containing a single value will be produced.
710
711 - const -- The value to be produced if the option is specified and the
712 option uses an action that takes no values.
713
714 - default -- The value to be produced if the option is not specified.
715
716 - type -- The type which the command-line arguments should be converted
717 to, should be one of 'string', 'int', 'float', 'complex' or a
718 callable object that accepts a single string argument. If None,
719 'string' is assumed.
720
721 - choices -- A container of values that should be allowed. If not None,
722 after a command-line argument has been converted to the appropriate
723 type, an exception will be raised if it is not a member of this
724 collection.
725
726 - required -- True if the action must always be specified at the
727 command line. This is only meaningful for optional command-line
728 arguments.
575 729
730 - help -- The help string describing the argument.
731
732 - metavar -- The name to be used for the option's argument with the
733 help string. If None, the 'dest' value will be used as the name.
734 """
576 735
577 736 def __init__(self,
578 737 option_strings,
@@ -606,14 +765,16 b' class Action(_AttributeHolder):'
606 765 'type',
607 766 'choices',
608 767 'help',
609 'metavar'
768 'metavar',
610 769 ]
611 770 return [(name, getattr(self, name)) for name in names]
612 771
613 772 def __call__(self, parser, namespace, values, option_string=None):
614 773 raise NotImplementedError(_('.__call__() not defined'))
615 774
775
616 776 class _StoreAction(Action):
777
617 778 def __init__(self,
618 779 option_strings,
619 780 dest,
@@ -644,7 +805,9 b' class _StoreAction(Action):'
644 805 def __call__(self, parser, namespace, values, option_string=None):
645 806 setattr(namespace, self.dest, values)
646 807
808
647 809 class _StoreConstAction(Action):
810
648 811 def __init__(self,
649 812 option_strings,
650 813 dest,
@@ -665,7 +828,9 b' class _StoreConstAction(Action):'
665 828 def __call__(self, parser, namespace, values, option_string=None):
666 829 setattr(namespace, self.dest, self.const)
667 830
831
668 832 class _StoreTrueAction(_StoreConstAction):
833
669 834 def __init__(self,
670 835 option_strings,
671 836 dest,
@@ -680,7 +845,9 b' class _StoreTrueAction(_StoreConstAction):'
680 845 required=required,
681 846 help=help)
682 847
848
683 849 class _StoreFalseAction(_StoreConstAction):
850
684 851 def __init__(self,
685 852 option_strings,
686 853 dest,
@@ -694,8 +861,10 b' class _StoreFalseAction(_StoreConstAction):'
694 861 default=default,
695 862 required=required,
696 863 help=help)
697
864
865
698 866 class _AppendAction(Action):
867
699 868 def __init__(self,
700 869 option_strings,
701 870 dest,
@@ -724,9 +893,13 b' class _AppendAction(Action):'
724 893 metavar=metavar)
725 894
726 895 def __call__(self, parser, namespace, values, option_string=None):
727 _ensure_value(namespace, self.dest, []).append(values)
896 items = _copy.copy(_ensure_value(namespace, self.dest, []))
897 items.append(values)
898 setattr(namespace, self.dest, items)
899
728 900
729 901 class _AppendConstAction(Action):
902
730 903 def __init__(self,
731 904 option_strings,
732 905 dest,
@@ -746,9 +919,13 b' class _AppendConstAction(Action):'
746 919 metavar=metavar)
747 920
748 921 def __call__(self, parser, namespace, values, option_string=None):
749 _ensure_value(namespace, self.dest, []).append(self.const)
922 items = _copy.copy(_ensure_value(namespace, self.dest, []))
923 items.append(self.const)
924 setattr(namespace, self.dest, items)
925
750 926
751 927 class _CountAction(Action):
928
752 929 def __init__(self,
753 930 option_strings,
754 931 dest,
@@ -767,7 +944,9 b' class _CountAction(Action):'
767 944 new_count = _ensure_value(namespace, self.dest, 0) + 1
768 945 setattr(namespace, self.dest, new_count)
769 946
947
770 948 class _HelpAction(Action):
949
771 950 def __init__(self,
772 951 option_strings,
773 952 dest=SUPPRESS,
@@ -784,7 +963,9 b' class _HelpAction(Action):'
784 963 parser.print_help()
785 964 parser.exit()
786 965
966
787 967 class _VersionAction(Action):
968
788 969 def __init__(self,
789 970 option_strings,
790 971 dest=SUPPRESS,
@@ -800,15 +981,16 b' class _VersionAction(Action):'
800 981 def __call__(self, parser, namespace, values, option_string=None):
801 982 parser.print_version()
802 983 parser.exit()
803
984
985
804 986 class _SubParsersAction(Action):
805 987
806 988 class _ChoicesPseudoAction(Action):
989
807 990 def __init__(self, name, help):
808 991 sup = super(_SubParsersAction._ChoicesPseudoAction, self)
809 992 sup.__init__(option_strings=[], dest=name, help=help)
810 993
811
812 994 def __init__(self,
813 995 option_strings,
814 996 prog,
@@ -816,7 +998,7 b' class _SubParsersAction(Action):'
816 998 dest=SUPPRESS,
817 999 help=None,
818 1000 metavar=None):
819
1001
820 1002 self._prog_prefix = prog
821 1003 self._parser_class = parser_class
822 1004 self._name_parser_map = {}
@@ -857,7 +1039,7 b' class _SubParsersAction(Action):'
857 1039 if self.dest is not SUPPRESS:
858 1040 setattr(namespace, self.dest, parser_name)
859 1041
860 # select the parser
1042 # select the parser
861 1043 try:
862 1044 parser = self._name_parser_map[parser_name]
863 1045 except KeyError:
@@ -880,21 +1062,22 b' class FileType(object):'
880 1062 ArgumentParser add_argument() method.
881 1063
882 1064 Keyword Arguments:
883 mode -- A string indicating how the file is to be opened. Accepts the
884 same values as the builtin open() function.
885 bufsize -- The file's desired buffer size. Accepts the same values as
886 the builtin open() function.
887 """
1065 - mode -- A string indicating how the file is to be opened. Accepts the
1066 same values as the builtin open() function.
1067 - bufsize -- The file's desired buffer size. Accepts the same values as
1068 the builtin open() function.
1069 """
1070
888 1071 def __init__(self, mode='r', bufsize=None):
889 1072 self._mode = mode
890 1073 self._bufsize = bufsize
891
1074
892 1075 def __call__(self, string):
893 1076 # the special argument "-" means sys.std{in,out}
894 1077 if string == '-':
895 if self._mode == 'r':
1078 if 'r' in self._mode:
896 1079 return _sys.stdin
897 elif self._mode == 'w':
1080 elif 'w' in self._mode:
898 1081 return _sys.stdout
899 1082 else:
900 1083 msg = _('argument "-" with mode %r' % self._mode)
@@ -906,16 +1089,25 b' class FileType(object):'
906 1089 else:
907 1090 return open(string, self._mode)
908 1091
1092 def __repr__(self):
1093 args = [self._mode, self._bufsize]
1094 args_str = ', '.join([repr(arg) for arg in args if arg is not None])
1095 return '%s(%s)' % (type(self).__name__, args_str)
909 1096
910 1097 # ===========================
911 1098 # Optional and Positional Parsing
912 1099 # ===========================
913 1100
914 1101 class Namespace(_AttributeHolder):
1102 """Simple object for storing attributes.
1103
1104 Implements equality by attribute names and values, and provides a simple
1105 string representation.
1106 """
915 1107
916 1108 def __init__(self, **kwargs):
917 for name, value in kwargs.iteritems():
918 setattr(self, name, value)
1109 for name in kwargs:
1110 setattr(self, name, kwargs[name])
919 1111
920 1112 def __eq__(self, other):
921 1113 return vars(self) == vars(other)
@@ -925,6 +1117,7 b' class Namespace(_AttributeHolder):'
925 1117
926 1118
927 1119 class _ActionsContainer(object):
1120
928 1121 def __init__(self,
929 1122 description,
930 1123 prefix_chars,
@@ -952,23 +1145,31 b' class _ActionsContainer(object):'
952 1145 self.register('action', 'help', _HelpAction)
953 1146 self.register('action', 'version', _VersionAction)
954 1147 self.register('action', 'parsers', _SubParsersAction)
955
1148
956 1149 # raise an exception if the conflict handler is invalid
957 1150 self._get_handler()
958 1151
959 1152 # action storage
960 self._optional_actions_list = []
961 self._positional_actions_list = []
962 self._positional_actions_full_list = []
963 self._option_strings = {}
1153 self._actions = []
1154 self._option_string_actions = {}
1155
1156 # groups
1157 self._action_groups = []
1158 self._mutually_exclusive_groups = []
964 1159
965 1160 # defaults storage
966 1161 self._defaults = {}
967 1162
1163 # determines whether an "option" looks like a negative number
1164 self._negative_number_matcher = _re.compile(r'^-\d+|-\d*.\d+$')
1165
1166 # whether or not there are any optionals that look like negative
1167 # numbers -- uses a list so it can be shared and edited
1168 self._has_negative_number_optionals = []
1169
968 1170 # ====================
969 1171 # Registration methods
970 1172 # ====================
971
972 1173 def register(self, registry_name, value, object):
973 1174 registry = self._registries.setdefault(registry_name, {})
974 1175 registry[value] = object
@@ -979,22 +1180,18 b' class _ActionsContainer(object):'
979 1180 # ==================================
980 1181 # Namespace default settings methods
981 1182 # ==================================
982
983 1183 def set_defaults(self, **kwargs):
984 1184 self._defaults.update(kwargs)
985 1185
986 1186 # if these defaults match any existing arguments, replace
987 1187 # the previous default on the object with the new one
988 for action_list in [self._option_strings.values(),
989 self._positional_actions_full_list]:
990 for action in action_list:
991 if action.dest in kwargs:
992 action.default = kwargs[action.dest]
1188 for action in self._actions:
1189 if action.dest in kwargs:
1190 action.default = kwargs[action.dest]
993 1191
994 1192 # =======================
995 1193 # Adding argument actions
996 1194 # =======================
997
998 1195 def add_argument(self, *args, **kwargs):
999 1196 """
1000 1197 add_argument(dest, ..., name=value, ...)
@@ -1019,43 +1216,88 b' class _ActionsContainer(object):'
1019 1216 kwargs['default'] = self._defaults[dest]
1020 1217 elif self.argument_default is not None:
1021 1218 kwargs['default'] = self.argument_default
1022
1219
1023 1220 # create the action object, and add it to the parser
1024 1221 action_class = self._pop_action_class(kwargs)
1025 1222 action = action_class(**kwargs)
1026 1223 return self._add_action(action)
1027 1224
1225 def add_argument_group(self, *args, **kwargs):
1226 group = _ArgumentGroup(self, *args, **kwargs)
1227 self._action_groups.append(group)
1228 return group
1229
1230 def add_mutually_exclusive_group(self, **kwargs):
1231 group = _MutuallyExclusiveGroup(self, **kwargs)
1232 self._mutually_exclusive_groups.append(group)
1233 return group
1234
1028 1235 def _add_action(self, action):
1029 1236 # resolve any conflicts
1030 1237 self._check_conflict(action)
1031 1238
1032 # add to optional or positional list
1033 if action.option_strings:
1034 self._optional_actions_list.append(action)
1035 else:
1036 self._positional_actions_list.append(action)
1037 self._positional_actions_full_list.append(action)
1239 # add to actions list
1240 self._actions.append(action)
1038 1241 action.container = self
1039 1242
1040 1243 # index the action by any option strings it has
1041 1244 for option_string in action.option_strings:
1042 self._option_strings[option_string] = action
1245 self._option_string_actions[option_string] = action
1246
1247 # set the flag if any option strings look like negative numbers
1248 for option_string in action.option_strings:
1249 if self._negative_number_matcher.match(option_string):
1250 if not self._has_negative_number_optionals:
1251 self._has_negative_number_optionals.append(True)
1043 1252
1044 1253 # return the created action
1045 1254 return action
1046 1255
1256 def _remove_action(self, action):
1257 self._actions.remove(action)
1258
1047 1259 def _add_container_actions(self, container):
1048 for action in container._optional_actions_list:
1049 self._add_action(action)
1050 for action in container._positional_actions_list:
1051 self._add_action(action)
1260 # collect groups by titles
1261 title_group_map = {}
1262 for group in self._action_groups:
1263 if group.title in title_group_map:
1264 msg = _('cannot merge actions - two groups are named %r')
1265 raise ValueError(msg % (group.title))
1266 title_group_map[group.title] = group
1267
1268 # map each action to its group
1269 group_map = {}
1270 for group in container._action_groups:
1271
1272 # if a group with the title exists, use that, otherwise
1273 # create a new group matching the container's group
1274 if group.title not in title_group_map:
1275 title_group_map[group.title] = self.add_argument_group(
1276 title=group.title,
1277 description=group.description,
1278 conflict_handler=group.conflict_handler)
1279
1280 # map the actions to their new group
1281 for action in group._group_actions:
1282 group_map[action] = title_group_map[group.title]
1283
1284 # add all actions to this container or their group
1285 for action in container._actions:
1286 group_map.get(action, self)._add_action(action)
1052 1287
1053 1288 def _get_positional_kwargs(self, dest, **kwargs):
1054 1289 # make sure required is not specified
1055 1290 if 'required' in kwargs:
1056 1291 msg = _("'required' is an invalid argument for positionals")
1057 1292 raise TypeError(msg)
1058
1293
1294 # mark positional arguments as required if at least one is
1295 # always required
1296 if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
1297 kwargs['required'] = True
1298 if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
1299 kwargs['required'] = True
1300
1059 1301 # return the keyword arguments with no option strings
1060 1302 return dict(kwargs, dest=dest, option_strings=[])
1061 1303
@@ -1078,14 +1320,14 b' class _ActionsContainer(object):'
1078 1320 raise ValueError(msg % tup)
1079 1321
1080 1322 # error on strings that are all prefix characters
1081 if not (set(option_string) - set(self.prefix_chars)):
1323 if not (_set(option_string) - _set(self.prefix_chars)):
1082 1324 msg = _('invalid option string %r: '
1083 1325 'must contain characters other than %r')
1084 1326 tup = option_string, self.prefix_chars
1085 1327 raise ValueError(msg % tup)
1086 1328
1087 1329 # strings starting with two prefix characters are long options
1088 option_strings.append(option_string)
1330 option_strings.append(option_string)
1089 1331 if option_string[0] in self.prefix_chars:
1090 1332 if option_string[1] in self.prefix_chars:
1091 1333 long_option_strings.append(option_string)
@@ -1118,11 +1360,11 b' class _ActionsContainer(object):'
1118 1360
1119 1361 def _check_conflict(self, action):
1120 1362
1121 # find all options that conflict with this option
1363 # find all options that conflict with this option
1122 1364 confl_optionals = []
1123 1365 for option_string in action.option_strings:
1124 if option_string in self._option_strings:
1125 confl_optional = self._option_strings[option_string]
1366 if option_string in self._option_string_actions:
1367 confl_optional = self._option_string_actions[option_string]
1126 1368 confl_optionals.append((option_string, confl_optional))
1127 1369
1128 1370 # resolve any conflicts
@@ -1132,24 +1374,24 b' class _ActionsContainer(object):'
1132 1374
1133 1375 def _handle_conflict_error(self, action, conflicting_actions):
1134 1376 message = _('conflicting option string(s): %s')
1135 conflict_string = ', '.join(option_string
1136 for option_string, action
1137 in conflicting_actions)
1377 conflict_string = ', '.join([option_string
1378 for option_string, action
1379 in conflicting_actions])
1138 1380 raise ArgumentError(action, message % conflict_string)
1139 1381
1140 1382 def _handle_conflict_resolve(self, action, conflicting_actions):
1141 1383
1142 # remove all conflicting options
1384 # remove all conflicting options
1143 1385 for option_string, action in conflicting_actions:
1144
1386
1145 1387 # remove the conflicting option
1146 1388 action.option_strings.remove(option_string)
1147 self._option_strings.pop(option_string, None)
1389 self._option_string_actions.pop(option_string, None)
1148 1390
1149 1391 # if the option now has no option string, remove it from the
1150 1392 # container holding it
1151 1393 if not action.option_strings:
1152 action.container._optional_actions_list.remove(action)
1394 action.container._remove_action(action)
1153 1395
1154 1396
1155 1397 class _ArgumentGroup(_ActionsContainer):
@@ -1162,15 +1404,67 b' class _ArgumentGroup(_ActionsContainer):'
1162 1404 update('argument_default', container.argument_default)
1163 1405 super_init = super(_ArgumentGroup, self).__init__
1164 1406 super_init(description=description, **kwargs)
1165
1407
1408 # group attributes
1166 1409 self.title = title
1410 self._group_actions = []
1411
1412 # share most attributes with the container
1167 1413 self._registries = container._registries
1168 self._positional_actions_full_list = container._positional_actions_full_list
1169 self._option_strings = container._option_strings
1414 self._actions = container._actions
1415 self._option_string_actions = container._option_string_actions
1170 1416 self._defaults = container._defaults
1417 self._has_negative_number_optionals = \
1418 container._has_negative_number_optionals
1419
1420 def _add_action(self, action):
1421 action = super(_ArgumentGroup, self)._add_action(action)
1422 self._group_actions.append(action)
1423 return action
1424
1425 def _remove_action(self, action):
1426 super(_ArgumentGroup, self)._remove_action(action)
1427 self._group_actions.remove(action)
1428
1429
1430 class _MutuallyExclusiveGroup(_ArgumentGroup):
1431
1432 def __init__(self, container, required=False):
1433 super(_MutuallyExclusiveGroup, self).__init__(container)
1434 self.required = required
1435 self._container = container
1436
1437 def _add_action(self, action):
1438 if action.required:
1439 msg = _('mutually exclusive arguments must be optional')
1440 raise ValueError(msg)
1441 action = self._container._add_action(action)
1442 self._group_actions.append(action)
1443 return action
1444
1445 def _remove_action(self, action):
1446 self._container._remove_action(action)
1447 self._group_actions.remove(action)
1171 1448
1172 1449
1173 1450 class ArgumentParser(_AttributeHolder, _ActionsContainer):
1451 """Object for parsing command line strings into Python objects.
1452
1453 Keyword Arguments:
1454 - prog -- The name of the program (default: sys.argv[0])
1455 - usage -- A usage message (default: auto-generated from arguments)
1456 - description -- A description of what the program does
1457 - epilog -- Text following the argument descriptions
1458 - version -- Add a -v/--version option with the given version string
1459 - parents -- Parsers whose arguments should be copied into this one
1460 - formatter_class -- HelpFormatter class for printing help messages
1461 - prefix_chars -- Characters that prefix optional arguments
1462 - fromfile_prefix_chars -- Characters that prefix files containing
1463 additional arguments
1464 - argument_default -- The default value for all arguments
1465 - conflict_handler -- String indicating how to handle conflicts
1466 - add_help -- Add a -h/-help option
1467 """
1174 1468
1175 1469 def __init__(self,
1176 1470 prog=None,
@@ -1181,6 +1475,7 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1181 1475 parents=[],
1182 1476 formatter_class=HelpFormatter,
1183 1477 prefix_chars='-',
1478 fromfile_prefix_chars=None,
1184 1479 argument_default=None,
1185 1480 conflict_handler='error',
1186 1481 add_help=True):
@@ -1200,11 +1495,13 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1200 1495 self.epilog = epilog
1201 1496 self.version = version
1202 1497 self.formatter_class = formatter_class
1498 self.fromfile_prefix_chars = fromfile_prefix_chars
1203 1499 self.add_help = add_help
1204 1500
1205 self._argument_group_class = _ArgumentGroup
1206 self._has_subparsers = False
1207 self._argument_groups = []
1501 add_group = self.add_argument_group
1502 self._positionals = add_group(_('positional arguments'))
1503 self._optionals = add_group(_('optional arguments'))
1504 self._subparsers = None
1208 1505
1209 1506 # register types
1210 1507 def identity(string):
@@ -1232,14 +1529,9 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1232 1529 else:
1233 1530 self._defaults.update(defaults)
1234 1531
1235 # determines whether an "option" looks like a negative number
1236 self._negative_number_matcher = _re.compile(r'^-\d+|-\d*.\d+$')
1237
1238
1239 1532 # =======================
1240 1533 # Pretty __repr__ methods
1241 1534 # =======================
1242
1243 1535 def _get_kwargs(self):
1244 1536 names = [
1245 1537 'prog',
@@ -1255,67 +1547,65 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1255 1547 # ==================================
1256 1548 # Optional/Positional adding methods
1257 1549 # ==================================
1258
1259 def add_argument_group(self, *args, **kwargs):
1260 group = self._argument_group_class(self, *args, **kwargs)
1261 self._argument_groups.append(group)
1262 return group
1263
1264 1550 def add_subparsers(self, **kwargs):
1265 if self._has_subparsers:
1551 if self._subparsers is not None:
1266 1552 self.error(_('cannot have multiple subparser arguments'))
1267
1553
1268 1554 # add the parser class to the arguments if it's not present
1269 1555 kwargs.setdefault('parser_class', type(self))
1270 1556
1557 if 'title' in kwargs or 'description' in kwargs:
1558 title = _(kwargs.pop('title', 'subcommands'))
1559 description = _(kwargs.pop('description', None))
1560 self._subparsers = self.add_argument_group(title, description)
1561 else:
1562 self._subparsers = self._positionals
1563
1271 1564 # prog defaults to the usage message of this parser, skipping
1272 1565 # optional arguments and with no "usage:" prefix
1273 1566 if kwargs.get('prog') is None:
1274 1567 formatter = self._get_formatter()
1275 formatter.add_usage(self.usage, [],
1276 self._get_positional_actions(), '')
1568 positionals = self._get_positional_actions()
1569 groups = self._mutually_exclusive_groups
1570 formatter.add_usage(self.usage, positionals, groups, '')
1277 1571 kwargs['prog'] = formatter.format_help().strip()
1278 1572
1279 1573 # create the parsers action and add it to the positionals list
1280 1574 parsers_class = self._pop_action_class(kwargs, 'parsers')
1281 1575 action = parsers_class(option_strings=[], **kwargs)
1282 self._positional_actions_list.append(action)
1283 self._positional_actions_full_list.append(action)
1284 self._has_subparsers = True
1576 self._subparsers._add_action(action)
1285 1577
1286 1578 # return the created parsers action
1287 1579 return action
1288 1580
1289 def _add_container_actions(self, container):
1290 super(ArgumentParser, self)._add_container_actions(container)
1291 try:
1292 groups = container._argument_groups
1293 except AttributeError:
1294 pass
1581 def _add_action(self, action):
1582 if action.option_strings:
1583 self._optionals._add_action(action)
1295 1584 else:
1296 for group in groups:
1297 new_group = self.add_argument_group(
1298 title=group.title,
1299 description=group.description,
1300 conflict_handler=group.conflict_handler)
1301 new_group._add_container_actions(group)
1585 self._positionals._add_action(action)
1586 return action
1302 1587
1303 1588 def _get_optional_actions(self):
1304 actions = []
1305 actions.extend(self._optional_actions_list)
1306 for argument_group in self._argument_groups:
1307 actions.extend(argument_group._optional_actions_list)
1308 return actions
1589 return [action
1590 for action in self._actions
1591 if action.option_strings]
1309 1592
1310 1593 def _get_positional_actions(self):
1311 return list(self._positional_actions_full_list)
1312
1594 return [action
1595 for action in self._actions
1596 if not action.option_strings]
1313 1597
1314 1598 # =====================================
1315 1599 # Command line argument parsing methods
1316 1600 # =====================================
1317
1318 1601 def parse_args(self, args=None, namespace=None):
1602 args, argv = self.parse_known_args(args, namespace)
1603 if argv:
1604 msg = _('unrecognized arguments: %s')
1605 self.error(msg % ' '.join(argv))
1606 return args
1607
1608 def parse_known_args(self, args=None, namespace=None):
1319 1609 # args default to the system args
1320 1610 if args is None:
1321 1611 args = _sys.argv[1:]
@@ -1323,42 +1613,43 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1323 1613 # default Namespace built from parser defaults
1324 1614 if namespace is None:
1325 1615 namespace = Namespace()
1326
1616
1327 1617 # add any action defaults that aren't present
1328 optional_actions = self._get_optional_actions()
1329 positional_actions = self._get_positional_actions()
1330 for action in optional_actions + positional_actions:
1618 for action in self._actions:
1331 1619 if action.dest is not SUPPRESS:
1332 1620 if not hasattr(namespace, action.dest):
1333 1621 if action.default is not SUPPRESS:
1334 1622 default = action.default
1335 if isinstance(action.default, basestring):
1623 if isinstance(action.default, _basestring):
1336 1624 default = self._get_value(action, default)
1337 1625 setattr(namespace, action.dest, default)
1338 1626
1339 1627 # add any parser defaults that aren't present
1340 for dest, value in self._defaults.iteritems():
1628 for dest in self._defaults:
1341 1629 if not hasattr(namespace, dest):
1342 setattr(namespace, dest, value)
1343
1630 setattr(namespace, dest, self._defaults[dest])
1631
1344 1632 # parse the arguments and exit if there are any errors
1345 1633 try:
1346 result = self._parse_args(args, namespace)
1347 except ArgumentError, err:
1634 return self._parse_known_args(args, namespace)
1635 except ArgumentError:
1636 err = _sys.exc_info()[1]
1348 1637 self.error(str(err))
1349 1638
1350 # make sure all required optionals are present
1351 for action in self._get_optional_actions():
1352 if action.required:
1353 if getattr(result, action.dest, None) is None:
1354 opt_strs = '/'.join(action.option_strings)
1355 msg = _('option %s is required' % opt_strs)
1356 self.error(msg)
1357
1358 # return the parsed arguments
1359 return result
1360
1361 def _parse_args(self, arg_strings, namespace):
1639 def _parse_known_args(self, arg_strings, namespace):
1640 # replace arg strings that are file references
1641 if self.fromfile_prefix_chars is not None:
1642 arg_strings = self._read_args_from_files(arg_strings)
1643
1644 # map all mutually exclusive arguments to the other arguments
1645 # they can't occur with
1646 action_conflicts = {}
1647 for mutex_group in self._mutually_exclusive_groups:
1648 group_actions = mutex_group._group_actions
1649 for i, mutex_action in enumerate(mutex_group._group_actions):
1650 conflicts = action_conflicts.setdefault(mutex_action, [])
1651 conflicts.extend(group_actions[:i])
1652 conflicts.extend(group_actions[i + 1:])
1362 1653
1363 1654 # find all option indices, and determine the arg_string_pattern
1364 1655 # which has an 'O' if there is an option at an index,
@@ -1389,30 +1680,46 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1389 1680 arg_strings_pattern = ''.join(arg_string_pattern_parts)
1390 1681
1391 1682 # converts arg strings to the appropriate and then takes the action
1683 seen_actions = _set()
1684 seen_non_default_actions = _set()
1685
1392 1686 def take_action(action, argument_strings, option_string=None):
1687 seen_actions.add(action)
1393 1688 argument_values = self._get_values(action, argument_strings)
1689
1690 # error if this argument is not allowed with other previously
1691 # seen arguments, assuming that actions that use the default
1692 # value don't really count as "present"
1693 if argument_values is not action.default:
1694 seen_non_default_actions.add(action)
1695 for conflict_action in action_conflicts.get(action, []):
1696 if conflict_action in seen_non_default_actions:
1697 msg = _('not allowed with argument %s')
1698 action_name = _get_action_name(conflict_action)
1699 raise ArgumentError(action, msg % action_name)
1700
1394 1701 # take the action if we didn't receive a SUPPRESS value
1395 # (e.g. from a default)
1702 # (e.g. from a default)
1396 1703 if argument_values is not SUPPRESS:
1397 1704 action(self, namespace, argument_values, option_string)
1398 1705
1399 1706 # function to convert arg_strings into an optional action
1400 1707 def consume_optional(start_index):
1401
1402 # determine the optional action and parse any explicit
1403 # argument out of the option string
1708
1709 # get the optional identified at this index
1404 1710 option_tuple = option_string_indices[start_index]
1405 1711 action, option_string, explicit_arg = option_tuple
1406 1712
1407 # loop because single-dash options can be chained
1713 # identify additional optionals in the same arg string
1408 1714 # (e.g. -xyz is the same as -x -y -z if no args are required)
1409 1715 match_argument = self._match_argument
1410 1716 action_tuples = []
1411 1717 while True:
1412 1718
1413 # if we found no optional action, raise an error
1719 # if we found no optional action, skip it
1414 1720 if action is None:
1415 self.error(_('no such option: %s') % option_string)
1721 extras.append(arg_strings[start_index])
1722 return start_index + 1
1416 1723
1417 1724 # if there is an explicit argument, try to match the
1418 1725 # optional's string arguments to only this
@@ -1425,19 +1732,17 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1425 1732 chars = self.prefix_chars
1426 1733 if arg_count == 0 and option_string[1] not in chars:
1427 1734 action_tuples.append((action, [], option_string))
1428 parse_optional = self._parse_optional
1429 1735 for char in self.prefix_chars:
1430 option_string = char + explicit_arg
1431 option_tuple = parse_optional(option_string)
1432 if option_tuple[0] is not None:
1736 option_string = char + explicit_arg[0]
1737 explicit_arg = explicit_arg[1:] or None
1738 optionals_map = self._option_string_actions
1739 if option_string in optionals_map:
1740 action = optionals_map[option_string]
1433 1741 break
1434 1742 else:
1435 1743 msg = _('ignored explicit argument %r')
1436 1744 raise ArgumentError(action, msg % explicit_arg)
1437 1745
1438 # set the action, etc. for the next loop iteration
1439 action, option_string, explicit_arg = option_tuple
1440
1441 1746 # if the action expect exactly one argument, we've
1442 1747 # successfully matched the option; exit the loop
1443 1748 elif arg_count == 1:
@@ -1451,7 +1756,7 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1451 1756 else:
1452 1757 msg = _('ignored explicit argument %r')
1453 1758 raise ArgumentError(action, msg % explicit_arg)
1454
1759
1455 1760 # if there is no explicit argument, try to match the
1456 1761 # optional's string arguments with the following strings
1457 1762 # if successful, exit the loop
@@ -1496,18 +1801,19 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1496 1801
1497 1802 # consume Positionals and Optionals alternately, until we have
1498 1803 # passed the last option string
1804 extras = []
1499 1805 start_index = 0
1500 1806 if option_string_indices:
1501 1807 max_option_string_index = max(option_string_indices)
1502 1808 else:
1503 1809 max_option_string_index = -1
1504 1810 while start_index <= max_option_string_index:
1505
1811
1506 1812 # consume any Positionals preceding the next option
1507 next_option_string_index = min(
1813 next_option_string_index = min([
1508 1814 index
1509 1815 for index in option_string_indices
1510 if index >= start_index)
1816 if index >= start_index])
1511 1817 if start_index != next_option_string_index:
1512 1818 positionals_end_index = consume_positionals(start_index)
1513 1819
@@ -1520,12 +1826,11 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1520 1826 start_index = positionals_end_index
1521 1827
1522 1828 # if we consumed all the positionals we could and we're not
1523 # at the index of an option string, there were unparseable
1524 # arguments
1829 # at the index of an option string, there were extra arguments
1525 1830 if start_index not in option_string_indices:
1526 msg = _('extra arguments found: %s')
1527 extras = arg_strings[start_index:next_option_string_index]
1528 self.error(msg % ' '.join(extras))
1831 strings = arg_strings[start_index:next_option_string_index]
1832 extras.extend(strings)
1833 start_index = next_option_string_index
1529 1834
1530 1835 # consume the next optional and any arguments for it
1531 1836 start_index = consume_optional(start_index)
@@ -1533,31 +1838,76 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1533 1838 # consume any positionals following the last Optional
1534 1839 stop_index = consume_positionals(start_index)
1535 1840
1536 # if we didn't consume all the argument strings, there were too
1537 # many supplied
1538 if stop_index != len(arg_strings):
1539 extras = arg_strings[stop_index:]
1540 self.error(_('extra arguments found: %s') % ' '.join(extras))
1841 # if we didn't consume all the argument strings, there were extras
1842 extras.extend(arg_strings[stop_index:])
1541 1843
1542 1844 # if we didn't use all the Positional objects, there were too few
1543 1845 # arg strings supplied.
1544 1846 if positionals:
1545 1847 self.error(_('too few arguments'))
1546 1848
1547 # return the updated namespace
1548 return namespace
1849 # make sure all required actions were present
1850 for action in self._actions:
1851 if action.required:
1852 if action not in seen_actions:
1853 name = _get_action_name(action)
1854 self.error(_('argument %s is required') % name)
1855
1856 # make sure all required groups had one option present
1857 for group in self._mutually_exclusive_groups:
1858 if group.required:
1859 for action in group._group_actions:
1860 if action in seen_non_default_actions:
1861 break
1862
1863 # if no actions were used, report the error
1864 else:
1865 names = [_get_action_name(action)
1866 for action in group._group_actions
1867 if action.help is not SUPPRESS]
1868 msg = _('one of the arguments %s is required')
1869 self.error(msg % ' '.join(names))
1870
1871 # return the updated namespace and the extra arguments
1872 return namespace, extras
1873
1874 def _read_args_from_files(self, arg_strings):
1875 # expand arguments referencing files
1876 new_arg_strings = []
1877 for arg_string in arg_strings:
1878
1879 # for regular arguments, just add them back into the list
1880 if arg_string[0] not in self.fromfile_prefix_chars:
1881 new_arg_strings.append(arg_string)
1882
1883 # replace arguments referencing files with the file content
1884 else:
1885 try:
1886 args_file = open(arg_string[1:])
1887 try:
1888 arg_strings = args_file.read().splitlines()
1889 arg_strings = self._read_args_from_files(arg_strings)
1890 new_arg_strings.extend(arg_strings)
1891 finally:
1892 args_file.close()
1893 except IOError:
1894 err = _sys.exc_info()[1]
1895 self.error(str(err))
1896
1897 # return the modified argument list
1898 return new_arg_strings
1549 1899
1550 1900 def _match_argument(self, action, arg_strings_pattern):
1551 1901 # match the pattern for this action to the arg strings
1552 1902 nargs_pattern = self._get_nargs_pattern(action)
1553 1903 match = _re.match(nargs_pattern, arg_strings_pattern)
1554 1904
1555 # raise an exception if we weren't able to find a match
1905 # raise an exception if we weren't able to find a match
1556 1906 if match is None:
1557 1907 nargs_errors = {
1558 None:_('expected one argument'),
1559 OPTIONAL:_('expected at most one argument'),
1560 ONE_OR_MORE:_('expected at least one argument')
1908 None: _('expected one argument'),
1909 OPTIONAL: _('expected at most one argument'),
1910 ONE_OR_MORE: _('expected at least one argument'),
1561 1911 }
1562 1912 default = _('expected %s argument(s)') % action.nargs
1563 1913 msg = nargs_errors.get(action.nargs, default)
@@ -1570,47 +1920,44 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1570 1920 # progressively shorten the actions list by slicing off the
1571 1921 # final actions until we find a match
1572 1922 result = []
1573 for i in xrange(len(actions), 0, -1):
1923 for i in range(len(actions), 0, -1):
1574 1924 actions_slice = actions[:i]
1575 pattern = ''.join(self._get_nargs_pattern(action)
1576 for action in actions_slice)
1925 pattern = ''.join([self._get_nargs_pattern(action)
1926 for action in actions_slice])
1577 1927 match = _re.match(pattern, arg_strings_pattern)
1578 1928 if match is not None:
1579 result.extend(len(string) for string in match.groups())
1929 result.extend([len(string) for string in match.groups()])
1580 1930 break
1581 1931
1582 1932 # return the list of arg string counts
1583 1933 return result
1584
1934
1585 1935 def _parse_optional(self, arg_string):
1936 # if it's an empty string, it was meant to be a positional
1937 if not arg_string:
1938 return None
1939
1586 1940 # if it doesn't start with a prefix, it was meant to be positional
1587 1941 if not arg_string[0] in self.prefix_chars:
1588 1942 return None
1589
1943
1590 1944 # if it's just dashes, it was meant to be positional
1591 1945 if not arg_string.strip('-'):
1592 1946 return None
1593 1947
1594 1948 # if the option string is present in the parser, return the action
1595 if arg_string in self._option_strings:
1596 action = self._option_strings[arg_string]
1949 if arg_string in self._option_string_actions:
1950 action = self._option_string_actions[arg_string]
1597 1951 return action, arg_string, None
1598 1952
1599 1953 # search through all possible prefixes of the option string
1600 1954 # and all actions in the parser for possible interpretations
1601 option_tuples = []
1602 prefix_tuples = self._get_option_prefix_tuples(arg_string)
1603 for option_string in self._option_strings:
1604 for option_prefix, explicit_arg in prefix_tuples:
1605 if option_string.startswith(option_prefix):
1606 action = self._option_strings[option_string]
1607 tup = action, option_string, explicit_arg
1608 option_tuples.append(tup)
1609 break
1955 option_tuples = self._get_option_tuples(arg_string)
1610 1956
1611 1957 # if multiple actions match, the option string was ambiguous
1612 1958 if len(option_tuples) > 1:
1613 options = ', '.join(opt_str for _, opt_str, _ in option_tuples)
1959 options = ', '.join([option_string
1960 for action, option_string, explicit_arg in option_tuples])
1614 1961 tup = arg_string, options
1615 1962 self.error(_('ambiguous option: %s could match %s') % tup)
1616 1963
@@ -1622,16 +1969,22 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1622 1969
1623 1970 # if it was not found as an option, but it looks like a negative
1624 1971 # number, it was meant to be positional
1972 # unless there are negative-number-like options
1625 1973 if self._negative_number_matcher.match(arg_string):
1974 if not self._has_negative_number_optionals:
1975 return None
1976
1977 # if it contains a space, it was meant to be a positional
1978 if ' ' in arg_string:
1626 1979 return None
1627 1980
1628 1981 # it was meant to be an optional but there is no such option
1629 1982 # in this parser (though it might be a valid option in a subparser)
1630 1983 return None, arg_string, None
1631 1984
1632 def _get_option_prefix_tuples(self, option_string):
1985 def _get_option_tuples(self, option_string):
1633 1986 result = []
1634
1987
1635 1988 # option strings starting with two prefix characters are only
1636 1989 # split at the '='
1637 1990 chars = self.prefix_chars
@@ -1641,27 +1994,43 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1641 1994 else:
1642 1995 option_prefix = option_string
1643 1996 explicit_arg = None
1644 tup = option_prefix, explicit_arg
1645 result.append(tup)
1997 for option_string in self._option_string_actions:
1998 if option_string.startswith(option_prefix):
1999 action = self._option_string_actions[option_string]
2000 tup = action, option_string, explicit_arg
2001 result.append(tup)
2002
2003 # single character options can be concatenated with their arguments
2004 # but multiple character options always have to have their argument
2005 # separate
2006 elif option_string[0] in chars and option_string[1] not in chars:
2007 option_prefix = option_string
2008 explicit_arg = None
2009 short_option_prefix = option_string[:2]
2010 short_explicit_arg = option_string[2:]
2011
2012 for option_string in self._option_string_actions:
2013 if option_string == short_option_prefix:
2014 action = self._option_string_actions[option_string]
2015 tup = action, option_string, short_explicit_arg
2016 result.append(tup)
2017 elif option_string.startswith(option_prefix):
2018 action = self._option_string_actions[option_string]
2019 tup = action, option_string, explicit_arg
2020 result.append(tup)
1646 2021
1647 # option strings starting with a single prefix character are
1648 # split at all indices
2022 # shouldn't ever get here
1649 2023 else:
1650 for first_index, char in enumerate(option_string):
1651 if char not in self.prefix_chars:
1652 break
1653 for i in xrange(len(option_string), first_index, -1):
1654 tup = option_string[:i], option_string[i:] or None
1655 result.append(tup)
2024 self.error(_('unexpected option string: %s') % option_string)
1656 2025
1657 # return the collected prefix tuples
1658 return result
2026 # return the collected option tuples
2027 return result
1659 2028
1660 2029 def _get_nargs_pattern(self, action):
1661 2030 # in all examples below, we have to allow for '--' args
1662 2031 # which are represented as '-' in the pattern
1663 2032 nargs = action.nargs
1664
2033
1665 2034 # the default (None) is assumed to be a single argument
1666 2035 if nargs is None:
1667 2036 nargs_pattern = '(-*A-*)'
@@ -1682,11 +2051,11 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1682 2051 elif nargs is PARSER:
1683 2052 nargs_pattern = '(-*A[-AO]*)'
1684 2053
1685 # all others should be integers
2054 # all others should be integers
1686 2055 else:
1687 2056 nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
1688 2057
1689 # if this is an optional action, -- is not allowed
2058 # if this is an optional action, -- is not allowed
1690 2059 if action.option_strings:
1691 2060 nargs_pattern = nargs_pattern.replace('-*', '')
1692 2061 nargs_pattern = nargs_pattern.replace('-', '')
@@ -1697,19 +2066,18 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1697 2066 # ========================
1698 2067 # Value conversion methods
1699 2068 # ========================
1700
1701 2069 def _get_values(self, action, arg_strings):
1702 2070 # for everything but PARSER args, strip out '--'
1703 2071 if action.nargs is not PARSER:
1704 2072 arg_strings = [s for s in arg_strings if s != '--']
1705
2073
1706 2074 # optional argument produces a default when not present
1707 2075 if not arg_strings and action.nargs == OPTIONAL:
1708 2076 if action.option_strings:
1709 2077 value = action.const
1710 2078 else:
1711 2079 value = action.default
1712 if isinstance(value, basestring):
2080 if isinstance(value, _basestring):
1713 2081 value = self._get_value(action, value)
1714 2082 self._check_value(action, value)
1715 2083
@@ -1722,7 +2090,7 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1722 2090 else:
1723 2091 value = arg_strings
1724 2092 self._check_value(action, value)
1725
2093
1726 2094 # single argument or optional argument produces a single value
1727 2095 elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
1728 2096 arg_string, = arg_strings
@@ -1731,24 +2099,24 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1731 2099
1732 2100 # PARSER arguments convert all values, but check only the first
1733 2101 elif action.nargs is PARSER:
1734 value = list(self._get_value(action, v) for v in arg_strings)
2102 value = [self._get_value(action, v) for v in arg_strings]
1735 2103 self._check_value(action, value[0])
1736 2104
1737 2105 # all other types of nargs produce a list
1738 2106 else:
1739 value = list(self._get_value(action, v) for v in arg_strings)
2107 value = [self._get_value(action, v) for v in arg_strings]
1740 2108 for v in value:
1741 2109 self._check_value(action, v)
1742 2110
1743 # return the converted value
2111 # return the converted value
1744 2112 return value
1745 2113
1746 2114 def _get_value(self, action, arg_string):
1747 2115 type_func = self._registry_get('type', action.type, action.type)
1748 if not callable(type_func):
2116 if not hasattr(type_func, '__call__'):
1749 2117 msg = _('%r is not callable')
1750 2118 raise ArgumentError(action, msg % type_func)
1751
2119
1752 2120 # convert the value to the appropriate type
1753 2121 try:
1754 2122 result = type_func(arg_string)
@@ -1769,46 +2137,30 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1769 2137 msg = _('invalid choice: %r (choose from %s)') % tup
1770 2138 raise ArgumentError(action, msg)
1771 2139
1772
1773
1774 2140 # =======================
1775 2141 # Help-formatting methods
1776 2142 # =======================
1777
1778 2143 def format_usage(self):
1779 2144 formatter = self._get_formatter()
1780 formatter.add_usage(self.usage,
1781 self._get_optional_actions(),
1782 self._get_positional_actions())
2145 formatter.add_usage(self.usage, self._actions,
2146 self._mutually_exclusive_groups)
1783 2147 return formatter.format_help()
1784 2148
1785 2149 def format_help(self):
1786 2150 formatter = self._get_formatter()
1787 2151
1788 2152 # usage
1789 formatter.add_usage(self.usage,
1790 self._get_optional_actions(),
1791 self._get_positional_actions())
2153 formatter.add_usage(self.usage, self._actions,
2154 self._mutually_exclusive_groups)
1792 2155
1793 # description
2156 # description
1794 2157 formatter.add_text(self.description)
1795 2158
1796 # positionals
1797 formatter.start_section(_('positional arguments'))
1798 formatter.add_arguments(self._positional_actions_list)
1799 formatter.end_section()
1800
1801 # optionals
1802 formatter.start_section(_('optional arguments'))
1803 formatter.add_arguments(self._optional_actions_list)
1804 formatter.end_section()
1805
1806 # user-defined groups
1807 for argument_group in self._argument_groups:
1808 formatter.start_section(argument_group.title)
1809 formatter.add_text(argument_group.description)
1810 formatter.add_arguments(argument_group._positional_actions_list)
1811 formatter.add_arguments(argument_group._optional_actions_list)
2159 # positionals, optionals and user-defined groups
2160 for action_group in self._action_groups:
2161 formatter.start_section(action_group.title)
2162 formatter.add_text(action_group.description)
2163 formatter.add_arguments(action_group._group_actions)
1812 2164 formatter.end_section()
1813 2165
1814 2166 # epilog
@@ -1828,7 +2180,6 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1828 2180 # =====================
1829 2181 # Help-printing methods
1830 2182 # =====================
1831
1832 2183 def print_usage(self, file=None):
1833 2184 self._print_message(self.format_usage(), file)
1834 2185
@@ -1844,11 +2195,9 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1844 2195 file = _sys.stderr
1845 2196 file.write(message)
1846 2197
1847
1848 2198 # ===============
1849 2199 # Exiting methods
1850 2200 # ===============
1851
1852 2201 def exit(self, status=0, message=None):
1853 2202 if message:
1854 2203 _sys.stderr.write(message)
@@ -1859,7 +2208,7 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):'
1859 2208
1860 2209 Prints a usage message incorporating the message to stderr and
1861 2210 exits.
1862
2211
1863 2212 If you override this in a subclass, it should not return -- it
1864 2213 should either exit or raise an exception.
1865 2214 """
@@ -359,12 +359,15 b' class IEnginePropertiesTestCase(object):'
359 359 return d
360 360
361 361 def testStrictDict(self):
362 s = """from IPython.kernel.engineservice import get_engine
363 p = get_engine(%s).properties"""%self.engine.id
362 s = """from IPython.kernel.engineservice import get_engine; p = get_engine(%s).properties"""%self.engine.id
364 363 d = self.engine.execute(s)
364 # These 3 lines cause a weird testing error on some platforms (OS X).
365 # I am leaving them here in case they are masking some really
366 # weird reactor issue. For now I will just keep my eye on this.
365 367 d.addCallback(lambda r: self.engine.execute("p['a'] = lambda _:None"))
366 368 d.addErrback(lambda f: self.assertRaises(error.InvalidProperty,
367 369 f.raiseException))
370 # Below here seems to be fine
368 371 d.addCallback(lambda r: self.engine.execute("p['a'] = range(5)"))
369 372 d.addCallback(lambda r: self.engine.execute("p['a'].append(5)"))
370 373 d.addCallback(lambda r: self.engine.get_properties('a'))
@@ -12,44 +12,6 b''
12 12 What's new
13 13 ==========
14 14
15 .. contents::
16 ..
17 1 Release dev
18 1.1 New features
19 1.2 Bug fixes
20 1.3 Backwards incompatible changes
21 2 Release 0.10
22 2.1 New features
23 2.2 Bug fixes
24 2.3 Backwards incompatible changes
25 3 Release 0.9.1
26 4 Release 0.9
27 4.1 New features
28 4.2 Bug fixes
29 4.3 Backwards incompatible changes
30 4.4 Changes merged in from IPython1
31 4.4.1 New features
32 4.4.2 Bug fixes
33 4.4.3 Backwards incompatible changes
34 5 Release 0.8.4
35 6 Release 0.8.3
36 7 Release 0.8.2
37 8 Older releases
38 ..
39
40 Release dev
41 ===========
42
43 New features
44 ------------
45
46 Bug fixes
47 ---------
48
49 Backwards incompatible changes
50 ------------------------------
51
52
53 15 Release 0.10
54 16 ============
55 17
@@ -90,6 +52,7 b' alphabetical order by first name):'
90 52 * Robert Kern: several extensions.
91 53 * Sameer D'Costa: help on critical bug #269966.
92 54 * Stephan Peijnik: feedback on Debian compliance and many man pages.
55 * Steven Bethard: we are now shipping his :mod:`argparse` module.
93 56 * Tom Fetherston: many improvements to :mod:`IPython.demo` module.
94 57 * Ville Vainio: lots of work everywhere (features, bug fixes, etc).
95 58 * Vishal Vasta: ssh support in ipcluster.
@@ -126,8 +89,6 b' New features'
126 89 using the `Numpy Documentation Standard`_ for all docstrings, and we have
127 90 tried to update as many existing ones as possible to this format.
128 91
129 .. _Numpy Documentation Standard: http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard
130
131 92 * The new :mod:`IPython.Extensions.ipy_pretty` extension by Robert Kern
132 93 provides configurable pretty-printing.
133 94
@@ -140,7 +101,8 b' New features'
140 101 :mod:`IPython.external` package, so we can use it internally and it is also
141 102 available to any IPython user. By installing it in this manner, we ensure
142 103 zero conflicts with any system-wide installation you may already have while
143 minimizing external dependencies for new users.
104 minimizing external dependencies for new users. In IPython 0.10, We ship
105 argparse version 1.0.
144 106
145 107 * An improved and much more robust test suite, that runs groups of tests in
146 108 separate subprocesses using either Nose or Twisted's :command:`trial` runner
@@ -173,8 +135,6 b' New features'
173 135 should be considered a technology preview. We plan on changing the API in
174 136 significant ways before it is final.
175 137
176 * The :mod:`argparse` module has been added to :mod:`IPython.external`.
177
178 138 * Full description of the security model added to the docs.
179 139
180 140 * cd completer: show bookmarks if no other completions are available.
@@ -188,6 +148,10 b' New features'
188 148 * %edit: If you do '%edit pasted_block', pasted_block variable gets updated
189 149 with new data (so repeated editing makes sense)
190 150
151 .. _Numpy Documentation Standard: http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard
152
153 .. _argparse: http://code.google.com/p/argparse/
154
191 155 Bug fixes
192 156 ---------
193 157
@@ -240,6 +204,9 b' Bug fixes'
240 204 * Bug #274067 'The code in get_home_dir is broken for py2exe' was
241 205 fixed.
242 206
207 * Many other small bug fixes not listed here by number (see the bzr log for
208 more info).
209
243 210 Backwards incompatible changes
244 211 ------------------------------
245 212
@@ -164,6 +164,45 b' ready to be merged. What types of things will we be looking for:'
164 164 Once your changes have been reviewed and approved, someone will merge them
165 165 into the main development branch.
166 166
167
168 Some notes for core developers when merging third-party contributions
169 =====================================================================
170
171 Core developers, who ultimately merge any approved branch (from themselves,
172 another developer, or any third-party contribution) will typically use
173 :command:`bzr merge` to merge the branch into the trunk and push it to the main
174 Launcphad site. This is a short list of things to keep in mind when doing this
175 process, so that the project history is easy to understand in the long run, and
176 that generating release notes is as painless and accurate as possible.
177
178 - When you merge any non-trivial functionality (from one small bug fix to a big
179 feature branch), please remember to always edit the changes_ file
180 accordingly. This file has one main section for each release, and if you
181 edit it as you go, noting what new features, bug fixes or API changes you
182 have made, the release notes will be almost finished when they are needed
183 later. This is much easier if done when you merge the work, rather than
184 weeks or months later by re-reading a massive Bazaar log.
185
186 - When big merges are done, the practice of putting a summary commit message in
187 the merge is *extremely* useful. It makes this kind of job much nicer,
188 because that summary log message can be almost copy/pasted without changes,
189 if it was well written, rather than dissecting the next-level messages from
190 the individual commits.
191
192 - It's important that we remember to always credit who gave us something if
193 it's not the committer. In general, we have been fairly good on this front,
194 this is just a reminder to keep things up. As a note, if you are ever
195 committing something that is completely (or almost so) a third-party
196 contribution, do the commit as::
197
198 $ bzr commit --author="Someone Else"
199
200 This way it will show that name separately in the log, which makes it even
201 easier to spot. Obviously we often rework third party contributions
202 extensively, but this is still good to keep in mind for cases when we don't
203 touch the code too much.
204
205
167 206 Documentation
168 207 =============
169 208
@@ -317,12 +356,18 b' it, you can find this script in the :file:`scripts` directory)::'
317 356
318 357 $ iptest
319 358
320 This command runs Nose with the proper options and extensions. By default,
321 :command:`iptest` runs the entire IPython test suite (skipping tests that may
322 be platform-specific or which depend on tools you may not have). But you can
323 also use it to run only one specific test file, or a specific test function.
324 For example, this will run only the :file:`test_magic` file from the test
325 suite::
359 This command colects all IPython tests into separate groups, and then calls
360 either Nose with the proper options and extensions, or Twisted's
361 :command:`trial`. This ensures that tests that need the Twisted reactor
362 management facilities execute separate of Nose. If any individual test group
363 fails, :command:`iptest` will print what you need to type so you can rerun that
364 particular test group alone for debugging.
365
366 By default, :command:`iptest` runs the entire IPython test
367 suite (skipping tests that may be platform-specific or which depend on tools
368 you may not have). But you can also use it to run only one specific test file,
369 or a specific test function. For example, this will run only the
370 :file:`test_magic` file from the test suite::
326 371
327 372 $ iptest IPython.tests.test_magic
328 373 ----------------------------------------------------------------------
@@ -345,36 +390,6 b' nosetests option. For example, you can use ``--pdb`` or ``--pdb-failures`` to'
345 390 automatically activate the interactive Pdb debugger on errors or failures. See
346 391 the nosetests documentation for further details.
347 392
348 .. warning::
349
350 Note that right now we have a nasty interaction between ipdoctest and
351 twisted. Until we figure this out, please use the following instructions to
352 ensure that at least you run all the tests.
353
354 Right now, if you now run::
355
356 $ iptest [any options] [any submodules]
357
358 it will NOT load ipdoctest but won't cause any Twisted problems.
359
360 Once you're happy that you didn't break Twisted, run::
361
362 $ iptest --with-ipdoctest [any options] [any submodules]
363
364 This MAY give a Twisted AlreadyCalledError exception at the end, but it will
365 also correctly load up all of the ipython-specific tests and doctests.
366
367 The above can be made easier with a trivial shell alias::
368
369 $ alias iptest2='iptest --with-ipdoctest'
370
371 So that you can run::
372
373 $ iptest ...
374 # Twisted happy
375 # iptest2 ...
376 # ignore possible Twisted error, this checks all the rest.
377
378 393
379 394 A few tips for writing tests
380 395 ----------------------------
@@ -450,6 +465,12 b' Release checklist'
450 465 Most of the release process is automated by the :file:`release` script in the
451 466 :file:`tools` directory. This is just a handy reminder for the release manager.
452 467
468 #. First, run :file:`build_release`, which does all the file checking and
469 building that the real release script will do. This will let you do test
470 installations, check that the build procedure runs OK, etc. You may want to
471 disable a few things like multi-version RPM building while testing, because
472 otherwise the build takes really long.
473
453 474 #. Run the release script, which makes the tar.gz, eggs and Win32 .exe
454 475 installer. It posts them to the site and registers the release with PyPI.
455 476
General Comments 0
You need to be logged in to leave comments. Login now