Back to index

python3.2  3.2.2
test_argparse.py
Go to the documentation of this file.
00001 # Author: Steven J. Bethard <steven.bethard@gmail.com>.
00002 
00003 import codecs
00004 import inspect
00005 import os
00006 import shutil
00007 import stat
00008 import sys
00009 import textwrap
00010 import tempfile
00011 import unittest
00012 import argparse
00013 
00014 from io import StringIO
00015 
00016 from test import support
00017 class StdIOBuffer(StringIO):
00018     pass
00019 
00020 class TestCase(unittest.TestCase):
00021 
00022     def assertEqual(self, obj1, obj2):
00023         if obj1 != obj2:
00024             print('')
00025             print(repr(obj1))
00026             print(repr(obj2))
00027             print(obj1)
00028             print(obj2)
00029         super(TestCase, self).assertEqual(obj1, obj2)
00030 
00031     def setUp(self):
00032         # The tests assume that line wrapping occurs at 80 columns, but this
00033         # behaviour can be overridden by setting the COLUMNS environment
00034         # variable.  To ensure that this assumption is true, unset COLUMNS.
00035         env = support.EnvironmentVarGuard()
00036         env.unset("COLUMNS")
00037         self.addCleanup(env.__exit__)
00038 
00039 
00040 class TempDirMixin(object):
00041 
00042     def setUp(self):
00043         self.temp_dir = tempfile.mkdtemp()
00044         self.old_dir = os.getcwd()
00045         os.chdir(self.temp_dir)
00046 
00047     def tearDown(self):
00048         os.chdir(self.old_dir)
00049         shutil.rmtree(self.temp_dir, True)
00050 
00051     def create_readonly_file(self, filename):
00052         file_path = os.path.join(self.temp_dir, filename)
00053         with open(file_path, 'w') as file:
00054             file.write(filename)
00055         os.chmod(file_path, stat.S_IREAD)
00056 
00057 class Sig(object):
00058 
00059     def __init__(self, *args, **kwargs):
00060         self.args = args
00061         self.kwargs = kwargs
00062 
00063 
00064 class NS(object):
00065 
00066     def __init__(self, **kwargs):
00067         self.__dict__.update(kwargs)
00068 
00069     def __repr__(self):
00070         sorted_items = sorted(self.__dict__.items())
00071         kwarg_str = ', '.join(['%s=%r' % tup for tup in sorted_items])
00072         return '%s(%s)' % (type(self).__name__, kwarg_str)
00073 
00074     def __eq__(self, other):
00075         return vars(self) == vars(other)
00076 
00077     def __ne__(self, other):
00078         return not (self == other)
00079 
00080 
00081 class ArgumentParserError(Exception):
00082 
00083     def __init__(self, message, stdout=None, stderr=None, error_code=None):
00084         Exception.__init__(self, message, stdout, stderr)
00085         self.message = message
00086         self.stdout = stdout
00087         self.stderr = stderr
00088         self.error_code = error_code
00089 
00090 
00091 def stderr_to_parser_error(parse_args, *args, **kwargs):
00092     # if this is being called recursively and stderr or stdout is already being
00093     # redirected, simply call the function and let the enclosing function
00094     # catch the exception
00095     if isinstance(sys.stderr, StdIOBuffer) or isinstance(sys.stdout, StdIOBuffer):
00096         return parse_args(*args, **kwargs)
00097 
00098     # if this is not being called recursively, redirect stderr and
00099     # use it as the ArgumentParserError message
00100     old_stdout = sys.stdout
00101     old_stderr = sys.stderr
00102     sys.stdout = StdIOBuffer()
00103     sys.stderr = StdIOBuffer()
00104     try:
00105         try:
00106             result = parse_args(*args, **kwargs)
00107             for key in list(vars(result)):
00108                 if getattr(result, key) is sys.stdout:
00109                     setattr(result, key, old_stdout)
00110                 if getattr(result, key) is sys.stderr:
00111                     setattr(result, key, old_stderr)
00112             return result
00113         except SystemExit:
00114             code = sys.exc_info()[1].code
00115             stdout = sys.stdout.getvalue()
00116             stderr = sys.stderr.getvalue()
00117             raise ArgumentParserError("SystemExit", stdout, stderr, code)
00118     finally:
00119         sys.stdout = old_stdout
00120         sys.stderr = old_stderr
00121 
00122 
00123 class ErrorRaisingArgumentParser(argparse.ArgumentParser):
00124 
00125     def parse_args(self, *args, **kwargs):
00126         parse_args = super(ErrorRaisingArgumentParser, self).parse_args
00127         return stderr_to_parser_error(parse_args, *args, **kwargs)
00128 
00129     def exit(self, *args, **kwargs):
00130         exit = super(ErrorRaisingArgumentParser, self).exit
00131         return stderr_to_parser_error(exit, *args, **kwargs)
00132 
00133     def error(self, *args, **kwargs):
00134         error = super(ErrorRaisingArgumentParser, self).error
00135         return stderr_to_parser_error(error, *args, **kwargs)
00136 
00137 
00138 class ParserTesterMetaclass(type):
00139     """Adds parser tests using the class attributes.
00140 
00141     Classes of this type should specify the following attributes:
00142 
00143     argument_signatures -- a list of Sig objects which specify
00144         the signatures of Argument objects to be created
00145     failures -- a list of args lists that should cause the parser
00146         to fail
00147     successes -- a list of (initial_args, options, remaining_args) tuples
00148         where initial_args specifies the string args to be parsed,
00149         options is a dict that should match the vars() of the options
00150         parsed out of initial_args, and remaining_args should be any
00151         remaining unparsed arguments
00152     """
00153 
00154     def __init__(cls, name, bases, bodydict):
00155         if name == 'ParserTestCase':
00156             return
00157 
00158         # default parser signature is empty
00159         if not hasattr(cls, 'parser_signature'):
00160             cls.parser_signature = Sig()
00161         if not hasattr(cls, 'parser_class'):
00162             cls.parser_class = ErrorRaisingArgumentParser
00163 
00164         # ---------------------------------------
00165         # functions for adding optional arguments
00166         # ---------------------------------------
00167         def no_groups(parser, argument_signatures):
00168             """Add all arguments directly to the parser"""
00169             for sig in argument_signatures:
00170                 parser.add_argument(*sig.args, **sig.kwargs)
00171 
00172         def one_group(parser, argument_signatures):
00173             """Add all arguments under a single group in the parser"""
00174             group = parser.add_argument_group('foo')
00175             for sig in argument_signatures:
00176                 group.add_argument(*sig.args, **sig.kwargs)
00177 
00178         def many_groups(parser, argument_signatures):
00179             """Add each argument in its own group to the parser"""
00180             for i, sig in enumerate(argument_signatures):
00181                 group = parser.add_argument_group('foo:%i' % i)
00182                 group.add_argument(*sig.args, **sig.kwargs)
00183 
00184         # --------------------------
00185         # functions for parsing args
00186         # --------------------------
00187         def listargs(parser, args):
00188             """Parse the args by passing in a list"""
00189             return parser.parse_args(args)
00190 
00191         def sysargs(parser, args):
00192             """Parse the args by defaulting to sys.argv"""
00193             old_sys_argv = sys.argv
00194             sys.argv = [old_sys_argv[0]] + args
00195             try:
00196                 return parser.parse_args()
00197             finally:
00198                 sys.argv = old_sys_argv
00199 
00200         # class that holds the combination of one optional argument
00201         # addition method and one arg parsing method
00202         class AddTests(object):
00203 
00204             def __init__(self, tester_cls, add_arguments, parse_args):
00205                 self._add_arguments = add_arguments
00206                 self._parse_args = parse_args
00207 
00208                 add_arguments_name = self._add_arguments.__name__
00209                 parse_args_name = self._parse_args.__name__
00210                 for test_func in [self.test_failures, self.test_successes]:
00211                     func_name = test_func.__name__
00212                     names = func_name, add_arguments_name, parse_args_name
00213                     test_name = '_'.join(names)
00214 
00215                     def wrapper(self, test_func=test_func):
00216                         test_func(self)
00217                     try:
00218                         wrapper.__name__ = test_name
00219                     except TypeError:
00220                         pass
00221                     setattr(tester_cls, test_name, wrapper)
00222 
00223             def _get_parser(self, tester):
00224                 args = tester.parser_signature.args
00225                 kwargs = tester.parser_signature.kwargs
00226                 parser = tester.parser_class(*args, **kwargs)
00227                 self._add_arguments(parser, tester.argument_signatures)
00228                 return parser
00229 
00230             def test_failures(self, tester):
00231                 parser = self._get_parser(tester)
00232                 for args_str in tester.failures:
00233                     args = args_str.split()
00234                     raises = tester.assertRaises
00235                     raises(ArgumentParserError, parser.parse_args, args)
00236 
00237             def test_successes(self, tester):
00238                 parser = self._get_parser(tester)
00239                 for args, expected_ns in tester.successes:
00240                     if isinstance(args, str):
00241                         args = args.split()
00242                     result_ns = self._parse_args(parser, args)
00243                     tester.assertEqual(expected_ns, result_ns)
00244 
00245         # add tests for each combination of an optionals adding method
00246         # and an arg parsing method
00247         for add_arguments in [no_groups, one_group, many_groups]:
00248             for parse_args in [listargs, sysargs]:
00249                 AddTests(cls, add_arguments, parse_args)
00250 
00251 bases = TestCase,
00252 ParserTestCase = ParserTesterMetaclass('ParserTestCase', bases, {})
00253 
00254 # ===============
00255 # Optionals tests
00256 # ===============
00257 
00258 class TestOptionalsSingleDash(ParserTestCase):
00259     """Test an Optional with a single-dash option string"""
00260 
00261     argument_signatures = [Sig('-x')]
00262     failures = ['-x', 'a', '--foo', '-x --foo', '-x -y']
00263     successes = [
00264         ('', NS(x=None)),
00265         ('-x a', NS(x='a')),
00266         ('-xa', NS(x='a')),
00267         ('-x -1', NS(x='-1')),
00268         ('-x-1', NS(x='-1')),
00269     ]
00270 
00271 
00272 class TestOptionalsSingleDashCombined(ParserTestCase):
00273     """Test an Optional with a single-dash option string"""
00274 
00275     argument_signatures = [
00276         Sig('-x', action='store_true'),
00277         Sig('-yyy', action='store_const', const=42),
00278         Sig('-z'),
00279     ]
00280     failures = ['a', '--foo', '-xa', '-x --foo', '-x -z', '-z -x',
00281                 '-yx', '-yz a', '-yyyx', '-yyyza', '-xyza']
00282     successes = [
00283         ('', NS(x=False, yyy=None, z=None)),
00284         ('-x', NS(x=True, yyy=None, z=None)),
00285         ('-za', NS(x=False, yyy=None, z='a')),
00286         ('-z a', NS(x=False, yyy=None, z='a')),
00287         ('-xza', NS(x=True, yyy=None, z='a')),
00288         ('-xz a', NS(x=True, yyy=None, z='a')),
00289         ('-x -za', NS(x=True, yyy=None, z='a')),
00290         ('-x -z a', NS(x=True, yyy=None, z='a')),
00291         ('-y', NS(x=False, yyy=42, z=None)),
00292         ('-yyy', NS(x=False, yyy=42, z=None)),
00293         ('-x -yyy -za', NS(x=True, yyy=42, z='a')),
00294         ('-x -yyy -z a', NS(x=True, yyy=42, z='a')),
00295     ]
00296 
00297 
00298 class TestOptionalsSingleDashLong(ParserTestCase):
00299     """Test an Optional with a multi-character single-dash option string"""
00300 
00301     argument_signatures = [Sig('-foo')]
00302     failures = ['-foo', 'a', '--foo', '-foo --foo', '-foo -y', '-fooa']
00303     successes = [
00304         ('', NS(foo=None)),
00305         ('-foo a', NS(foo='a')),
00306         ('-foo -1', NS(foo='-1')),
00307         ('-fo a', NS(foo='a')),
00308         ('-f a', NS(foo='a')),
00309     ]
00310 
00311 
00312 class TestOptionalsSingleDashSubsetAmbiguous(ParserTestCase):
00313     """Test Optionals where option strings are subsets of each other"""
00314 
00315     argument_signatures = [Sig('-f'), Sig('-foobar'), Sig('-foorab')]
00316     failures = ['-f', '-foo', '-fo', '-foo b', '-foob', '-fooba', '-foora']
00317     successes = [
00318         ('', NS(f=None, foobar=None, foorab=None)),
00319         ('-f a', NS(f='a', foobar=None, foorab=None)),
00320         ('-fa', NS(f='a', foobar=None, foorab=None)),
00321         ('-foa', NS(f='oa', foobar=None, foorab=None)),
00322         ('-fooa', NS(f='ooa', foobar=None, foorab=None)),
00323         ('-foobar a', NS(f=None, foobar='a', foorab=None)),
00324         ('-foorab a', NS(f=None, foobar=None, foorab='a')),
00325     ]
00326 
00327 
00328 class TestOptionalsSingleDashAmbiguous(ParserTestCase):
00329     """Test Optionals that partially match but are not subsets"""
00330 
00331     argument_signatures = [Sig('-foobar'), Sig('-foorab')]
00332     failures = ['-f', '-f a', '-fa', '-foa', '-foo', '-fo', '-foo b']
00333     successes = [
00334         ('', NS(foobar=None, foorab=None)),
00335         ('-foob a', NS(foobar='a', foorab=None)),
00336         ('-foor a', NS(foobar=None, foorab='a')),
00337         ('-fooba a', NS(foobar='a', foorab=None)),
00338         ('-foora a', NS(foobar=None, foorab='a')),
00339         ('-foobar a', NS(foobar='a', foorab=None)),
00340         ('-foorab a', NS(foobar=None, foorab='a')),
00341     ]
00342 
00343 
00344 class TestOptionalsNumeric(ParserTestCase):
00345     """Test an Optional with a short opt string"""
00346 
00347     argument_signatures = [Sig('-1', dest='one')]
00348     failures = ['-1', 'a', '-1 --foo', '-1 -y', '-1 -1', '-1 -2']
00349     successes = [
00350         ('', NS(one=None)),
00351         ('-1 a', NS(one='a')),
00352         ('-1a', NS(one='a')),
00353         ('-1-2', NS(one='-2')),
00354     ]
00355 
00356 
00357 class TestOptionalsDoubleDash(ParserTestCase):
00358     """Test an Optional with a double-dash option string"""
00359 
00360     argument_signatures = [Sig('--foo')]
00361     failures = ['--foo', '-f', '-f a', 'a', '--foo -x', '--foo --bar']
00362     successes = [
00363         ('', NS(foo=None)),
00364         ('--foo a', NS(foo='a')),
00365         ('--foo=a', NS(foo='a')),
00366         ('--foo -2.5', NS(foo='-2.5')),
00367         ('--foo=-2.5', NS(foo='-2.5')),
00368     ]
00369 
00370 
00371 class TestOptionalsDoubleDashPartialMatch(ParserTestCase):
00372     """Tests partial matching with a double-dash option string"""
00373 
00374     argument_signatures = [
00375         Sig('--badger', action='store_true'),
00376         Sig('--bat'),
00377     ]
00378     failures = ['--bar', '--b', '--ba', '--b=2', '--ba=4', '--badge 5']
00379     successes = [
00380         ('', NS(badger=False, bat=None)),
00381         ('--bat X', NS(badger=False, bat='X')),
00382         ('--bad', NS(badger=True, bat=None)),
00383         ('--badg', NS(badger=True, bat=None)),
00384         ('--badge', NS(badger=True, bat=None)),
00385         ('--badger', NS(badger=True, bat=None)),
00386     ]
00387 
00388 
00389 class TestOptionalsDoubleDashPrefixMatch(ParserTestCase):
00390     """Tests when one double-dash option string is a prefix of another"""
00391 
00392     argument_signatures = [
00393         Sig('--badger', action='store_true'),
00394         Sig('--ba'),
00395     ]
00396     failures = ['--bar', '--b', '--ba', '--b=2', '--badge 5']
00397     successes = [
00398         ('', NS(badger=False, ba=None)),
00399         ('--ba X', NS(badger=False, ba='X')),
00400         ('--ba=X', NS(badger=False, ba='X')),
00401         ('--bad', NS(badger=True, ba=None)),
00402         ('--badg', NS(badger=True, ba=None)),
00403         ('--badge', NS(badger=True, ba=None)),
00404         ('--badger', NS(badger=True, ba=None)),
00405     ]
00406 
00407 
00408 class TestOptionalsSingleDoubleDash(ParserTestCase):
00409     """Test an Optional with single- and double-dash option strings"""
00410 
00411     argument_signatures = [
00412         Sig('-f', action='store_true'),
00413         Sig('--bar'),
00414         Sig('-baz', action='store_const', const=42),
00415     ]
00416     failures = ['--bar', '-fbar', '-fbaz', '-bazf', '-b B', 'B']
00417     successes = [
00418         ('', NS(f=False, bar=None, baz=None)),
00419         ('-f', NS(f=True, bar=None, baz=None)),
00420         ('--ba B', NS(f=False, bar='B', baz=None)),
00421         ('-f --bar B', NS(f=True, bar='B', baz=None)),
00422         ('-f -b', NS(f=True, bar=None, baz=42)),
00423         ('-ba -f', NS(f=True, bar=None, baz=42)),
00424     ]
00425 
00426 
00427 class TestOptionalsAlternatePrefixChars(ParserTestCase):
00428     """Test an Optional with option strings with custom prefixes"""
00429 
00430     parser_signature = Sig(prefix_chars='+:/', add_help=False)
00431     argument_signatures = [
00432         Sig('+f', action='store_true'),
00433         Sig('::bar'),
00434         Sig('/baz', action='store_const', const=42),
00435     ]
00436     failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz', '-h', '--help', '+h', '::help', '/help']
00437     successes = [
00438         ('', NS(f=False, bar=None, baz=None)),
00439         ('+f', NS(f=True, bar=None, baz=None)),
00440         ('::ba B', NS(f=False, bar='B', baz=None)),
00441         ('+f ::bar B', NS(f=True, bar='B', baz=None)),
00442         ('+f /b', NS(f=True, bar=None, baz=42)),
00443         ('/ba +f', NS(f=True, bar=None, baz=42)),
00444     ]
00445 
00446 
00447 class TestOptionalsAlternatePrefixCharsAddedHelp(ParserTestCase):
00448     """When ``-`` not in prefix_chars, default operators created for help
00449        should use the prefix_chars in use rather than - or --
00450        http://bugs.python.org/issue9444"""
00451 
00452     parser_signature = Sig(prefix_chars='+:/', add_help=True)
00453     argument_signatures = [
00454         Sig('+f', action='store_true'),
00455         Sig('::bar'),
00456         Sig('/baz', action='store_const', const=42),
00457     ]
00458     failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz']
00459     successes = [
00460         ('', NS(f=False, bar=None, baz=None)),
00461         ('+f', NS(f=True, bar=None, baz=None)),
00462         ('::ba B', NS(f=False, bar='B', baz=None)),
00463         ('+f ::bar B', NS(f=True, bar='B', baz=None)),
00464         ('+f /b', NS(f=True, bar=None, baz=42)),
00465         ('/ba +f', NS(f=True, bar=None, baz=42))
00466     ]
00467 
00468 
00469 class TestOptionalsAlternatePrefixCharsMultipleShortArgs(ParserTestCase):
00470     """Verify that Optionals must be called with their defined prefixes"""
00471 
00472     parser_signature = Sig(prefix_chars='+-', add_help=False)
00473     argument_signatures = [
00474         Sig('-x', action='store_true'),
00475         Sig('+y', action='store_true'),
00476         Sig('+z', action='store_true'),
00477     ]
00478     failures = ['-w',
00479                 '-xyz',
00480                 '+x',
00481                 '-y',
00482                 '+xyz',
00483     ]
00484     successes = [
00485         ('', NS(x=False, y=False, z=False)),
00486         ('-x', NS(x=True, y=False, z=False)),
00487         ('+y -x', NS(x=True, y=True, z=False)),
00488         ('+yz -x', NS(x=True, y=True, z=True)),
00489     ]
00490 
00491 
00492 class TestOptionalsShortLong(ParserTestCase):
00493     """Test a combination of single- and double-dash option strings"""
00494 
00495     argument_signatures = [
00496         Sig('-v', '--verbose', '-n', '--noisy', action='store_true'),
00497     ]
00498     failures = ['--x --verbose', '-N', 'a', '-v x']
00499     successes = [
00500         ('', NS(verbose=False)),
00501         ('-v', NS(verbose=True)),
00502         ('--verbose', NS(verbose=True)),
00503         ('-n', NS(verbose=True)),
00504         ('--noisy', NS(verbose=True)),
00505     ]
00506 
00507 
00508 class TestOptionalsDest(ParserTestCase):
00509     """Tests various means of setting destination"""
00510 
00511     argument_signatures = [Sig('--foo-bar'), Sig('--baz', dest='zabbaz')]
00512     failures = ['a']
00513     successes = [
00514         ('--foo-bar f', NS(foo_bar='f', zabbaz=None)),
00515         ('--baz g', NS(foo_bar=None, zabbaz='g')),
00516         ('--foo-bar h --baz i', NS(foo_bar='h', zabbaz='i')),
00517         ('--baz j --foo-bar k', NS(foo_bar='k', zabbaz='j')),
00518     ]
00519 
00520 
00521 class TestOptionalsDefault(ParserTestCase):
00522     """Tests specifying a default for an Optional"""
00523 
00524     argument_signatures = [Sig('-x'), Sig('-y', default=42)]
00525     failures = ['a']
00526     successes = [
00527         ('', NS(x=None, y=42)),
00528         ('-xx', NS(x='x', y=42)),
00529         ('-yy', NS(x=None, y='y')),
00530     ]
00531 
00532 
00533 class TestOptionalsNargsDefault(ParserTestCase):
00534     """Tests not specifying the number of args for an Optional"""
00535 
00536     argument_signatures = [Sig('-x')]
00537     failures = ['a', '-x']
00538     successes = [
00539         ('', NS(x=None)),
00540         ('-x a', NS(x='a')),
00541     ]
00542 
00543 
00544 class TestOptionalsNargs1(ParserTestCase):
00545     """Tests specifying the 1 arg for an Optional"""
00546 
00547     argument_signatures = [Sig('-x', nargs=1)]
00548     failures = ['a', '-x']
00549     successes = [
00550         ('', NS(x=None)),
00551         ('-x a', NS(x=['a'])),
00552     ]
00553 
00554 
00555 class TestOptionalsNargs3(ParserTestCase):
00556     """Tests specifying the 3 args for an Optional"""
00557 
00558     argument_signatures = [Sig('-x', nargs=3)]
00559     failures = ['a', '-x', '-x a', '-x a b', 'a -x', 'a -x b']
00560     successes = [
00561         ('', NS(x=None)),
00562         ('-x a b c', NS(x=['a', 'b', 'c'])),
00563     ]
00564 
00565 
00566 class TestOptionalsNargsOptional(ParserTestCase):
00567     """Tests specifying an Optional arg for an Optional"""
00568 
00569     argument_signatures = [
00570         Sig('-w', nargs='?'),
00571         Sig('-x', nargs='?', const=42),
00572         Sig('-y', nargs='?', default='spam'),
00573         Sig('-z', nargs='?', type=int, const='42', default='84'),
00574     ]
00575     failures = ['2']
00576     successes = [
00577         ('', NS(w=None, x=None, y='spam', z=84)),
00578         ('-w', NS(w=None, x=None, y='spam', z=84)),
00579         ('-w 2', NS(w='2', x=None, y='spam', z=84)),
00580         ('-x', NS(w=None, x=42, y='spam', z=84)),
00581         ('-x 2', NS(w=None, x='2', y='spam', z=84)),
00582         ('-y', NS(w=None, x=None, y=None, z=84)),
00583         ('-y 2', NS(w=None, x=None, y='2', z=84)),
00584         ('-z', NS(w=None, x=None, y='spam', z=42)),
00585         ('-z 2', NS(w=None, x=None, y='spam', z=2)),
00586     ]
00587 
00588 
00589 class TestOptionalsNargsZeroOrMore(ParserTestCase):
00590     """Tests specifying an args for an Optional that accepts zero or more"""
00591 
00592     argument_signatures = [
00593         Sig('-x', nargs='*'),
00594         Sig('-y', nargs='*', default='spam'),
00595     ]
00596     failures = ['a']
00597     successes = [
00598         ('', NS(x=None, y='spam')),
00599         ('-x', NS(x=[], y='spam')),
00600         ('-x a', NS(x=['a'], y='spam')),
00601         ('-x a b', NS(x=['a', 'b'], y='spam')),
00602         ('-y', NS(x=None, y=[])),
00603         ('-y a', NS(x=None, y=['a'])),
00604         ('-y a b', NS(x=None, y=['a', 'b'])),
00605     ]
00606 
00607 
00608 class TestOptionalsNargsOneOrMore(ParserTestCase):
00609     """Tests specifying an args for an Optional that accepts one or more"""
00610 
00611     argument_signatures = [
00612         Sig('-x', nargs='+'),
00613         Sig('-y', nargs='+', default='spam'),
00614     ]
00615     failures = ['a', '-x', '-y', 'a -x', 'a -y b']
00616     successes = [
00617         ('', NS(x=None, y='spam')),
00618         ('-x a', NS(x=['a'], y='spam')),
00619         ('-x a b', NS(x=['a', 'b'], y='spam')),
00620         ('-y a', NS(x=None, y=['a'])),
00621         ('-y a b', NS(x=None, y=['a', 'b'])),
00622     ]
00623 
00624 
00625 class TestOptionalsChoices(ParserTestCase):
00626     """Tests specifying the choices for an Optional"""
00627 
00628     argument_signatures = [
00629         Sig('-f', choices='abc'),
00630         Sig('-g', type=int, choices=range(5))]
00631     failures = ['a', '-f d', '-fad', '-ga', '-g 6']
00632     successes = [
00633         ('', NS(f=None, g=None)),
00634         ('-f a', NS(f='a', g=None)),
00635         ('-f c', NS(f='c', g=None)),
00636         ('-g 0', NS(f=None, g=0)),
00637         ('-g 03', NS(f=None, g=3)),
00638         ('-fb -g4', NS(f='b', g=4)),
00639     ]
00640 
00641 
00642 class TestOptionalsRequired(ParserTestCase):
00643     """Tests the an optional action that is required"""
00644 
00645     argument_signatures = [
00646         Sig('-x', type=int, required=True),
00647     ]
00648     failures = ['a', '']
00649     successes = [
00650         ('-x 1', NS(x=1)),
00651         ('-x42', NS(x=42)),
00652     ]
00653 
00654 
00655 class TestOptionalsActionStore(ParserTestCase):
00656     """Tests the store action for an Optional"""
00657 
00658     argument_signatures = [Sig('-x', action='store')]
00659     failures = ['a', 'a -x']
00660     successes = [
00661         ('', NS(x=None)),
00662         ('-xfoo', NS(x='foo')),
00663     ]
00664 
00665 
00666 class TestOptionalsActionStoreConst(ParserTestCase):
00667     """Tests the store_const action for an Optional"""
00668 
00669     argument_signatures = [Sig('-y', action='store_const', const=object)]
00670     failures = ['a']
00671     successes = [
00672         ('', NS(y=None)),
00673         ('-y', NS(y=object)),
00674     ]
00675 
00676 
00677 class TestOptionalsActionStoreFalse(ParserTestCase):
00678     """Tests the store_false action for an Optional"""
00679 
00680     argument_signatures = [Sig('-z', action='store_false')]
00681     failures = ['a', '-za', '-z a']
00682     successes = [
00683         ('', NS(z=True)),
00684         ('-z', NS(z=False)),
00685     ]
00686 
00687 
00688 class TestOptionalsActionStoreTrue(ParserTestCase):
00689     """Tests the store_true action for an Optional"""
00690 
00691     argument_signatures = [Sig('--apple', action='store_true')]
00692     failures = ['a', '--apple=b', '--apple b']
00693     successes = [
00694         ('', NS(apple=False)),
00695         ('--apple', NS(apple=True)),
00696     ]
00697 
00698 
00699 class TestOptionalsActionAppend(ParserTestCase):
00700     """Tests the append action for an Optional"""
00701 
00702     argument_signatures = [Sig('--baz', action='append')]
00703     failures = ['a', '--baz', 'a --baz', '--baz a b']
00704     successes = [
00705         ('', NS(baz=None)),
00706         ('--baz a', NS(baz=['a'])),
00707         ('--baz a --baz b', NS(baz=['a', 'b'])),
00708     ]
00709 
00710 
00711 class TestOptionalsActionAppendWithDefault(ParserTestCase):
00712     """Tests the append action for an Optional"""
00713 
00714     argument_signatures = [Sig('--baz', action='append', default=['X'])]
00715     failures = ['a', '--baz', 'a --baz', '--baz a b']
00716     successes = [
00717         ('', NS(baz=['X'])),
00718         ('--baz a', NS(baz=['X', 'a'])),
00719         ('--baz a --baz b', NS(baz=['X', 'a', 'b'])),
00720     ]
00721 
00722 
00723 class TestOptionalsActionAppendConst(ParserTestCase):
00724     """Tests the append_const action for an Optional"""
00725 
00726     argument_signatures = [
00727         Sig('-b', action='append_const', const=Exception),
00728         Sig('-c', action='append', dest='b'),
00729     ]
00730     failures = ['a', '-c', 'a -c', '-bx', '-b x']
00731     successes = [
00732         ('', NS(b=None)),
00733         ('-b', NS(b=[Exception])),
00734         ('-b -cx -b -cyz', NS(b=[Exception, 'x', Exception, 'yz'])),
00735     ]
00736 
00737 
00738 class TestOptionalsActionAppendConstWithDefault(ParserTestCase):
00739     """Tests the append_const action for an Optional"""
00740 
00741     argument_signatures = [
00742         Sig('-b', action='append_const', const=Exception, default=['X']),
00743         Sig('-c', action='append', dest='b'),
00744     ]
00745     failures = ['a', '-c', 'a -c', '-bx', '-b x']
00746     successes = [
00747         ('', NS(b=['X'])),
00748         ('-b', NS(b=['X', Exception])),
00749         ('-b -cx -b -cyz', NS(b=['X', Exception, 'x', Exception, 'yz'])),
00750     ]
00751 
00752 
00753 class TestOptionalsActionCount(ParserTestCase):
00754     """Tests the count action for an Optional"""
00755 
00756     argument_signatures = [Sig('-x', action='count')]
00757     failures = ['a', '-x a', '-x b', '-x a -x b']
00758     successes = [
00759         ('', NS(x=None)),
00760         ('-x', NS(x=1)),
00761     ]
00762 
00763 
00764 # ================
00765 # Positional tests
00766 # ================
00767 
00768 class TestPositionalsNargsNone(ParserTestCase):
00769     """Test a Positional that doesn't specify nargs"""
00770 
00771     argument_signatures = [Sig('foo')]
00772     failures = ['', '-x', 'a b']
00773     successes = [
00774         ('a', NS(foo='a')),
00775     ]
00776 
00777 
00778 class TestPositionalsNargs1(ParserTestCase):
00779     """Test a Positional that specifies an nargs of 1"""
00780 
00781     argument_signatures = [Sig('foo', nargs=1)]
00782     failures = ['', '-x', 'a b']
00783     successes = [
00784         ('a', NS(foo=['a'])),
00785     ]
00786 
00787 
00788 class TestPositionalsNargs2(ParserTestCase):
00789     """Test a Positional that specifies an nargs of 2"""
00790 
00791     argument_signatures = [Sig('foo', nargs=2)]
00792     failures = ['', 'a', '-x', 'a b c']
00793     successes = [
00794         ('a b', NS(foo=['a', 'b'])),
00795     ]
00796 
00797 
00798 class TestPositionalsNargsZeroOrMore(ParserTestCase):
00799     """Test a Positional that specifies unlimited nargs"""
00800 
00801     argument_signatures = [Sig('foo', nargs='*')]
00802     failures = ['-x']
00803     successes = [
00804         ('', NS(foo=[])),
00805         ('a', NS(foo=['a'])),
00806         ('a b', NS(foo=['a', 'b'])),
00807     ]
00808 
00809 
00810 class TestPositionalsNargsZeroOrMoreDefault(ParserTestCase):
00811     """Test a Positional that specifies unlimited nargs and a default"""
00812 
00813     argument_signatures = [Sig('foo', nargs='*', default='bar')]
00814     failures = ['-x']
00815     successes = [
00816         ('', NS(foo='bar')),
00817         ('a', NS(foo=['a'])),
00818         ('a b', NS(foo=['a', 'b'])),
00819     ]
00820 
00821 
00822 class TestPositionalsNargsOneOrMore(ParserTestCase):
00823     """Test a Positional that specifies one or more nargs"""
00824 
00825     argument_signatures = [Sig('foo', nargs='+')]
00826     failures = ['', '-x']
00827     successes = [
00828         ('a', NS(foo=['a'])),
00829         ('a b', NS(foo=['a', 'b'])),
00830     ]
00831 
00832 
00833 class TestPositionalsNargsOptional(ParserTestCase):
00834     """Tests an Optional Positional"""
00835 
00836     argument_signatures = [Sig('foo', nargs='?')]
00837     failures = ['-x', 'a b']
00838     successes = [
00839         ('', NS(foo=None)),
00840         ('a', NS(foo='a')),
00841     ]
00842 
00843 
00844 class TestPositionalsNargsOptionalDefault(ParserTestCase):
00845     """Tests an Optional Positional with a default value"""
00846 
00847     argument_signatures = [Sig('foo', nargs='?', default=42)]
00848     failures = ['-x', 'a b']
00849     successes = [
00850         ('', NS(foo=42)),
00851         ('a', NS(foo='a')),
00852     ]
00853 
00854 
00855 class TestPositionalsNargsOptionalConvertedDefault(ParserTestCase):
00856     """Tests an Optional Positional with a default value
00857     that needs to be converted to the appropriate type.
00858     """
00859 
00860     argument_signatures = [
00861         Sig('foo', nargs='?', type=int, default='42'),
00862     ]
00863     failures = ['-x', 'a b', '1 2']
00864     successes = [
00865         ('', NS(foo=42)),
00866         ('1', NS(foo=1)),
00867     ]
00868 
00869 
00870 class TestPositionalsNargsNoneNone(ParserTestCase):
00871     """Test two Positionals that don't specify nargs"""
00872 
00873     argument_signatures = [Sig('foo'), Sig('bar')]
00874     failures = ['', '-x', 'a', 'a b c']
00875     successes = [
00876         ('a b', NS(foo='a', bar='b')),
00877     ]
00878 
00879 
00880 class TestPositionalsNargsNone1(ParserTestCase):
00881     """Test a Positional with no nargs followed by one with 1"""
00882 
00883     argument_signatures = [Sig('foo'), Sig('bar', nargs=1)]
00884     failures = ['', '--foo', 'a', 'a b c']
00885     successes = [
00886         ('a b', NS(foo='a', bar=['b'])),
00887     ]
00888 
00889 
00890 class TestPositionalsNargs2None(ParserTestCase):
00891     """Test a Positional with 2 nargs followed by one with none"""
00892 
00893     argument_signatures = [Sig('foo', nargs=2), Sig('bar')]
00894     failures = ['', '--foo', 'a', 'a b', 'a b c d']
00895     successes = [
00896         ('a b c', NS(foo=['a', 'b'], bar='c')),
00897     ]
00898 
00899 
00900 class TestPositionalsNargsNoneZeroOrMore(ParserTestCase):
00901     """Test a Positional with no nargs followed by one with unlimited"""
00902 
00903     argument_signatures = [Sig('foo'), Sig('bar', nargs='*')]
00904     failures = ['', '--foo']
00905     successes = [
00906         ('a', NS(foo='a', bar=[])),
00907         ('a b', NS(foo='a', bar=['b'])),
00908         ('a b c', NS(foo='a', bar=['b', 'c'])),
00909     ]
00910 
00911 
00912 class TestPositionalsNargsNoneOneOrMore(ParserTestCase):
00913     """Test a Positional with no nargs followed by one with one or more"""
00914 
00915     argument_signatures = [Sig('foo'), Sig('bar', nargs='+')]
00916     failures = ['', '--foo', 'a']
00917     successes = [
00918         ('a b', NS(foo='a', bar=['b'])),
00919         ('a b c', NS(foo='a', bar=['b', 'c'])),
00920     ]
00921 
00922 
00923 class TestPositionalsNargsNoneOptional(ParserTestCase):
00924     """Test a Positional with no nargs followed by one with an Optional"""
00925 
00926     argument_signatures = [Sig('foo'), Sig('bar', nargs='?')]
00927     failures = ['', '--foo', 'a b c']
00928     successes = [
00929         ('a', NS(foo='a', bar=None)),
00930         ('a b', NS(foo='a', bar='b')),
00931     ]
00932 
00933 
00934 class TestPositionalsNargsZeroOrMoreNone(ParserTestCase):
00935     """Test a Positional with unlimited nargs followed by one with none"""
00936 
00937     argument_signatures = [Sig('foo', nargs='*'), Sig('bar')]
00938     failures = ['', '--foo']
00939     successes = [
00940         ('a', NS(foo=[], bar='a')),
00941         ('a b', NS(foo=['a'], bar='b')),
00942         ('a b c', NS(foo=['a', 'b'], bar='c')),
00943     ]
00944 
00945 
00946 class TestPositionalsNargsOneOrMoreNone(ParserTestCase):
00947     """Test a Positional with one or more nargs followed by one with none"""
00948 
00949     argument_signatures = [Sig('foo', nargs='+'), Sig('bar')]
00950     failures = ['', '--foo', 'a']
00951     successes = [
00952         ('a b', NS(foo=['a'], bar='b')),
00953         ('a b c', NS(foo=['a', 'b'], bar='c')),
00954     ]
00955 
00956 
00957 class TestPositionalsNargsOptionalNone(ParserTestCase):
00958     """Test a Positional with an Optional nargs followed by one with none"""
00959 
00960     argument_signatures = [Sig('foo', nargs='?', default=42), Sig('bar')]
00961     failures = ['', '--foo', 'a b c']
00962     successes = [
00963         ('a', NS(foo=42, bar='a')),
00964         ('a b', NS(foo='a', bar='b')),
00965     ]
00966 
00967 
00968 class TestPositionalsNargs2ZeroOrMore(ParserTestCase):
00969     """Test a Positional with 2 nargs followed by one with unlimited"""
00970 
00971     argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='*')]
00972     failures = ['', '--foo', 'a']
00973     successes = [
00974         ('a b', NS(foo=['a', 'b'], bar=[])),
00975         ('a b c', NS(foo=['a', 'b'], bar=['c'])),
00976     ]
00977 
00978 
00979 class TestPositionalsNargs2OneOrMore(ParserTestCase):
00980     """Test a Positional with 2 nargs followed by one with one or more"""
00981 
00982     argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='+')]
00983     failures = ['', '--foo', 'a', 'a b']
00984     successes = [
00985         ('a b c', NS(foo=['a', 'b'], bar=['c'])),
00986     ]
00987 
00988 
00989 class TestPositionalsNargs2Optional(ParserTestCase):
00990     """Test a Positional with 2 nargs followed by one optional"""
00991 
00992     argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='?')]
00993     failures = ['', '--foo', 'a', 'a b c d']
00994     successes = [
00995         ('a b', NS(foo=['a', 'b'], bar=None)),
00996         ('a b c', NS(foo=['a', 'b'], bar='c')),
00997     ]
00998 
00999 
01000 class TestPositionalsNargsZeroOrMore1(ParserTestCase):
01001     """Test a Positional with unlimited nargs followed by one with 1"""
01002 
01003     argument_signatures = [Sig('foo', nargs='*'), Sig('bar', nargs=1)]
01004     failures = ['', '--foo', ]
01005     successes = [
01006         ('a', NS(foo=[], bar=['a'])),
01007         ('a b', NS(foo=['a'], bar=['b'])),
01008         ('a b c', NS(foo=['a', 'b'], bar=['c'])),
01009     ]
01010 
01011 
01012 class TestPositionalsNargsOneOrMore1(ParserTestCase):
01013     """Test a Positional with one or more nargs followed by one with 1"""
01014 
01015     argument_signatures = [Sig('foo', nargs='+'), Sig('bar', nargs=1)]
01016     failures = ['', '--foo', 'a']
01017     successes = [
01018         ('a b', NS(foo=['a'], bar=['b'])),
01019         ('a b c', NS(foo=['a', 'b'], bar=['c'])),
01020     ]
01021 
01022 
01023 class TestPositionalsNargsOptional1(ParserTestCase):
01024     """Test a Positional with an Optional nargs followed by one with 1"""
01025 
01026     argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs=1)]
01027     failures = ['', '--foo', 'a b c']
01028     successes = [
01029         ('a', NS(foo=None, bar=['a'])),
01030         ('a b', NS(foo='a', bar=['b'])),
01031     ]
01032 
01033 
01034 class TestPositionalsNargsNoneZeroOrMore1(ParserTestCase):
01035     """Test three Positionals: no nargs, unlimited nargs and 1 nargs"""
01036 
01037     argument_signatures = [
01038         Sig('foo'),
01039         Sig('bar', nargs='*'),
01040         Sig('baz', nargs=1),
01041     ]
01042     failures = ['', '--foo', 'a']
01043     successes = [
01044         ('a b', NS(foo='a', bar=[], baz=['b'])),
01045         ('a b c', NS(foo='a', bar=['b'], baz=['c'])),
01046     ]
01047 
01048 
01049 class TestPositionalsNargsNoneOneOrMore1(ParserTestCase):
01050     """Test three Positionals: no nargs, one or more nargs and 1 nargs"""
01051 
01052     argument_signatures = [
01053         Sig('foo'),
01054         Sig('bar', nargs='+'),
01055         Sig('baz', nargs=1),
01056     ]
01057     failures = ['', '--foo', 'a', 'b']
01058     successes = [
01059         ('a b c', NS(foo='a', bar=['b'], baz=['c'])),
01060         ('a b c d', NS(foo='a', bar=['b', 'c'], baz=['d'])),
01061     ]
01062 
01063 
01064 class TestPositionalsNargsNoneOptional1(ParserTestCase):
01065     """Test three Positionals: no nargs, optional narg and 1 nargs"""
01066 
01067     argument_signatures = [
01068         Sig('foo'),
01069         Sig('bar', nargs='?', default=0.625),
01070         Sig('baz', nargs=1),
01071     ]
01072     failures = ['', '--foo', 'a']
01073     successes = [
01074         ('a b', NS(foo='a', bar=0.625, baz=['b'])),
01075         ('a b c', NS(foo='a', bar='b', baz=['c'])),
01076     ]
01077 
01078 
01079 class TestPositionalsNargsOptionalOptional(ParserTestCase):
01080     """Test two optional nargs"""
01081 
01082     argument_signatures = [
01083         Sig('foo', nargs='?'),
01084         Sig('bar', nargs='?', default=42),
01085     ]
01086     failures = ['--foo', 'a b c']
01087     successes = [
01088         ('', NS(foo=None, bar=42)),
01089         ('a', NS(foo='a', bar=42)),
01090         ('a b', NS(foo='a', bar='b')),
01091     ]
01092 
01093 
01094 class TestPositionalsNargsOptionalZeroOrMore(ParserTestCase):
01095     """Test an Optional narg followed by unlimited nargs"""
01096 
01097     argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='*')]
01098     failures = ['--foo']
01099     successes = [
01100         ('', NS(foo=None, bar=[])),
01101         ('a', NS(foo='a', bar=[])),
01102         ('a b', NS(foo='a', bar=['b'])),
01103         ('a b c', NS(foo='a', bar=['b', 'c'])),
01104     ]
01105 
01106 
01107 class TestPositionalsNargsOptionalOneOrMore(ParserTestCase):
01108     """Test an Optional narg followed by one or more nargs"""
01109 
01110     argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='+')]
01111     failures = ['', '--foo']
01112     successes = [
01113         ('a', NS(foo=None, bar=['a'])),
01114         ('a b', NS(foo='a', bar=['b'])),
01115         ('a b c', NS(foo='a', bar=['b', 'c'])),
01116     ]
01117 
01118 
01119 class TestPositionalsChoicesString(ParserTestCase):
01120     """Test a set of single-character choices"""
01121 
01122     argument_signatures = [Sig('spam', choices=set('abcdefg'))]
01123     failures = ['', '--foo', 'h', '42', 'ef']
01124     successes = [
01125         ('a', NS(spam='a')),
01126         ('g', NS(spam='g')),
01127     ]
01128 
01129 
01130 class TestPositionalsChoicesInt(ParserTestCase):
01131     """Test a set of integer choices"""
01132 
01133     argument_signatures = [Sig('spam', type=int, choices=range(20))]
01134     failures = ['', '--foo', 'h', '42', 'ef']
01135     successes = [
01136         ('4', NS(spam=4)),
01137         ('15', NS(spam=15)),
01138     ]
01139 
01140 
01141 class TestPositionalsActionAppend(ParserTestCase):
01142     """Test the 'append' action"""
01143 
01144     argument_signatures = [
01145         Sig('spam', action='append'),
01146         Sig('spam', action='append', nargs=2),
01147     ]
01148     failures = ['', '--foo', 'a', 'a b', 'a b c d']
01149     successes = [
01150         ('a b c', NS(spam=['a', ['b', 'c']])),
01151     ]
01152 
01153 # ========================================
01154 # Combined optionals and positionals tests
01155 # ========================================
01156 
01157 class TestOptionalsNumericAndPositionals(ParserTestCase):
01158     """Tests negative number args when numeric options are present"""
01159 
01160     argument_signatures = [
01161         Sig('x', nargs='?'),
01162         Sig('-4', dest='y', action='store_true'),
01163     ]
01164     failures = ['-2', '-315']
01165     successes = [
01166         ('', NS(x=None, y=False)),
01167         ('a', NS(x='a', y=False)),
01168         ('-4', NS(x=None, y=True)),
01169         ('-4 a', NS(x='a', y=True)),
01170     ]
01171 
01172 
01173 class TestOptionalsAlmostNumericAndPositionals(ParserTestCase):
01174     """Tests negative number args when almost numeric options are present"""
01175 
01176     argument_signatures = [
01177         Sig('x', nargs='?'),
01178         Sig('-k4', dest='y', action='store_true'),
01179     ]
01180     failures = ['-k3']
01181     successes = [
01182         ('', NS(x=None, y=False)),
01183         ('-2', NS(x='-2', y=False)),
01184         ('a', NS(x='a', y=False)),
01185         ('-k4', NS(x=None, y=True)),
01186         ('-k4 a', NS(x='a', y=True)),
01187     ]
01188 
01189 
01190 class TestEmptyAndSpaceContainingArguments(ParserTestCase):
01191 
01192     argument_signatures = [
01193         Sig('x', nargs='?'),
01194         Sig('-y', '--yyy', dest='y'),
01195     ]
01196     failures = ['-y']
01197     successes = [
01198         ([''], NS(x='', y=None)),
01199         (['a badger'], NS(x='a badger', y=None)),
01200         (['-a badger'], NS(x='-a badger', y=None)),
01201         (['-y', ''], NS(x=None, y='')),
01202         (['-y', 'a badger'], NS(x=None, y='a badger')),
01203         (['-y', '-a badger'], NS(x=None, y='-a badger')),
01204         (['--yyy=a badger'], NS(x=None, y='a badger')),
01205         (['--yyy=-a badger'], NS(x=None, y='-a badger')),
01206     ]
01207 
01208 
01209 class TestPrefixCharacterOnlyArguments(ParserTestCase):
01210 
01211     parser_signature = Sig(prefix_chars='-+')
01212     argument_signatures = [
01213         Sig('-', dest='x', nargs='?', const='badger'),
01214         Sig('+', dest='y', type=int, default=42),
01215         Sig('-+-', dest='z', action='store_true'),
01216     ]
01217     failures = ['-y', '+ -']
01218     successes = [
01219         ('', NS(x=None, y=42, z=False)),
01220         ('-', NS(x='badger', y=42, z=False)),
01221         ('- X', NS(x='X', y=42, z=False)),
01222         ('+ -3', NS(x=None, y=-3, z=False)),
01223         ('-+-', NS(x=None, y=42, z=True)),
01224         ('- ===', NS(x='===', y=42, z=False)),
01225     ]
01226 
01227 
01228 class TestNargsZeroOrMore(ParserTestCase):
01229     """Tests specifying an args for an Optional that accepts zero or more"""
01230 
01231     argument_signatures = [Sig('-x', nargs='*'), Sig('y', nargs='*')]
01232     failures = []
01233     successes = [
01234         ('', NS(x=None, y=[])),
01235         ('-x', NS(x=[], y=[])),
01236         ('-x a', NS(x=['a'], y=[])),
01237         ('-x a -- b', NS(x=['a'], y=['b'])),
01238         ('a', NS(x=None, y=['a'])),
01239         ('a -x', NS(x=[], y=['a'])),
01240         ('a -x b', NS(x=['b'], y=['a'])),
01241     ]
01242 
01243 
01244 class TestNargsRemainder(ParserTestCase):
01245     """Tests specifying a positional with nargs=REMAINDER"""
01246 
01247     argument_signatures = [Sig('x'), Sig('y', nargs='...'), Sig('-z')]
01248     failures = ['', '-z', '-z Z']
01249     successes = [
01250         ('X', NS(x='X', y=[], z=None)),
01251         ('-z Z X', NS(x='X', y=[], z='Z')),
01252         ('X A B -z Z', NS(x='X', y=['A', 'B', '-z', 'Z'], z=None)),
01253         ('X Y --foo', NS(x='X', y=['Y', '--foo'], z=None)),
01254     ]
01255 
01256 
01257 class TestOptionLike(ParserTestCase):
01258     """Tests options that may or may not be arguments"""
01259 
01260     argument_signatures = [
01261         Sig('-x', type=float),
01262         Sig('-3', type=float, dest='y'),
01263         Sig('z', nargs='*'),
01264     ]
01265     failures = ['-x', '-y2.5', '-xa', '-x -a',
01266                 '-x -3', '-x -3.5', '-3 -3.5',
01267                 '-x -2.5', '-x -2.5 a', '-3 -.5',
01268                 'a x -1', '-x -1 a', '-3 -1 a']
01269     successes = [
01270         ('', NS(x=None, y=None, z=[])),
01271         ('-x 2.5', NS(x=2.5, y=None, z=[])),
01272         ('-x 2.5 a', NS(x=2.5, y=None, z=['a'])),
01273         ('-3.5', NS(x=None, y=0.5, z=[])),
01274         ('-3-.5', NS(x=None, y=-0.5, z=[])),
01275         ('-3 .5', NS(x=None, y=0.5, z=[])),
01276         ('a -3.5', NS(x=None, y=0.5, z=['a'])),
01277         ('a', NS(x=None, y=None, z=['a'])),
01278         ('a -x 1', NS(x=1.0, y=None, z=['a'])),
01279         ('-x 1 a', NS(x=1.0, y=None, z=['a'])),
01280         ('-3 1 a', NS(x=None, y=1.0, z=['a'])),
01281     ]
01282 
01283 
01284 class TestDefaultSuppress(ParserTestCase):
01285     """Test actions with suppressed defaults"""
01286 
01287     argument_signatures = [
01288         Sig('foo', nargs='?', default=argparse.SUPPRESS),
01289         Sig('bar', nargs='*', default=argparse.SUPPRESS),
01290         Sig('--baz', action='store_true', default=argparse.SUPPRESS),
01291     ]
01292     failures = ['-x']
01293     successes = [
01294         ('', NS()),
01295         ('a', NS(foo='a')),
01296         ('a b', NS(foo='a', bar=['b'])),
01297         ('--baz', NS(baz=True)),
01298         ('a --baz', NS(foo='a', baz=True)),
01299         ('--baz a b', NS(foo='a', bar=['b'], baz=True)),
01300     ]
01301 
01302 
01303 class TestParserDefaultSuppress(ParserTestCase):
01304     """Test actions with a parser-level default of SUPPRESS"""
01305 
01306     parser_signature = Sig(argument_default=argparse.SUPPRESS)
01307     argument_signatures = [
01308         Sig('foo', nargs='?'),
01309         Sig('bar', nargs='*'),
01310         Sig('--baz', action='store_true'),
01311     ]
01312     failures = ['-x']
01313     successes = [
01314         ('', NS()),
01315         ('a', NS(foo='a')),
01316         ('a b', NS(foo='a', bar=['b'])),
01317         ('--baz', NS(baz=True)),
01318         ('a --baz', NS(foo='a', baz=True)),
01319         ('--baz a b', NS(foo='a', bar=['b'], baz=True)),
01320     ]
01321 
01322 
01323 class TestParserDefault42(ParserTestCase):
01324     """Test actions with a parser-level default of 42"""
01325 
01326     parser_signature = Sig(argument_default=42, version='1.0')
01327     argument_signatures = [
01328         Sig('foo', nargs='?'),
01329         Sig('bar', nargs='*'),
01330         Sig('--baz', action='store_true'),
01331     ]
01332     failures = ['-x']
01333     successes = [
01334         ('', NS(foo=42, bar=42, baz=42)),
01335         ('a', NS(foo='a', bar=42, baz=42)),
01336         ('a b', NS(foo='a', bar=['b'], baz=42)),
01337         ('--baz', NS(foo=42, bar=42, baz=True)),
01338         ('a --baz', NS(foo='a', bar=42, baz=True)),
01339         ('--baz a b', NS(foo='a', bar=['b'], baz=True)),
01340     ]
01341 
01342 
01343 class TestArgumentsFromFile(TempDirMixin, ParserTestCase):
01344     """Test reading arguments from a file"""
01345 
01346     def setUp(self):
01347         super(TestArgumentsFromFile, self).setUp()
01348         file_texts = [
01349             ('hello', 'hello world!\n'),
01350             ('recursive', '-a\n'
01351                           'A\n'
01352                           '@hello'),
01353             ('invalid', '@no-such-path\n'),
01354         ]
01355         for path, text in file_texts:
01356             file = open(path, 'w')
01357             file.write(text)
01358             file.close()
01359 
01360     parser_signature = Sig(fromfile_prefix_chars='@')
01361     argument_signatures = [
01362         Sig('-a'),
01363         Sig('x'),
01364         Sig('y', nargs='+'),
01365     ]
01366     failures = ['', '-b', 'X', '@invalid', '@missing']
01367     successes = [
01368         ('X Y', NS(a=None, x='X', y=['Y'])),
01369         ('X -a A Y Z', NS(a='A', x='X', y=['Y', 'Z'])),
01370         ('@hello X', NS(a=None, x='hello world!', y=['X'])),
01371         ('X @hello', NS(a=None, x='X', y=['hello world!'])),
01372         ('-a B @recursive Y Z', NS(a='A', x='hello world!', y=['Y', 'Z'])),
01373         ('X @recursive Z -a B', NS(a='B', x='X', y=['hello world!', 'Z'])),
01374     ]
01375 
01376 
01377 class TestArgumentsFromFileConverter(TempDirMixin, ParserTestCase):
01378     """Test reading arguments from a file"""
01379 
01380     def setUp(self):
01381         super(TestArgumentsFromFileConverter, self).setUp()
01382         file_texts = [
01383             ('hello', 'hello world!\n'),
01384         ]
01385         for path, text in file_texts:
01386             file = open(path, 'w')
01387             file.write(text)
01388             file.close()
01389 
01390     class FromFileConverterArgumentParser(ErrorRaisingArgumentParser):
01391 
01392         def convert_arg_line_to_args(self, arg_line):
01393             for arg in arg_line.split():
01394                 if not arg.strip():
01395                     continue
01396                 yield arg
01397     parser_class = FromFileConverterArgumentParser
01398     parser_signature = Sig(fromfile_prefix_chars='@')
01399     argument_signatures = [
01400         Sig('y', nargs='+'),
01401     ]
01402     failures = []
01403     successes = [
01404         ('@hello X', NS(y=['hello', 'world!', 'X'])),
01405     ]
01406 
01407 
01408 # =====================
01409 # Type conversion tests
01410 # =====================
01411 
01412 class TestFileTypeRepr(TestCase):
01413 
01414     def test_r(self):
01415         type = argparse.FileType('r')
01416         self.assertEqual("FileType('r')", repr(type))
01417 
01418     def test_wb_1(self):
01419         type = argparse.FileType('wb', 1)
01420         self.assertEqual("FileType('wb', 1)", repr(type))
01421 
01422 
01423 class RFile(object):
01424     seen = {}
01425 
01426     def __init__(self, name):
01427         self.name = name
01428 
01429     def __eq__(self, other):
01430         if other in self.seen:
01431             text = self.seen[other]
01432         else:
01433             text = self.seen[other] = other.read()
01434             other.close()
01435         if not isinstance(text, str):
01436             text = text.decode('ascii')
01437         return self.name == other.name == text
01438 
01439 
01440 class TestFileTypeR(TempDirMixin, ParserTestCase):
01441     """Test the FileType option/argument type for reading files"""
01442 
01443     def setUp(self):
01444         super(TestFileTypeR, self).setUp()
01445         for file_name in ['foo', 'bar']:
01446             file = open(os.path.join(self.temp_dir, file_name), 'w')
01447             file.write(file_name)
01448             file.close()
01449         self.create_readonly_file('readonly')
01450 
01451     argument_signatures = [
01452         Sig('-x', type=argparse.FileType()),
01453         Sig('spam', type=argparse.FileType('r')),
01454     ]
01455     failures = ['-x', '', 'non-existent-file.txt']
01456     successes = [
01457         ('foo', NS(x=None, spam=RFile('foo'))),
01458         ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
01459         ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
01460         ('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
01461         ('readonly', NS(x=None, spam=RFile('readonly'))),
01462     ]
01463 
01464 
01465 class TestFileTypeRB(TempDirMixin, ParserTestCase):
01466     """Test the FileType option/argument type for reading files"""
01467 
01468     def setUp(self):
01469         super(TestFileTypeRB, self).setUp()
01470         for file_name in ['foo', 'bar']:
01471             file = open(os.path.join(self.temp_dir, file_name), 'w')
01472             file.write(file_name)
01473             file.close()
01474 
01475     argument_signatures = [
01476         Sig('-x', type=argparse.FileType('rb')),
01477         Sig('spam', type=argparse.FileType('rb')),
01478     ]
01479     failures = ['-x', '']
01480     successes = [
01481         ('foo', NS(x=None, spam=RFile('foo'))),
01482         ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
01483         ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
01484         ('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
01485     ]
01486 
01487 
01488 class WFile(object):
01489     seen = set()
01490 
01491     def __init__(self, name):
01492         self.name = name
01493 
01494     def __eq__(self, other):
01495         if other not in self.seen:
01496             text = 'Check that file is writable.'
01497             if 'b' in other.mode:
01498                 text = text.encode('ascii')
01499             other.write(text)
01500             other.close()
01501             self.seen.add(other)
01502         return self.name == other.name
01503 
01504 
01505 class TestFileTypeW(TempDirMixin, ParserTestCase):
01506     """Test the FileType option/argument type for writing files"""
01507 
01508     def setUp(self):
01509         super(TestFileTypeW, self).setUp()
01510         self.create_readonly_file('readonly')
01511 
01512     argument_signatures = [
01513         Sig('-x', type=argparse.FileType('w')),
01514         Sig('spam', type=argparse.FileType('w')),
01515     ]
01516     failures = ['-x', '', 'readonly']
01517     successes = [
01518         ('foo', NS(x=None, spam=WFile('foo'))),
01519         ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),
01520         ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))),
01521         ('-x - -', NS(x=sys.stdout, spam=sys.stdout)),
01522     ]
01523 
01524 
01525 class TestFileTypeWB(TempDirMixin, ParserTestCase):
01526 
01527     argument_signatures = [
01528         Sig('-x', type=argparse.FileType('wb')),
01529         Sig('spam', type=argparse.FileType('wb')),
01530     ]
01531     failures = ['-x', '']
01532     successes = [
01533         ('foo', NS(x=None, spam=WFile('foo'))),
01534         ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),
01535         ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))),
01536         ('-x - -', NS(x=sys.stdout, spam=sys.stdout)),
01537     ]
01538 
01539 
01540 class TestTypeCallable(ParserTestCase):
01541     """Test some callables as option/argument types"""
01542 
01543     argument_signatures = [
01544         Sig('--eggs', type=complex),
01545         Sig('spam', type=float),
01546     ]
01547     failures = ['a', '42j', '--eggs a', '--eggs 2i']
01548     successes = [
01549         ('--eggs=42 42', NS(eggs=42, spam=42.0)),
01550         ('--eggs 2j -- -1.5', NS(eggs=2j, spam=-1.5)),
01551         ('1024.675', NS(eggs=None, spam=1024.675)),
01552     ]
01553 
01554 
01555 class TestTypeUserDefined(ParserTestCase):
01556     """Test a user-defined option/argument type"""
01557 
01558     class MyType(TestCase):
01559 
01560         def __init__(self, value):
01561             self.value = value
01562 
01563         def __eq__(self, other):
01564             return (type(self), self.value) == (type(other), other.value)
01565 
01566     argument_signatures = [
01567         Sig('-x', type=MyType),
01568         Sig('spam', type=MyType),
01569     ]
01570     failures = []
01571     successes = [
01572         ('a -x b', NS(x=MyType('b'), spam=MyType('a'))),
01573         ('-xf g', NS(x=MyType('f'), spam=MyType('g'))),
01574     ]
01575 
01576 
01577 class TestTypeClassicClass(ParserTestCase):
01578     """Test a classic class type"""
01579 
01580     class C:
01581 
01582         def __init__(self, value):
01583             self.value = value
01584 
01585         def __eq__(self, other):
01586             return (type(self), self.value) == (type(other), other.value)
01587 
01588     argument_signatures = [
01589         Sig('-x', type=C),
01590         Sig('spam', type=C),
01591     ]
01592     failures = []
01593     successes = [
01594         ('a -x b', NS(x=C('b'), spam=C('a'))),
01595         ('-xf g', NS(x=C('f'), spam=C('g'))),
01596     ]
01597 
01598 
01599 class TestTypeRegistration(TestCase):
01600     """Test a user-defined type by registering it"""
01601 
01602     def test(self):
01603 
01604         def get_my_type(string):
01605             return 'my_type{%s}' % string
01606 
01607         parser = argparse.ArgumentParser()
01608         parser.register('type', 'my_type', get_my_type)
01609         parser.add_argument('-x', type='my_type')
01610         parser.add_argument('y', type='my_type')
01611 
01612         self.assertEqual(parser.parse_args('1'.split()),
01613                          NS(x=None, y='my_type{1}'))
01614         self.assertEqual(parser.parse_args('-x 1 42'.split()),
01615                          NS(x='my_type{1}', y='my_type{42}'))
01616 
01617 
01618 # ============
01619 # Action tests
01620 # ============
01621 
01622 class TestActionUserDefined(ParserTestCase):
01623     """Test a user-defined option/argument action"""
01624 
01625     class OptionalAction(argparse.Action):
01626 
01627         def __call__(self, parser, namespace, value, option_string=None):
01628             try:
01629                 # check destination and option string
01630                 assert self.dest == 'spam', 'dest: %s' % self.dest
01631                 assert option_string == '-s', 'flag: %s' % option_string
01632                 # when option is before argument, badger=2, and when
01633                 # option is after argument, badger=<whatever was set>
01634                 expected_ns = NS(spam=0.25)
01635                 if value in [0.125, 0.625]:
01636                     expected_ns.badger = 2
01637                 elif value in [2.0]:
01638                     expected_ns.badger = 84
01639                 else:
01640                     raise AssertionError('value: %s' % value)
01641                 assert expected_ns == namespace, ('expected %s, got %s' %
01642                                                   (expected_ns, namespace))
01643             except AssertionError:
01644                 e = sys.exc_info()[1]
01645                 raise ArgumentParserError('opt_action failed: %s' % e)
01646             setattr(namespace, 'spam', value)
01647 
01648     class PositionalAction(argparse.Action):
01649 
01650         def __call__(self, parser, namespace, value, option_string=None):
01651             try:
01652                 assert option_string is None, ('option_string: %s' %
01653                                                option_string)
01654                 # check destination
01655                 assert self.dest == 'badger', 'dest: %s' % self.dest
01656                 # when argument is before option, spam=0.25, and when
01657                 # option is after argument, spam=<whatever was set>
01658                 expected_ns = NS(badger=2)
01659                 if value in [42, 84]:
01660                     expected_ns.spam = 0.25
01661                 elif value in [1]:
01662                     expected_ns.spam = 0.625
01663                 elif value in [2]:
01664                     expected_ns.spam = 0.125
01665                 else:
01666                     raise AssertionError('value: %s' % value)
01667                 assert expected_ns == namespace, ('expected %s, got %s' %
01668                                                   (expected_ns, namespace))
01669             except AssertionError:
01670                 e = sys.exc_info()[1]
01671                 raise ArgumentParserError('arg_action failed: %s' % e)
01672             setattr(namespace, 'badger', value)
01673 
01674     argument_signatures = [
01675         Sig('-s', dest='spam', action=OptionalAction,
01676             type=float, default=0.25),
01677         Sig('badger', action=PositionalAction,
01678             type=int, nargs='?', default=2),
01679     ]
01680     failures = []
01681     successes = [
01682         ('-s0.125', NS(spam=0.125, badger=2)),
01683         ('42', NS(spam=0.25, badger=42)),
01684         ('-s 0.625 1', NS(spam=0.625, badger=1)),
01685         ('84 -s2', NS(spam=2.0, badger=84)),
01686     ]
01687 
01688 
01689 class TestActionRegistration(TestCase):
01690     """Test a user-defined action supplied by registering it"""
01691 
01692     class MyAction(argparse.Action):
01693 
01694         def __call__(self, parser, namespace, values, option_string=None):
01695             setattr(namespace, self.dest, 'foo[%s]' % values)
01696 
01697     def test(self):
01698 
01699         parser = argparse.ArgumentParser()
01700         parser.register('action', 'my_action', self.MyAction)
01701         parser.add_argument('badger', action='my_action')
01702 
01703         self.assertEqual(parser.parse_args(['1']), NS(badger='foo[1]'))
01704         self.assertEqual(parser.parse_args(['42']), NS(badger='foo[42]'))
01705 
01706 
01707 # ================
01708 # Subparsers tests
01709 # ================
01710 
01711 class TestAddSubparsers(TestCase):
01712     """Test the add_subparsers method"""
01713 
01714     def assertArgumentParserError(self, *args, **kwargs):
01715         self.assertRaises(ArgumentParserError, *args, **kwargs)
01716 
01717     def _get_parser(self, subparser_help=False, prefix_chars=None,
01718                     aliases=False):
01719         # create a parser with a subparsers argument
01720         if prefix_chars:
01721             parser = ErrorRaisingArgumentParser(
01722                 prog='PROG', description='main description', prefix_chars=prefix_chars)
01723             parser.add_argument(
01724                 prefix_chars[0] * 2 + 'foo', action='store_true', help='foo help')
01725         else:
01726             parser = ErrorRaisingArgumentParser(
01727                 prog='PROG', description='main description')
01728             parser.add_argument(
01729                 '--foo', action='store_true', help='foo help')
01730         parser.add_argument(
01731             'bar', type=float, help='bar help')
01732 
01733         # check that only one subparsers argument can be added
01734         subparsers_kwargs = {}
01735         if aliases:
01736             subparsers_kwargs['metavar'] = 'COMMAND'
01737             subparsers_kwargs['title'] = 'commands'
01738         else:
01739             subparsers_kwargs['help'] = 'command help'
01740         subparsers = parser.add_subparsers(**subparsers_kwargs)
01741         self.assertArgumentParserError(parser.add_subparsers)
01742 
01743         # add first sub-parser
01744         parser1_kwargs = dict(description='1 description')
01745         if subparser_help:
01746             parser1_kwargs['help'] = '1 help'
01747         if aliases:
01748             parser1_kwargs['aliases'] = ['1alias1', '1alias2']
01749         parser1 = subparsers.add_parser('1', **parser1_kwargs)
01750         parser1.add_argument('-w', type=int, help='w help')
01751         parser1.add_argument('x', choices='abc', help='x help')
01752 
01753         # add second sub-parser
01754         parser2_kwargs = dict(description='2 description')
01755         if subparser_help:
01756             parser2_kwargs['help'] = '2 help'
01757         parser2 = subparsers.add_parser('2', **parser2_kwargs)
01758         parser2.add_argument('-y', choices='123', help='y help')
01759         parser2.add_argument('z', type=complex, nargs='*', help='z help')
01760 
01761         # return the main parser
01762         return parser
01763 
01764     def setUp(self):
01765         super().setUp()
01766         self.parser = self._get_parser()
01767         self.command_help_parser = self._get_parser(subparser_help=True)
01768 
01769     def test_parse_args_failures(self):
01770         # check some failure cases:
01771         for args_str in ['', 'a', 'a a', '0.5 a', '0.5 1',
01772                          '0.5 1 -y', '0.5 2 -w']:
01773             args = args_str.split()
01774             self.assertArgumentParserError(self.parser.parse_args, args)
01775 
01776     def test_parse_args(self):
01777         # check some non-failure cases:
01778         self.assertEqual(
01779             self.parser.parse_args('0.5 1 b -w 7'.split()),
01780             NS(foo=False, bar=0.5, w=7, x='b'),
01781         )
01782         self.assertEqual(
01783             self.parser.parse_args('0.25 --foo 2 -y 2 3j -- -1j'.split()),
01784             NS(foo=True, bar=0.25, y='2', z=[3j, -1j]),
01785         )
01786         self.assertEqual(
01787             self.parser.parse_args('--foo 0.125 1 c'.split()),
01788             NS(foo=True, bar=0.125, w=None, x='c'),
01789         )
01790 
01791     def test_parse_known_args(self):
01792         self.assertEqual(
01793             self.parser.parse_known_args('0.5 1 b -w 7'.split()),
01794             (NS(foo=False, bar=0.5, w=7, x='b'), []),
01795         )
01796         self.assertEqual(
01797             self.parser.parse_known_args('0.5 -p 1 b -w 7'.split()),
01798             (NS(foo=False, bar=0.5, w=7, x='b'), ['-p']),
01799         )
01800         self.assertEqual(
01801             self.parser.parse_known_args('0.5 1 b -w 7 -p'.split()),
01802             (NS(foo=False, bar=0.5, w=7, x='b'), ['-p']),
01803         )
01804         self.assertEqual(
01805             self.parser.parse_known_args('0.5 1 b -q -rs -w 7'.split()),
01806             (NS(foo=False, bar=0.5, w=7, x='b'), ['-q', '-rs']),
01807         )
01808         self.assertEqual(
01809             self.parser.parse_known_args('0.5 -W 1 b -X Y -w 7 Z'.split()),
01810             (NS(foo=False, bar=0.5, w=7, x='b'), ['-W', '-X', 'Y', 'Z']),
01811         )
01812 
01813     def test_dest(self):
01814         parser = ErrorRaisingArgumentParser()
01815         parser.add_argument('--foo', action='store_true')
01816         subparsers = parser.add_subparsers(dest='bar')
01817         parser1 = subparsers.add_parser('1')
01818         parser1.add_argument('baz')
01819         self.assertEqual(NS(foo=False, bar='1', baz='2'),
01820                          parser.parse_args('1 2'.split()))
01821 
01822     def test_help(self):
01823         self.assertEqual(self.parser.format_usage(),
01824                          'usage: PROG [-h] [--foo] bar {1,2} ...\n')
01825         self.assertEqual(self.parser.format_help(), textwrap.dedent('''\
01826             usage: PROG [-h] [--foo] bar {1,2} ...
01827 
01828             main description
01829 
01830             positional arguments:
01831               bar         bar help
01832               {1,2}       command help
01833 
01834             optional arguments:
01835               -h, --help  show this help message and exit
01836               --foo       foo help
01837             '''))
01838 
01839     def test_help_extra_prefix_chars(self):
01840         # Make sure - is still used for help if it is a non-first prefix char
01841         parser = self._get_parser(prefix_chars='+:-')
01842         self.assertEqual(parser.format_usage(),
01843                          'usage: PROG [-h] [++foo] bar {1,2} ...\n')
01844         self.assertEqual(parser.format_help(), textwrap.dedent('''\
01845             usage: PROG [-h] [++foo] bar {1,2} ...
01846 
01847             main description
01848 
01849             positional arguments:
01850               bar         bar help
01851               {1,2}       command help
01852 
01853             optional arguments:
01854               -h, --help  show this help message and exit
01855               ++foo       foo help
01856             '''))
01857 
01858 
01859     def test_help_alternate_prefix_chars(self):
01860         parser = self._get_parser(prefix_chars='+:/')
01861         self.assertEqual(parser.format_usage(),
01862                          'usage: PROG [+h] [++foo] bar {1,2} ...\n')
01863         self.assertEqual(parser.format_help(), textwrap.dedent('''\
01864             usage: PROG [+h] [++foo] bar {1,2} ...
01865 
01866             main description
01867 
01868             positional arguments:
01869               bar         bar help
01870               {1,2}       command help
01871 
01872             optional arguments:
01873               +h, ++help  show this help message and exit
01874               ++foo       foo help
01875             '''))
01876 
01877     def test_parser_command_help(self):
01878         self.assertEqual(self.command_help_parser.format_usage(),
01879                          'usage: PROG [-h] [--foo] bar {1,2} ...\n')
01880         self.assertEqual(self.command_help_parser.format_help(),
01881                          textwrap.dedent('''\
01882             usage: PROG [-h] [--foo] bar {1,2} ...
01883 
01884             main description
01885 
01886             positional arguments:
01887               bar         bar help
01888               {1,2}       command help
01889                 1         1 help
01890                 2         2 help
01891 
01892             optional arguments:
01893               -h, --help  show this help message and exit
01894               --foo       foo help
01895             '''))
01896 
01897     def test_subparser_title_help(self):
01898         parser = ErrorRaisingArgumentParser(prog='PROG',
01899                                             description='main description')
01900         parser.add_argument('--foo', action='store_true', help='foo help')
01901         parser.add_argument('bar', help='bar help')
01902         subparsers = parser.add_subparsers(title='subcommands',
01903                                            description='command help',
01904                                            help='additional text')
01905         parser1 = subparsers.add_parser('1')
01906         parser2 = subparsers.add_parser('2')
01907         self.assertEqual(parser.format_usage(),
01908                          'usage: PROG [-h] [--foo] bar {1,2} ...\n')
01909         self.assertEqual(parser.format_help(), textwrap.dedent('''\
01910             usage: PROG [-h] [--foo] bar {1,2} ...
01911 
01912             main description
01913 
01914             positional arguments:
01915               bar         bar help
01916 
01917             optional arguments:
01918               -h, --help  show this help message and exit
01919               --foo       foo help
01920 
01921             subcommands:
01922               command help
01923 
01924               {1,2}       additional text
01925             '''))
01926 
01927     def _test_subparser_help(self, args_str, expected_help):
01928         try:
01929             self.parser.parse_args(args_str.split())
01930         except ArgumentParserError:
01931             err = sys.exc_info()[1]
01932             if err.stdout != expected_help:
01933                 print(repr(expected_help))
01934                 print(repr(err.stdout))
01935             self.assertEqual(err.stdout, expected_help)
01936 
01937     def test_subparser1_help(self):
01938         self._test_subparser_help('5.0 1 -h', textwrap.dedent('''\
01939             usage: PROG bar 1 [-h] [-w W] {a,b,c}
01940 
01941             1 description
01942 
01943             positional arguments:
01944               {a,b,c}     x help
01945 
01946             optional arguments:
01947               -h, --help  show this help message and exit
01948               -w W        w help
01949             '''))
01950 
01951     def test_subparser2_help(self):
01952         self._test_subparser_help('5.0 2 -h', textwrap.dedent('''\
01953             usage: PROG bar 2 [-h] [-y {1,2,3}] [z [z ...]]
01954 
01955             2 description
01956 
01957             positional arguments:
01958               z           z help
01959 
01960             optional arguments:
01961               -h, --help  show this help message and exit
01962               -y {1,2,3}  y help
01963             '''))
01964 
01965     def test_alias_invocation(self):
01966         parser = self._get_parser(aliases=True)
01967         self.assertEqual(
01968             parser.parse_known_args('0.5 1alias1 b'.split()),
01969             (NS(foo=False, bar=0.5, w=None, x='b'), []),
01970         )
01971         self.assertEqual(
01972             parser.parse_known_args('0.5 1alias2 b'.split()),
01973             (NS(foo=False, bar=0.5, w=None, x='b'), []),
01974         )
01975 
01976     def test_error_alias_invocation(self):
01977         parser = self._get_parser(aliases=True)
01978         self.assertArgumentParserError(parser.parse_args,
01979                                        '0.5 1alias3 b'.split())
01980 
01981     def test_alias_help(self):
01982         parser = self._get_parser(aliases=True, subparser_help=True)
01983         self.maxDiff = None
01984         self.assertEqual(parser.format_help(), textwrap.dedent("""\
01985             usage: PROG [-h] [--foo] bar COMMAND ...
01986 
01987             main description
01988 
01989             positional arguments:
01990               bar                   bar help
01991 
01992             optional arguments:
01993               -h, --help            show this help message and exit
01994               --foo                 foo help
01995 
01996             commands:
01997               COMMAND
01998                 1 (1alias1, 1alias2)
01999                                     1 help
02000                 2                   2 help
02001             """))
02002 
02003 # ============
02004 # Groups tests
02005 # ============
02006 
02007 class TestPositionalsGroups(TestCase):
02008     """Tests that order of group positionals matches construction order"""
02009 
02010     def test_nongroup_first(self):
02011         parser = ErrorRaisingArgumentParser()
02012         parser.add_argument('foo')
02013         group = parser.add_argument_group('g')
02014         group.add_argument('bar')
02015         parser.add_argument('baz')
02016         expected = NS(foo='1', bar='2', baz='3')
02017         result = parser.parse_args('1 2 3'.split())
02018         self.assertEqual(expected, result)
02019 
02020     def test_group_first(self):
02021         parser = ErrorRaisingArgumentParser()
02022         group = parser.add_argument_group('xxx')
02023         group.add_argument('foo')
02024         parser.add_argument('bar')
02025         parser.add_argument('baz')
02026         expected = NS(foo='1', bar='2', baz='3')
02027         result = parser.parse_args('1 2 3'.split())
02028         self.assertEqual(expected, result)
02029 
02030     def test_interleaved_groups(self):
02031         parser = ErrorRaisingArgumentParser()
02032         group = parser.add_argument_group('xxx')
02033         parser.add_argument('foo')
02034         group.add_argument('bar')
02035         parser.add_argument('baz')
02036         group = parser.add_argument_group('yyy')
02037         group.add_argument('frell')
02038         expected = NS(foo='1', bar='2', baz='3', frell='4')
02039         result = parser.parse_args('1 2 3 4'.split())
02040         self.assertEqual(expected, result)
02041 
02042 # ===================
02043 # Parent parser tests
02044 # ===================
02045 
02046 class TestParentParsers(TestCase):
02047     """Tests that parsers can be created with parent parsers"""
02048 
02049     def assertArgumentParserError(self, *args, **kwargs):
02050         self.assertRaises(ArgumentParserError, *args, **kwargs)
02051 
02052     def setUp(self):
02053         super().setUp()
02054         self.wxyz_parent = ErrorRaisingArgumentParser(add_help=False)
02055         self.wxyz_parent.add_argument('--w')
02056         x_group = self.wxyz_parent.add_argument_group('x')
02057         x_group.add_argument('-y')
02058         self.wxyz_parent.add_argument('z')
02059 
02060         self.abcd_parent = ErrorRaisingArgumentParser(add_help=False)
02061         self.abcd_parent.add_argument('a')
02062         self.abcd_parent.add_argument('-b')
02063         c_group = self.abcd_parent.add_argument_group('c')
02064         c_group.add_argument('--d')
02065 
02066         self.w_parent = ErrorRaisingArgumentParser(add_help=False)
02067         self.w_parent.add_argument('--w')
02068 
02069         self.z_parent = ErrorRaisingArgumentParser(add_help=False)
02070         self.z_parent.add_argument('z')
02071 
02072         # parents with mutually exclusive groups
02073         self.ab_mutex_parent = ErrorRaisingArgumentParser(add_help=False)
02074         group = self.ab_mutex_parent.add_mutually_exclusive_group()
02075         group.add_argument('-a', action='store_true')
02076         group.add_argument('-b', action='store_true')
02077 
02078         self.main_program = os.path.basename(sys.argv[0])
02079 
02080     def test_single_parent(self):
02081         parser = ErrorRaisingArgumentParser(parents=[self.wxyz_parent])
02082         self.assertEqual(parser.parse_args('-y 1 2 --w 3'.split()),
02083                          NS(w='3', y='1', z='2'))
02084 
02085     def test_single_parent_mutex(self):
02086         self._test_mutex_ab(self.ab_mutex_parent.parse_args)
02087         parser = ErrorRaisingArgumentParser(parents=[self.ab_mutex_parent])
02088         self._test_mutex_ab(parser.parse_args)
02089 
02090     def test_single_granparent_mutex(self):
02091         parents = [self.ab_mutex_parent]
02092         parser = ErrorRaisingArgumentParser(add_help=False, parents=parents)
02093         parser = ErrorRaisingArgumentParser(parents=[parser])
02094         self._test_mutex_ab(parser.parse_args)
02095 
02096     def _test_mutex_ab(self, parse_args):
02097         self.assertEqual(parse_args([]), NS(a=False, b=False))
02098         self.assertEqual(parse_args(['-a']), NS(a=True, b=False))
02099         self.assertEqual(parse_args(['-b']), NS(a=False, b=True))
02100         self.assertArgumentParserError(parse_args, ['-a', '-b'])
02101         self.assertArgumentParserError(parse_args, ['-b', '-a'])
02102         self.assertArgumentParserError(parse_args, ['-c'])
02103         self.assertArgumentParserError(parse_args, ['-a', '-c'])
02104         self.assertArgumentParserError(parse_args, ['-b', '-c'])
02105 
02106     def test_multiple_parents(self):
02107         parents = [self.abcd_parent, self.wxyz_parent]
02108         parser = ErrorRaisingArgumentParser(parents=parents)
02109         self.assertEqual(parser.parse_args('--d 1 --w 2 3 4'.split()),
02110                          NS(a='3', b=None, d='1', w='2', y=None, z='4'))
02111 
02112     def test_multiple_parents_mutex(self):
02113         parents = [self.ab_mutex_parent, self.wxyz_parent]
02114         parser = ErrorRaisingArgumentParser(parents=parents)
02115         self.assertEqual(parser.parse_args('-a --w 2 3'.split()),
02116                          NS(a=True, b=False, w='2', y=None, z='3'))
02117         self.assertArgumentParserError(
02118             parser.parse_args, '-a --w 2 3 -b'.split())
02119         self.assertArgumentParserError(
02120             parser.parse_args, '-a -b --w 2 3'.split())
02121 
02122     def test_conflicting_parents(self):
02123         self.assertRaises(
02124             argparse.ArgumentError,
02125             argparse.ArgumentParser,
02126             parents=[self.w_parent, self.wxyz_parent])
02127 
02128     def test_conflicting_parents_mutex(self):
02129         self.assertRaises(
02130             argparse.ArgumentError,
02131             argparse.ArgumentParser,
02132             parents=[self.abcd_parent, self.ab_mutex_parent])
02133 
02134     def test_same_argument_name_parents(self):
02135         parents = [self.wxyz_parent, self.z_parent]
02136         parser = ErrorRaisingArgumentParser(parents=parents)
02137         self.assertEqual(parser.parse_args('1 2'.split()),
02138                          NS(w=None, y=None, z='2'))
02139 
02140     def test_subparser_parents(self):
02141         parser = ErrorRaisingArgumentParser()
02142         subparsers = parser.add_subparsers()
02143         abcde_parser = subparsers.add_parser('bar', parents=[self.abcd_parent])
02144         abcde_parser.add_argument('e')
02145         self.assertEqual(parser.parse_args('bar -b 1 --d 2 3 4'.split()),
02146                          NS(a='3', b='1', d='2', e='4'))
02147 
02148     def test_subparser_parents_mutex(self):
02149         parser = ErrorRaisingArgumentParser()
02150         subparsers = parser.add_subparsers()
02151         parents = [self.ab_mutex_parent]
02152         abc_parser = subparsers.add_parser('foo', parents=parents)
02153         c_group = abc_parser.add_argument_group('c_group')
02154         c_group.add_argument('c')
02155         parents = [self.wxyz_parent, self.ab_mutex_parent]
02156         wxyzabe_parser = subparsers.add_parser('bar', parents=parents)
02157         wxyzabe_parser.add_argument('e')
02158         self.assertEqual(parser.parse_args('foo -a 4'.split()),
02159                          NS(a=True, b=False, c='4'))
02160         self.assertEqual(parser.parse_args('bar -b  --w 2 3 4'.split()),
02161                          NS(a=False, b=True, w='2', y=None, z='3', e='4'))
02162         self.assertArgumentParserError(
02163             parser.parse_args, 'foo -a -b 4'.split())
02164         self.assertArgumentParserError(
02165             parser.parse_args, 'bar -b -a 4'.split())
02166 
02167     def test_parent_help(self):
02168         parents = [self.abcd_parent, self.wxyz_parent]
02169         parser = ErrorRaisingArgumentParser(parents=parents)
02170         parser_help = parser.format_help()
02171         self.assertEqual(parser_help, textwrap.dedent('''\
02172             usage: {} [-h] [-b B] [--d D] [--w W] [-y Y] a z
02173 
02174             positional arguments:
02175               a
02176               z
02177 
02178             optional arguments:
02179               -h, --help  show this help message and exit
02180               -b B
02181               --w W
02182 
02183             c:
02184               --d D
02185 
02186             x:
02187               -y Y
02188         '''.format(self.main_program)))
02189 
02190     def test_groups_parents(self):
02191         parent = ErrorRaisingArgumentParser(add_help=False)
02192         g = parent.add_argument_group(title='g', description='gd')
02193         g.add_argument('-w')
02194         g.add_argument('-x')
02195         m = parent.add_mutually_exclusive_group()
02196         m.add_argument('-y')
02197         m.add_argument('-z')
02198         parser = ErrorRaisingArgumentParser(parents=[parent])
02199 
02200         self.assertRaises(ArgumentParserError, parser.parse_args,
02201             ['-y', 'Y', '-z', 'Z'])
02202 
02203         parser_help = parser.format_help()
02204         self.assertEqual(parser_help, textwrap.dedent('''\
02205             usage: {} [-h] [-w W] [-x X] [-y Y | -z Z]
02206 
02207             optional arguments:
02208               -h, --help  show this help message and exit
02209               -y Y
02210               -z Z
02211 
02212             g:
02213               gd
02214 
02215               -w W
02216               -x X
02217         '''.format(self.main_program)))
02218 
02219 # ==============================
02220 # Mutually exclusive group tests
02221 # ==============================
02222 
02223 class TestMutuallyExclusiveGroupErrors(TestCase):
02224 
02225     def test_invalid_add_argument_group(self):
02226         parser = ErrorRaisingArgumentParser()
02227         raises = self.assertRaises
02228         raises(TypeError, parser.add_mutually_exclusive_group, title='foo')
02229 
02230     def test_invalid_add_argument(self):
02231         parser = ErrorRaisingArgumentParser()
02232         group = parser.add_mutually_exclusive_group()
02233         add_argument = group.add_argument
02234         raises = self.assertRaises
02235         raises(ValueError, add_argument, '--foo', required=True)
02236         raises(ValueError, add_argument, 'bar')
02237         raises(ValueError, add_argument, 'bar', nargs='+')
02238         raises(ValueError, add_argument, 'bar', nargs=1)
02239         raises(ValueError, add_argument, 'bar', nargs=argparse.PARSER)
02240 
02241     def test_help(self):
02242         parser = ErrorRaisingArgumentParser(prog='PROG')
02243         group1 = parser.add_mutually_exclusive_group()
02244         group1.add_argument('--foo', action='store_true')
02245         group1.add_argument('--bar', action='store_false')
02246         group2 = parser.add_mutually_exclusive_group()
02247         group2.add_argument('--soup', action='store_true')
02248         group2.add_argument('--nuts', action='store_false')
02249         expected = '''\
02250             usage: PROG [-h] [--foo | --bar] [--soup | --nuts]
02251 
02252             optional arguments:
02253               -h, --help  show this help message and exit
02254               --foo
02255               --bar
02256               --soup
02257               --nuts
02258               '''
02259         self.assertEqual(parser.format_help(), textwrap.dedent(expected))
02260 
02261 class MEMixin(object):
02262 
02263     def test_failures_when_not_required(self):
02264         parse_args = self.get_parser(required=False).parse_args
02265         error = ArgumentParserError
02266         for args_string in self.failures:
02267             self.assertRaises(error, parse_args, args_string.split())
02268 
02269     def test_failures_when_required(self):
02270         parse_args = self.get_parser(required=True).parse_args
02271         error = ArgumentParserError
02272         for args_string in self.failures + ['']:
02273             self.assertRaises(error, parse_args, args_string.split())
02274 
02275     def test_successes_when_not_required(self):
02276         parse_args = self.get_parser(required=False).parse_args
02277         successes = self.successes + self.successes_when_not_required
02278         for args_string, expected_ns in successes:
02279             actual_ns = parse_args(args_string.split())
02280             self.assertEqual(actual_ns, expected_ns)
02281 
02282     def test_successes_when_required(self):
02283         parse_args = self.get_parser(required=True).parse_args
02284         for args_string, expected_ns in self.successes:
02285             actual_ns = parse_args(args_string.split())
02286             self.assertEqual(actual_ns, expected_ns)
02287 
02288     def test_usage_when_not_required(self):
02289         format_usage = self.get_parser(required=False).format_usage
02290         expected_usage = self.usage_when_not_required
02291         self.assertEqual(format_usage(), textwrap.dedent(expected_usage))
02292 
02293     def test_usage_when_required(self):
02294         format_usage = self.get_parser(required=True).format_usage
02295         expected_usage = self.usage_when_required
02296         self.assertEqual(format_usage(), textwrap.dedent(expected_usage))
02297 
02298     def test_help_when_not_required(self):
02299         format_help = self.get_parser(required=False).format_help
02300         help = self.usage_when_not_required + self.help
02301         self.assertEqual(format_help(), textwrap.dedent(help))
02302 
02303     def test_help_when_required(self):
02304         format_help = self.get_parser(required=True).format_help
02305         help = self.usage_when_required + self.help
02306         self.assertEqual(format_help(), textwrap.dedent(help))
02307 
02308 
02309 class TestMutuallyExclusiveSimple(MEMixin, TestCase):
02310 
02311     def get_parser(self, required=None):
02312         parser = ErrorRaisingArgumentParser(prog='PROG')
02313         group = parser.add_mutually_exclusive_group(required=required)
02314         group.add_argument('--bar', help='bar help')
02315         group.add_argument('--baz', nargs='?', const='Z', help='baz help')
02316         return parser
02317 
02318     failures = ['--bar X --baz Y', '--bar X --baz']
02319     successes = [
02320         ('--bar X', NS(bar='X', baz=None)),
02321         ('--bar X --bar Z', NS(bar='Z', baz=None)),
02322         ('--baz Y', NS(bar=None, baz='Y')),
02323         ('--baz', NS(bar=None, baz='Z')),
02324     ]
02325     successes_when_not_required = [
02326         ('', NS(bar=None, baz=None)),
02327     ]
02328 
02329     usage_when_not_required = '''\
02330         usage: PROG [-h] [--bar BAR | --baz [BAZ]]
02331         '''
02332     usage_when_required = '''\
02333         usage: PROG [-h] (--bar BAR | --baz [BAZ])
02334         '''
02335     help = '''\
02336 
02337         optional arguments:
02338           -h, --help   show this help message and exit
02339           --bar BAR    bar help
02340           --baz [BAZ]  baz help
02341         '''
02342 
02343 
02344 class TestMutuallyExclusiveLong(MEMixin, TestCase):
02345 
02346     def get_parser(self, required=None):
02347         parser = ErrorRaisingArgumentParser(prog='PROG')
02348         parser.add_argument('--abcde', help='abcde help')
02349         parser.add_argument('--fghij', help='fghij help')
02350         group = parser.add_mutually_exclusive_group(required=required)
02351         group.add_argument('--klmno', help='klmno help')
02352         group.add_argument('--pqrst', help='pqrst help')
02353         return parser
02354 
02355     failures = ['--klmno X --pqrst Y']
02356     successes = [
02357         ('--klmno X', NS(abcde=None, fghij=None, klmno='X', pqrst=None)),
02358         ('--abcde Y --klmno X',
02359             NS(abcde='Y', fghij=None, klmno='X', pqrst=None)),
02360         ('--pqrst X', NS(abcde=None, fghij=None, klmno=None, pqrst='X')),
02361         ('--pqrst X --fghij Y',
02362             NS(abcde=None, fghij='Y', klmno=None, pqrst='X')),
02363     ]
02364     successes_when_not_required = [
02365         ('', NS(abcde=None, fghij=None, klmno=None, pqrst=None)),
02366     ]
02367 
02368     usage_when_not_required = '''\
02369     usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
02370                 [--klmno KLMNO | --pqrst PQRST]
02371     '''
02372     usage_when_required = '''\
02373     usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
02374                 (--klmno KLMNO | --pqrst PQRST)
02375     '''
02376     help = '''\
02377 
02378     optional arguments:
02379       -h, --help     show this help message and exit
02380       --abcde ABCDE  abcde help
02381       --fghij FGHIJ  fghij help
02382       --klmno KLMNO  klmno help
02383       --pqrst PQRST  pqrst help
02384     '''
02385 
02386 
02387 class TestMutuallyExclusiveFirstSuppressed(MEMixin, TestCase):
02388 
02389     def get_parser(self, required):
02390         parser = ErrorRaisingArgumentParser(prog='PROG')
02391         group = parser.add_mutually_exclusive_group(required=required)
02392         group.add_argument('-x', help=argparse.SUPPRESS)
02393         group.add_argument('-y', action='store_false', help='y help')
02394         return parser
02395 
02396     failures = ['-x X -y']
02397     successes = [
02398         ('-x X', NS(x='X', y=True)),
02399         ('-x X -x Y', NS(x='Y', y=True)),
02400         ('-y', NS(x=None, y=False)),
02401     ]
02402     successes_when_not_required = [
02403         ('', NS(x=None, y=True)),
02404     ]
02405 
02406     usage_when_not_required = '''\
02407         usage: PROG [-h] [-y]
02408         '''
02409     usage_when_required = '''\
02410         usage: PROG [-h] -y
02411         '''
02412     help = '''\
02413 
02414         optional arguments:
02415           -h, --help  show this help message and exit
02416           -y          y help
02417         '''
02418 
02419 
02420 class TestMutuallyExclusiveManySuppressed(MEMixin, TestCase):
02421 
02422     def get_parser(self, required):
02423         parser = ErrorRaisingArgumentParser(prog='PROG')
02424         group = parser.add_mutually_exclusive_group(required=required)
02425         add = group.add_argument
02426         add('--spam', action='store_true', help=argparse.SUPPRESS)
02427         add('--badger', action='store_false', help=argparse.SUPPRESS)
02428         add('--bladder', help=argparse.SUPPRESS)
02429         return parser
02430 
02431     failures = [
02432         '--spam --badger',
02433         '--badger --bladder B',
02434         '--bladder B --spam',
02435     ]
02436     successes = [
02437         ('--spam', NS(spam=True, badger=True, bladder=None)),
02438         ('--badger', NS(spam=False, badger=False, bladder=None)),
02439         ('--bladder B', NS(spam=False, badger=True, bladder='B')),
02440         ('--spam --spam', NS(spam=True, badger=True, bladder=None)),
02441     ]
02442     successes_when_not_required = [
02443         ('', NS(spam=False, badger=True, bladder=None)),
02444     ]
02445 
02446     usage_when_required = usage_when_not_required = '''\
02447         usage: PROG [-h]
02448         '''
02449     help = '''\
02450 
02451         optional arguments:
02452           -h, --help  show this help message and exit
02453         '''
02454 
02455 
02456 class TestMutuallyExclusiveOptionalAndPositional(MEMixin, TestCase):
02457 
02458     def get_parser(self, required):
02459         parser = ErrorRaisingArgumentParser(prog='PROG')
02460         group = parser.add_mutually_exclusive_group(required=required)
02461         group.add_argument('--foo', action='store_true', help='FOO')
02462         group.add_argument('--spam', help='SPAM')
02463         group.add_argument('badger', nargs='*', default='X', help='BADGER')
02464         return parser
02465 
02466     failures = [
02467         '--foo --spam S',
02468         '--spam S X',
02469         'X --foo',
02470         'X Y Z --spam S',
02471         '--foo X Y',
02472     ]
02473     successes = [
02474         ('--foo', NS(foo=True, spam=None, badger='X')),
02475         ('--spam S', NS(foo=False, spam='S', badger='X')),
02476         ('X', NS(foo=False, spam=None, badger=['X'])),
02477         ('X Y Z', NS(foo=False, spam=None, badger=['X', 'Y', 'Z'])),
02478     ]
02479     successes_when_not_required = [
02480         ('', NS(foo=False, spam=None, badger='X')),
02481     ]
02482 
02483     usage_when_not_required = '''\
02484         usage: PROG [-h] [--foo | --spam SPAM | badger [badger ...]]
02485         '''
02486     usage_when_required = '''\
02487         usage: PROG [-h] (--foo | --spam SPAM | badger [badger ...])
02488         '''
02489     help = '''\
02490 
02491         positional arguments:
02492           badger       BADGER
02493 
02494         optional arguments:
02495           -h, --help   show this help message and exit
02496           --foo        FOO
02497           --spam SPAM  SPAM
02498         '''
02499 
02500 
02501 class TestMutuallyExclusiveOptionalsMixed(MEMixin, TestCase):
02502 
02503     def get_parser(self, required):
02504         parser = ErrorRaisingArgumentParser(prog='PROG')
02505         parser.add_argument('-x', action='store_true', help='x help')
02506         group = parser.add_mutually_exclusive_group(required=required)
02507         group.add_argument('-a', action='store_true', help='a help')
02508         group.add_argument('-b', action='store_true', help='b help')
02509         parser.add_argument('-y', action='store_true', help='y help')
02510         group.add_argument('-c', action='store_true', help='c help')
02511         return parser
02512 
02513     failures = ['-a -b', '-b -c', '-a -c', '-a -b -c']
02514     successes = [
02515         ('-a', NS(a=True, b=False, c=False, x=False, y=False)),
02516         ('-b', NS(a=False, b=True, c=False, x=False, y=False)),
02517         ('-c', NS(a=False, b=False, c=True, x=False, y=False)),
02518         ('-a -x', NS(a=True, b=False, c=False, x=True, y=False)),
02519         ('-y -b', NS(a=False, b=True, c=False, x=False, y=True)),
02520         ('-x -y -c', NS(a=False, b=False, c=True, x=True, y=True)),
02521     ]
02522     successes_when_not_required = [
02523         ('', NS(a=False, b=False, c=False, x=False, y=False)),
02524         ('-x', NS(a=False, b=False, c=False, x=True, y=False)),
02525         ('-y', NS(a=False, b=False, c=False, x=False, y=True)),
02526     ]
02527 
02528     usage_when_required = usage_when_not_required = '''\
02529         usage: PROG [-h] [-x] [-a] [-b] [-y] [-c]
02530         '''
02531     help = '''\
02532 
02533         optional arguments:
02534           -h, --help  show this help message and exit
02535           -x          x help
02536           -a          a help
02537           -b          b help
02538           -y          y help
02539           -c          c help
02540         '''
02541 
02542 
02543 class TestMutuallyExclusiveInGroup(MEMixin, TestCase):
02544 
02545     def get_parser(self, required=None):
02546         parser = ErrorRaisingArgumentParser(prog='PROG')
02547         titled_group = parser.add_argument_group(
02548             title='Titled group', description='Group description')
02549         mutex_group = \
02550             titled_group.add_mutually_exclusive_group(required=required)
02551         mutex_group.add_argument('--bar', help='bar help')
02552         mutex_group.add_argument('--baz', help='baz help')
02553         return parser
02554 
02555     failures = ['--bar X --baz Y', '--baz X --bar Y']
02556     successes = [
02557         ('--bar X', NS(bar='X', baz=None)),
02558         ('--baz Y', NS(bar=None, baz='Y')),
02559     ]
02560     successes_when_not_required = [
02561         ('', NS(bar=None, baz=None)),
02562     ]
02563 
02564     usage_when_not_required = '''\
02565         usage: PROG [-h] [--bar BAR | --baz BAZ]
02566         '''
02567     usage_when_required = '''\
02568         usage: PROG [-h] (--bar BAR | --baz BAZ)
02569         '''
02570     help = '''\
02571 
02572         optional arguments:
02573           -h, --help  show this help message and exit
02574 
02575         Titled group:
02576           Group description
02577 
02578           --bar BAR   bar help
02579           --baz BAZ   baz help
02580         '''
02581 
02582 
02583 class TestMutuallyExclusiveOptionalsAndPositionalsMixed(MEMixin, TestCase):
02584 
02585     def get_parser(self, required):
02586         parser = ErrorRaisingArgumentParser(prog='PROG')
02587         parser.add_argument('x', help='x help')
02588         parser.add_argument('-y', action='store_true', help='y help')
02589         group = parser.add_mutually_exclusive_group(required=required)
02590         group.add_argument('a', nargs='?', help='a help')
02591         group.add_argument('-b', action='store_true', help='b help')
02592         group.add_argument('-c', action='store_true', help='c help')
02593         return parser
02594 
02595     failures = ['X A -b', '-b -c', '-c X A']
02596     successes = [
02597         ('X A', NS(a='A', b=False, c=False, x='X', y=False)),
02598         ('X -b', NS(a=None, b=True, c=False, x='X', y=False)),
02599         ('X -c', NS(a=None, b=False, c=True, x='X', y=False)),
02600         ('X A -y', NS(a='A', b=False, c=False, x='X', y=True)),
02601         ('X -y -b', NS(a=None, b=True, c=False, x='X', y=True)),
02602     ]
02603     successes_when_not_required = [
02604         ('X', NS(a=None, b=False, c=False, x='X', y=False)),
02605         ('X -y', NS(a=None, b=False, c=False, x='X', y=True)),
02606     ]
02607 
02608     usage_when_required = usage_when_not_required = '''\
02609         usage: PROG [-h] [-y] [-b] [-c] x [a]
02610         '''
02611     help = '''\
02612 
02613         positional arguments:
02614           x           x help
02615           a           a help
02616 
02617         optional arguments:
02618           -h, --help  show this help message and exit
02619           -y          y help
02620           -b          b help
02621           -c          c help
02622         '''
02623 
02624 # =================================================
02625 # Mutually exclusive group in parent parser tests
02626 # =================================================
02627 
02628 class MEPBase(object):
02629 
02630     def get_parser(self, required=None):
02631         parent = super(MEPBase, self).get_parser(required=required)
02632         parser = ErrorRaisingArgumentParser(
02633             prog=parent.prog, add_help=False, parents=[parent])
02634         return parser
02635 
02636 
02637 class TestMutuallyExclusiveGroupErrorsParent(
02638     MEPBase, TestMutuallyExclusiveGroupErrors):
02639     pass
02640 
02641 
02642 class TestMutuallyExclusiveSimpleParent(
02643     MEPBase, TestMutuallyExclusiveSimple):
02644     pass
02645 
02646 
02647 class TestMutuallyExclusiveLongParent(
02648     MEPBase, TestMutuallyExclusiveLong):
02649     pass
02650 
02651 
02652 class TestMutuallyExclusiveFirstSuppressedParent(
02653     MEPBase, TestMutuallyExclusiveFirstSuppressed):
02654     pass
02655 
02656 
02657 class TestMutuallyExclusiveManySuppressedParent(
02658     MEPBase, TestMutuallyExclusiveManySuppressed):
02659     pass
02660 
02661 
02662 class TestMutuallyExclusiveOptionalAndPositionalParent(
02663     MEPBase, TestMutuallyExclusiveOptionalAndPositional):
02664     pass
02665 
02666 
02667 class TestMutuallyExclusiveOptionalsMixedParent(
02668     MEPBase, TestMutuallyExclusiveOptionalsMixed):
02669     pass
02670 
02671 
02672 class TestMutuallyExclusiveOptionalsAndPositionalsMixedParent(
02673     MEPBase, TestMutuallyExclusiveOptionalsAndPositionalsMixed):
02674     pass
02675 
02676 # =================
02677 # Set default tests
02678 # =================
02679 
02680 class TestSetDefaults(TestCase):
02681 
02682     def test_set_defaults_no_args(self):
02683         parser = ErrorRaisingArgumentParser()
02684         parser.set_defaults(x='foo')
02685         parser.set_defaults(y='bar', z=1)
02686         self.assertEqual(NS(x='foo', y='bar', z=1),
02687                          parser.parse_args([]))
02688         self.assertEqual(NS(x='foo', y='bar', z=1),
02689                          parser.parse_args([], NS()))
02690         self.assertEqual(NS(x='baz', y='bar', z=1),
02691                          parser.parse_args([], NS(x='baz')))
02692         self.assertEqual(NS(x='baz', y='bar', z=2),
02693                          parser.parse_args([], NS(x='baz', z=2)))
02694 
02695     def test_set_defaults_with_args(self):
02696         parser = ErrorRaisingArgumentParser()
02697         parser.set_defaults(x='foo', y='bar')
02698         parser.add_argument('-x', default='xfoox')
02699         self.assertEqual(NS(x='xfoox', y='bar'),
02700                          parser.parse_args([]))
02701         self.assertEqual(NS(x='xfoox', y='bar'),
02702                          parser.parse_args([], NS()))
02703         self.assertEqual(NS(x='baz', y='bar'),
02704                          parser.parse_args([], NS(x='baz')))
02705         self.assertEqual(NS(x='1', y='bar'),
02706                          parser.parse_args('-x 1'.split()))
02707         self.assertEqual(NS(x='1', y='bar'),
02708                          parser.parse_args('-x 1'.split(), NS()))
02709         self.assertEqual(NS(x='1', y='bar'),
02710                          parser.parse_args('-x 1'.split(), NS(x='baz')))
02711 
02712     def test_set_defaults_subparsers(self):
02713         parser = ErrorRaisingArgumentParser()
02714         parser.set_defaults(x='foo')
02715         subparsers = parser.add_subparsers()
02716         parser_a = subparsers.add_parser('a')
02717         parser_a.set_defaults(y='bar')
02718         self.assertEqual(NS(x='foo', y='bar'),
02719                          parser.parse_args('a'.split()))
02720 
02721     def test_set_defaults_parents(self):
02722         parent = ErrorRaisingArgumentParser(add_help=False)
02723         parent.set_defaults(x='foo')
02724         parser = ErrorRaisingArgumentParser(parents=[parent])
02725         self.assertEqual(NS(x='foo'), parser.parse_args([]))
02726 
02727     def test_set_defaults_same_as_add_argument(self):
02728         parser = ErrorRaisingArgumentParser()
02729         parser.set_defaults(w='W', x='X', y='Y', z='Z')
02730         parser.add_argument('-w')
02731         parser.add_argument('-x', default='XX')
02732         parser.add_argument('y', nargs='?')
02733         parser.add_argument('z', nargs='?', default='ZZ')
02734 
02735         # defaults set previously
02736         self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'),
02737                          parser.parse_args([]))
02738 
02739         # reset defaults
02740         parser.set_defaults(w='WW', x='X', y='YY', z='Z')
02741         self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'),
02742                          parser.parse_args([]))
02743 
02744     def test_set_defaults_same_as_add_argument_group(self):
02745         parser = ErrorRaisingArgumentParser()
02746         parser.set_defaults(w='W', x='X', y='Y', z='Z')
02747         group = parser.add_argument_group('foo')
02748         group.add_argument('-w')
02749         group.add_argument('-x', default='XX')
02750         group.add_argument('y', nargs='?')
02751         group.add_argument('z', nargs='?', default='ZZ')
02752 
02753 
02754         # defaults set previously
02755         self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'),
02756                          parser.parse_args([]))
02757 
02758         # reset defaults
02759         parser.set_defaults(w='WW', x='X', y='YY', z='Z')
02760         self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'),
02761                          parser.parse_args([]))
02762 
02763 # =================
02764 # Get default tests
02765 # =================
02766 
02767 class TestGetDefault(TestCase):
02768 
02769     def test_get_default(self):
02770         parser = ErrorRaisingArgumentParser()
02771         self.assertEqual(None, parser.get_default("foo"))
02772         self.assertEqual(None, parser.get_default("bar"))
02773 
02774         parser.add_argument("--foo")
02775         self.assertEqual(None, parser.get_default("foo"))
02776         self.assertEqual(None, parser.get_default("bar"))
02777 
02778         parser.add_argument("--bar", type=int, default=42)
02779         self.assertEqual(None, parser.get_default("foo"))
02780         self.assertEqual(42, parser.get_default("bar"))
02781 
02782         parser.set_defaults(foo="badger")
02783         self.assertEqual("badger", parser.get_default("foo"))
02784         self.assertEqual(42, parser.get_default("bar"))
02785 
02786 # ==========================
02787 # Namespace 'contains' tests
02788 # ==========================
02789 
02790 class TestNamespaceContainsSimple(TestCase):
02791 
02792     def test_empty(self):
02793         ns = argparse.Namespace()
02794         self.assertEqual('' in ns, False)
02795         self.assertEqual('' not in ns, True)
02796         self.assertEqual('x' in ns, False)
02797 
02798     def test_non_empty(self):
02799         ns = argparse.Namespace(x=1, y=2)
02800         self.assertEqual('x' in ns, True)
02801         self.assertEqual('x' not in ns, False)
02802         self.assertEqual('y' in ns, True)
02803         self.assertEqual('' in ns, False)
02804         self.assertEqual('xx' in ns, False)
02805         self.assertEqual('z' in ns, False)
02806 
02807 # =====================
02808 # Help formatting tests
02809 # =====================
02810 
02811 class TestHelpFormattingMetaclass(type):
02812 
02813     def __init__(cls, name, bases, bodydict):
02814         if name == 'HelpTestCase':
02815             return
02816 
02817         class AddTests(object):
02818 
02819             def __init__(self, test_class, func_suffix, std_name):
02820                 self.func_suffix = func_suffix
02821                 self.std_name = std_name
02822 
02823                 for test_func in [self.test_format,
02824                                   self.test_print,
02825                                   self.test_print_file]:
02826                     test_name = '%s_%s' % (test_func.__name__, func_suffix)
02827 
02828                     def test_wrapper(self, test_func=test_func):
02829                         test_func(self)
02830                     try:
02831                         test_wrapper.__name__ = test_name
02832                     except TypeError:
02833                         pass
02834                     setattr(test_class, test_name, test_wrapper)
02835 
02836             def _get_parser(self, tester):
02837                 parser = argparse.ArgumentParser(
02838                     *tester.parser_signature.args,
02839                     **tester.parser_signature.kwargs)
02840                 for argument_sig in getattr(tester, 'argument_signatures', []):
02841                     parser.add_argument(*argument_sig.args,
02842                                         **argument_sig.kwargs)
02843                 group_sigs = getattr(tester, 'argument_group_signatures', [])
02844                 for group_sig, argument_sigs in group_sigs:
02845                     group = parser.add_argument_group(*group_sig.args,
02846                                                       **group_sig.kwargs)
02847                     for argument_sig in argument_sigs:
02848                         group.add_argument(*argument_sig.args,
02849                                            **argument_sig.kwargs)
02850                 subparsers_sigs = getattr(tester, 'subparsers_signatures', [])
02851                 if subparsers_sigs:
02852                     subparsers = parser.add_subparsers()
02853                     for subparser_sig in subparsers_sigs:
02854                         subparsers.add_parser(*subparser_sig.args,
02855                                                **subparser_sig.kwargs)
02856                 return parser
02857 
02858             def _test(self, tester, parser_text):
02859                 expected_text = getattr(tester, self.func_suffix)
02860                 expected_text = textwrap.dedent(expected_text)
02861                 if expected_text != parser_text:
02862                     print(repr(expected_text))
02863                     print(repr(parser_text))
02864                     for char1, char2 in zip(expected_text, parser_text):
02865                         if char1 != char2:
02866                             print('first diff: %r %r' % (char1, char2))
02867                             break
02868                 tester.assertEqual(expected_text, parser_text)
02869 
02870             def test_format(self, tester):
02871                 parser = self._get_parser(tester)
02872                 format = getattr(parser, 'format_%s' % self.func_suffix)
02873                 self._test(tester, format())
02874 
02875             def test_print(self, tester):
02876                 parser = self._get_parser(tester)
02877                 print_ = getattr(parser, 'print_%s' % self.func_suffix)
02878                 old_stream = getattr(sys, self.std_name)
02879                 setattr(sys, self.std_name, StdIOBuffer())
02880                 try:
02881                     print_()
02882                     parser_text = getattr(sys, self.std_name).getvalue()
02883                 finally:
02884                     setattr(sys, self.std_name, old_stream)
02885                 self._test(tester, parser_text)
02886 
02887             def test_print_file(self, tester):
02888                 parser = self._get_parser(tester)
02889                 print_ = getattr(parser, 'print_%s' % self.func_suffix)
02890                 sfile = StdIOBuffer()
02891                 print_(sfile)
02892                 parser_text = sfile.getvalue()
02893                 self._test(tester, parser_text)
02894 
02895         # add tests for {format,print}_{usage,help,version}
02896         for func_suffix, std_name in [('usage', 'stdout'),
02897                                       ('help', 'stdout'),
02898                                       ('version', 'stderr')]:
02899             AddTests(cls, func_suffix, std_name)
02900 
02901 bases = TestCase,
02902 HelpTestCase = TestHelpFormattingMetaclass('HelpTestCase', bases, {})
02903 
02904 
02905 class TestHelpBiggerOptionals(HelpTestCase):
02906     """Make sure that argument help aligns when options are longer"""
02907 
02908     parser_signature = Sig(prog='PROG', description='DESCRIPTION',
02909                            epilog='EPILOG', version='0.1')
02910     argument_signatures = [
02911         Sig('-x', action='store_true', help='X HELP'),
02912         Sig('--y', help='Y HELP'),
02913         Sig('foo', help='FOO HELP'),
02914         Sig('bar', help='BAR HELP'),
02915     ]
02916     argument_group_signatures = []
02917     usage = '''\
02918         usage: PROG [-h] [-v] [-x] [--y Y] foo bar
02919         '''
02920     help = usage + '''\
02921 
02922         DESCRIPTION
02923 
02924         positional arguments:
02925           foo            FOO HELP
02926           bar            BAR HELP
02927 
02928         optional arguments:
02929           -h, --help     show this help message and exit
02930           -v, --version  show program's version number and exit
02931           -x             X HELP
02932           --y Y          Y HELP
02933 
02934         EPILOG
02935     '''
02936     version = '''\
02937         0.1
02938         '''
02939 
02940 
02941 class TestHelpBiggerOptionalGroups(HelpTestCase):
02942     """Make sure that argument help aligns when options are longer"""
02943 
02944     parser_signature = Sig(prog='PROG', description='DESCRIPTION',
02945                            epilog='EPILOG', version='0.1')
02946     argument_signatures = [
02947         Sig('-x', action='store_true', help='X HELP'),
02948         Sig('--y', help='Y HELP'),
02949         Sig('foo', help='FOO HELP'),
02950         Sig('bar', help='BAR HELP'),
02951     ]
02952     argument_group_signatures = [
02953         (Sig('GROUP TITLE', description='GROUP DESCRIPTION'), [
02954             Sig('baz', help='BAZ HELP'),
02955             Sig('-z', nargs='+', help='Z HELP')]),
02956     ]
02957     usage = '''\
02958         usage: PROG [-h] [-v] [-x] [--y Y] [-z Z [Z ...]] foo bar baz
02959         '''
02960     help = usage + '''\
02961 
02962         DESCRIPTION
02963 
02964         positional arguments:
02965           foo            FOO HELP
02966           bar            BAR HELP
02967 
02968         optional arguments:
02969           -h, --help     show this help message and exit
02970           -v, --version  show program's version number and exit
02971           -x             X HELP
02972           --y Y          Y HELP
02973 
02974         GROUP TITLE:
02975           GROUP DESCRIPTION
02976 
02977           baz            BAZ HELP
02978           -z Z [Z ...]   Z HELP
02979 
02980         EPILOG
02981     '''
02982     version = '''\
02983         0.1
02984         '''
02985 
02986 
02987 class TestHelpBiggerPositionals(HelpTestCase):
02988     """Make sure that help aligns when arguments are longer"""
02989 
02990     parser_signature = Sig(usage='USAGE', description='DESCRIPTION')
02991     argument_signatures = [
02992         Sig('-x', action='store_true', help='X HELP'),
02993         Sig('--y', help='Y HELP'),
02994         Sig('ekiekiekifekang', help='EKI HELP'),
02995         Sig('bar', help='BAR HELP'),
02996     ]
02997     argument_group_signatures = []
02998     usage = '''\
02999         usage: USAGE
03000         '''
03001     help = usage + '''\
03002 
03003         DESCRIPTION
03004 
03005         positional arguments:
03006           ekiekiekifekang  EKI HELP
03007           bar              BAR HELP
03008 
03009         optional arguments:
03010           -h, --help       show this help message and exit
03011           -x               X HELP
03012           --y Y            Y HELP
03013         '''
03014 
03015     version = ''
03016 
03017 
03018 class TestHelpReformatting(HelpTestCase):
03019     """Make sure that text after short names starts on the first line"""
03020 
03021     parser_signature = Sig(
03022         prog='PROG',
03023         description='   oddly    formatted\n'
03024                     'description\n'
03025                     '\n'
03026                     'that is so long that it should go onto multiple '
03027                     'lines when wrapped')
03028     argument_signatures = [
03029         Sig('-x', metavar='XX', help='oddly\n'
03030                                      '    formatted -x help'),
03031         Sig('y', metavar='yyy', help='normal y help'),
03032     ]
03033     argument_group_signatures = [
03034         (Sig('title', description='\n'
03035                                   '    oddly formatted group\n'
03036                                   '\n'
03037                                   'description'),
03038          [Sig('-a', action='store_true',
03039               help=' oddly \n'
03040                    'formatted    -a  help  \n'
03041                    '    again, so long that it should be wrapped over '
03042                    'multiple lines')]),
03043     ]
03044     usage = '''\
03045         usage: PROG [-h] [-x XX] [-a] yyy
03046         '''
03047     help = usage + '''\
03048 
03049         oddly formatted description that is so long that it should go onto \
03050 multiple
03051         lines when wrapped
03052 
03053         positional arguments:
03054           yyy         normal y help
03055 
03056         optional arguments:
03057           -h, --help  show this help message and exit
03058           -x XX       oddly formatted -x help
03059 
03060         title:
03061           oddly formatted group description
03062 
03063           -a          oddly formatted -a help again, so long that it should \
03064 be wrapped
03065                       over multiple lines
03066         '''
03067     version = ''
03068 
03069 
03070 class TestHelpWrappingShortNames(HelpTestCase):
03071     """Make sure that text after short names starts on the first line"""
03072 
03073     parser_signature = Sig(prog='PROG', description= 'D\nD' * 30)
03074     argument_signatures = [
03075         Sig('-x', metavar='XX', help='XHH HX' * 20),
03076         Sig('y', metavar='yyy', help='YH YH' * 20),
03077     ]
03078     argument_group_signatures = [
03079         (Sig('ALPHAS'), [
03080             Sig('-a', action='store_true', help='AHHH HHA' * 10)]),
03081     ]
03082     usage = '''\
03083         usage: PROG [-h] [-x XX] [-a] yyy
03084         '''
03085     help = usage + '''\
03086 
03087         D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
03088 DD DD DD
03089         DD DD DD DD D
03090 
03091         positional arguments:
03092           yyy         YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
03093 YHYH YHYH
03094                       YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
03095 
03096         optional arguments:
03097           -h, --help  show this help message and exit
03098           -x XX       XHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH \
03099 HXXHH HXXHH
03100                       HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HX
03101 
03102         ALPHAS:
03103           -a          AHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH \
03104 HHAAHHH
03105                       HHAAHHH HHAAHHH HHA
03106         '''
03107     version = ''
03108 
03109 
03110 class TestHelpWrappingLongNames(HelpTestCase):
03111     """Make sure that text after long names starts on the next line"""
03112 
03113     parser_signature = Sig(usage='USAGE', description= 'D D' * 30,
03114                            version='V V'*30)
03115     argument_signatures = [
03116         Sig('-x', metavar='X' * 25, help='XH XH' * 20),
03117         Sig('y', metavar='y' * 25, help='YH YH' * 20),
03118     ]
03119     argument_group_signatures = [
03120         (Sig('ALPHAS'), [
03121             Sig('-a', metavar='A' * 25, help='AH AH' * 20),
03122             Sig('z', metavar='z' * 25, help='ZH ZH' * 20)]),
03123     ]
03124     usage = '''\
03125         usage: USAGE
03126         '''
03127     help = usage + '''\
03128 
03129         D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
03130 DD DD DD
03131         DD DD DD DD D
03132 
03133         positional arguments:
03134           yyyyyyyyyyyyyyyyyyyyyyyyy
03135                                 YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
03136 YHYH YHYH
03137                                 YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
03138 
03139         optional arguments:
03140           -h, --help            show this help message and exit
03141           -v, --version         show program's version number and exit
03142           -x XXXXXXXXXXXXXXXXXXXXXXXXX
03143                                 XH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH \
03144 XHXH XHXH
03145                                 XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XH
03146 
03147         ALPHAS:
03148           -a AAAAAAAAAAAAAAAAAAAAAAAAA
03149                                 AH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH \
03150 AHAH AHAH
03151                                 AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AH
03152           zzzzzzzzzzzzzzzzzzzzzzzzz
03153                                 ZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH \
03154 ZHZH ZHZH
03155                                 ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZH
03156         '''
03157     version = '''\
03158         V VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV \
03159 VV VV VV
03160         VV VV VV VV V
03161         '''
03162 
03163 
03164 class TestHelpUsage(HelpTestCase):
03165     """Test basic usage messages"""
03166 
03167     parser_signature = Sig(prog='PROG')
03168     argument_signatures = [
03169         Sig('-w', nargs='+', help='w'),
03170         Sig('-x', nargs='*', help='x'),
03171         Sig('a', help='a'),
03172         Sig('b', help='b', nargs=2),
03173         Sig('c', help='c', nargs='?'),
03174     ]
03175     argument_group_signatures = [
03176         (Sig('group'), [
03177             Sig('-y', nargs='?', help='y'),
03178             Sig('-z', nargs=3, help='z'),
03179             Sig('d', help='d', nargs='*'),
03180             Sig('e', help='e', nargs='+'),
03181         ])
03182     ]
03183     usage = '''\
03184         usage: PROG [-h] [-w W [W ...]] [-x [X [X ...]]] [-y [Y]] [-z Z Z Z]
03185                     a b b [c] [d [d ...]] e [e ...]
03186         '''
03187     help = usage + '''\
03188 
03189         positional arguments:
03190           a               a
03191           b               b
03192           c               c
03193 
03194         optional arguments:
03195           -h, --help      show this help message and exit
03196           -w W [W ...]    w
03197           -x [X [X ...]]  x
03198 
03199         group:
03200           -y [Y]          y
03201           -z Z Z Z        z
03202           d               d
03203           e               e
03204         '''
03205     version = ''
03206 
03207 
03208 class TestHelpOnlyUserGroups(HelpTestCase):
03209     """Test basic usage messages"""
03210 
03211     parser_signature = Sig(prog='PROG', add_help=False)
03212     argument_signatures = []
03213     argument_group_signatures = [
03214         (Sig('xxxx'), [
03215             Sig('-x', help='x'),
03216             Sig('a', help='a'),
03217         ]),
03218         (Sig('yyyy'), [
03219             Sig('b', help='b'),
03220             Sig('-y', help='y'),
03221         ]),
03222     ]
03223     usage = '''\
03224         usage: PROG [-x X] [-y Y] a b
03225         '''
03226     help = usage + '''\
03227 
03228         xxxx:
03229           -x X  x
03230           a     a
03231 
03232         yyyy:
03233           b     b
03234           -y Y  y
03235         '''
03236     version = ''
03237 
03238 
03239 class TestHelpUsageLongProg(HelpTestCase):
03240     """Test usage messages where the prog is long"""
03241 
03242     parser_signature = Sig(prog='P' * 60)
03243     argument_signatures = [
03244         Sig('-w', metavar='W'),
03245         Sig('-x', metavar='X'),
03246         Sig('a'),
03247         Sig('b'),
03248     ]
03249     argument_group_signatures = []
03250     usage = '''\
03251         usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
03252                [-h] [-w W] [-x X] a b
03253         '''
03254     help = usage + '''\
03255 
03256         positional arguments:
03257           a
03258           b
03259 
03260         optional arguments:
03261           -h, --help  show this help message and exit
03262           -w W
03263           -x X
03264         '''
03265     version = ''
03266 
03267 
03268 class TestHelpUsageLongProgOptionsWrap(HelpTestCase):
03269     """Test usage messages where the prog is long and the optionals wrap"""
03270 
03271     parser_signature = Sig(prog='P' * 60)
03272     argument_signatures = [
03273         Sig('-w', metavar='W' * 25),
03274         Sig('-x', metavar='X' * 25),
03275         Sig('-y', metavar='Y' * 25),
03276         Sig('-z', metavar='Z' * 25),
03277         Sig('a'),
03278         Sig('b'),
03279     ]
03280     argument_group_signatures = []
03281     usage = '''\
03282         usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
03283                [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
03284 [-x XXXXXXXXXXXXXXXXXXXXXXXXX]
03285                [-y YYYYYYYYYYYYYYYYYYYYYYYYY] [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
03286                a b
03287         '''
03288     help = usage + '''\
03289 
03290         positional arguments:
03291           a
03292           b
03293 
03294         optional arguments:
03295           -h, --help            show this help message and exit
03296           -w WWWWWWWWWWWWWWWWWWWWWWWWW
03297           -x XXXXXXXXXXXXXXXXXXXXXXXXX
03298           -y YYYYYYYYYYYYYYYYYYYYYYYYY
03299           -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
03300         '''
03301     version = ''
03302 
03303 
03304 class TestHelpUsageLongProgPositionalsWrap(HelpTestCase):
03305     """Test usage messages where the prog is long and the positionals wrap"""
03306 
03307     parser_signature = Sig(prog='P' * 60, add_help=False)
03308     argument_signatures = [
03309         Sig('a' * 25),
03310         Sig('b' * 25),
03311         Sig('c' * 25),
03312     ]
03313     argument_group_signatures = []
03314     usage = '''\
03315         usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
03316                aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
03317                ccccccccccccccccccccccccc
03318         '''
03319     help = usage + '''\
03320 
03321         positional arguments:
03322           aaaaaaaaaaaaaaaaaaaaaaaaa
03323           bbbbbbbbbbbbbbbbbbbbbbbbb
03324           ccccccccccccccccccccccccc
03325         '''
03326     version = ''
03327 
03328 
03329 class TestHelpUsageOptionalsWrap(HelpTestCase):
03330     """Test usage messages where the optionals wrap"""
03331 
03332     parser_signature = Sig(prog='PROG')
03333     argument_signatures = [
03334         Sig('-w', metavar='W' * 25),
03335         Sig('-x', metavar='X' * 25),
03336         Sig('-y', metavar='Y' * 25),
03337         Sig('-z', metavar='Z' * 25),
03338         Sig('a'),
03339         Sig('b'),
03340         Sig('c'),
03341     ]
03342     argument_group_signatures = []
03343     usage = '''\
03344         usage: PROG [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
03345 [-x XXXXXXXXXXXXXXXXXXXXXXXXX]
03346                     [-y YYYYYYYYYYYYYYYYYYYYYYYYY] \
03347 [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
03348                     a b c
03349         '''
03350     help = usage + '''\
03351 
03352         positional arguments:
03353           a
03354           b
03355           c
03356 
03357         optional arguments:
03358           -h, --help            show this help message and exit
03359           -w WWWWWWWWWWWWWWWWWWWWWWWWW
03360           -x XXXXXXXXXXXXXXXXXXXXXXXXX
03361           -y YYYYYYYYYYYYYYYYYYYYYYYYY
03362           -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
03363         '''
03364     version = ''
03365 
03366 
03367 class TestHelpUsagePositionalsWrap(HelpTestCase):
03368     """Test usage messages where the positionals wrap"""
03369 
03370     parser_signature = Sig(prog='PROG')
03371     argument_signatures = [
03372         Sig('-x'),
03373         Sig('-y'),
03374         Sig('-z'),
03375         Sig('a' * 25),
03376         Sig('b' * 25),
03377         Sig('c' * 25),
03378     ]
03379     argument_group_signatures = []
03380     usage = '''\
03381         usage: PROG [-h] [-x X] [-y Y] [-z Z]
03382                     aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
03383                     ccccccccccccccccccccccccc
03384         '''
03385     help = usage + '''\
03386 
03387         positional arguments:
03388           aaaaaaaaaaaaaaaaaaaaaaaaa
03389           bbbbbbbbbbbbbbbbbbbbbbbbb
03390           ccccccccccccccccccccccccc
03391 
03392         optional arguments:
03393           -h, --help            show this help message and exit
03394           -x X
03395           -y Y
03396           -z Z
03397         '''
03398     version = ''
03399 
03400 
03401 class TestHelpUsageOptionalsPositionalsWrap(HelpTestCase):
03402     """Test usage messages where the optionals and positionals wrap"""
03403 
03404     parser_signature = Sig(prog='PROG')
03405     argument_signatures = [
03406         Sig('-x', metavar='X' * 25),
03407         Sig('-y', metavar='Y' * 25),
03408         Sig('-z', metavar='Z' * 25),
03409         Sig('a' * 25),
03410         Sig('b' * 25),
03411         Sig('c' * 25),
03412     ]
03413     argument_group_signatures = []
03414     usage = '''\
03415         usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
03416 [-y YYYYYYYYYYYYYYYYYYYYYYYYY]
03417                     [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
03418                     aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
03419                     ccccccccccccccccccccccccc
03420         '''
03421     help = usage + '''\
03422 
03423         positional arguments:
03424           aaaaaaaaaaaaaaaaaaaaaaaaa
03425           bbbbbbbbbbbbbbbbbbbbbbbbb
03426           ccccccccccccccccccccccccc
03427 
03428         optional arguments:
03429           -h, --help            show this help message and exit
03430           -x XXXXXXXXXXXXXXXXXXXXXXXXX
03431           -y YYYYYYYYYYYYYYYYYYYYYYYYY
03432           -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
03433         '''
03434     version = ''
03435 
03436 
03437 class TestHelpUsageOptionalsOnlyWrap(HelpTestCase):
03438     """Test usage messages where there are only optionals and they wrap"""
03439 
03440     parser_signature = Sig(prog='PROG')
03441     argument_signatures = [
03442         Sig('-x', metavar='X' * 25),
03443         Sig('-y', metavar='Y' * 25),
03444         Sig('-z', metavar='Z' * 25),
03445     ]
03446     argument_group_signatures = []
03447     usage = '''\
03448         usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
03449 [-y YYYYYYYYYYYYYYYYYYYYYYYYY]
03450                     [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
03451         '''
03452     help = usage + '''\
03453 
03454         optional arguments:
03455           -h, --help            show this help message and exit
03456           -x XXXXXXXXXXXXXXXXXXXXXXXXX
03457           -y YYYYYYYYYYYYYYYYYYYYYYYYY
03458           -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
03459         '''
03460     version = ''
03461 
03462 
03463 class TestHelpUsagePositionalsOnlyWrap(HelpTestCase):
03464     """Test usage messages where there are only positionals and they wrap"""
03465 
03466     parser_signature = Sig(prog='PROG', add_help=False)
03467     argument_signatures = [
03468         Sig('a' * 25),
03469         Sig('b' * 25),
03470         Sig('c' * 25),
03471     ]
03472     argument_group_signatures = []
03473     usage = '''\
03474         usage: PROG aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
03475                     ccccccccccccccccccccccccc
03476         '''
03477     help = usage + '''\
03478 
03479         positional arguments:
03480           aaaaaaaaaaaaaaaaaaaaaaaaa
03481           bbbbbbbbbbbbbbbbbbbbbbbbb
03482           ccccccccccccccccccccccccc
03483         '''
03484     version = ''
03485 
03486 
03487 class TestHelpVariableExpansion(HelpTestCase):
03488     """Test that variables are expanded properly in help messages"""
03489 
03490     parser_signature = Sig(prog='PROG')
03491     argument_signatures = [
03492         Sig('-x', type=int,
03493             help='x %(prog)s %(default)s %(type)s %%'),
03494         Sig('-y', action='store_const', default=42, const='XXX',
03495             help='y %(prog)s %(default)s %(const)s'),
03496         Sig('--foo', choices='abc',
03497             help='foo %(prog)s %(default)s %(choices)s'),
03498         Sig('--bar', default='baz', choices=[1, 2], metavar='BBB',
03499             help='bar %(prog)s %(default)s %(dest)s'),
03500         Sig('spam', help='spam %(prog)s %(default)s'),
03501         Sig('badger', default=0.5, help='badger %(prog)s %(default)s'),
03502     ]
03503     argument_group_signatures = [
03504         (Sig('group'), [
03505             Sig('-a', help='a %(prog)s %(default)s'),
03506             Sig('-b', default=-1, help='b %(prog)s %(default)s'),
03507         ])
03508     ]
03509     usage = ('''\
03510         usage: PROG [-h] [-x X] [-y] [--foo {a,b,c}] [--bar BBB] [-a A] [-b B]
03511                     spam badger
03512         ''')
03513     help = usage + '''\
03514 
03515         positional arguments:
03516           spam           spam PROG None
03517           badger         badger PROG 0.5
03518 
03519         optional arguments:
03520           -h, --help     show this help message and exit
03521           -x X           x PROG None int %
03522           -y             y PROG 42 XXX
03523           --foo {a,b,c}  foo PROG None a, b, c
03524           --bar BBB      bar PROG baz bar
03525 
03526         group:
03527           -a A           a PROG None
03528           -b B           b PROG -1
03529         '''
03530     version = ''
03531 
03532 
03533 class TestHelpVariableExpansionUsageSupplied(HelpTestCase):
03534     """Test that variables are expanded properly when usage= is present"""
03535 
03536     parser_signature = Sig(prog='PROG', usage='%(prog)s FOO')
03537     argument_signatures = []
03538     argument_group_signatures = []
03539     usage = ('''\
03540         usage: PROG FOO
03541         ''')
03542     help = usage + '''\
03543 
03544         optional arguments:
03545           -h, --help  show this help message and exit
03546         '''
03547     version = ''
03548 
03549 
03550 class TestHelpVariableExpansionNoArguments(HelpTestCase):
03551     """Test that variables are expanded properly with no arguments"""
03552 
03553     parser_signature = Sig(prog='PROG', add_help=False)
03554     argument_signatures = []
03555     argument_group_signatures = []
03556     usage = ('''\
03557         usage: PROG
03558         ''')
03559     help = usage
03560     version = ''
03561 
03562 
03563 class TestHelpSuppressUsage(HelpTestCase):
03564     """Test that items can be suppressed in usage messages"""
03565 
03566     parser_signature = Sig(prog='PROG', usage=argparse.SUPPRESS)
03567     argument_signatures = [
03568         Sig('--foo', help='foo help'),
03569         Sig('spam', help='spam help'),
03570     ]
03571     argument_group_signatures = []
03572     help = '''\
03573         positional arguments:
03574           spam        spam help
03575 
03576         optional arguments:
03577           -h, --help  show this help message and exit
03578           --foo FOO   foo help
03579         '''
03580     usage = ''
03581     version = ''
03582 
03583 
03584 class TestHelpSuppressOptional(HelpTestCase):
03585     """Test that optional arguments can be suppressed in help messages"""
03586 
03587     parser_signature = Sig(prog='PROG', add_help=False)
03588     argument_signatures = [
03589         Sig('--foo', help=argparse.SUPPRESS),
03590         Sig('spam', help='spam help'),
03591     ]
03592     argument_group_signatures = []
03593     usage = '''\
03594         usage: PROG spam
03595         '''
03596     help = usage + '''\
03597 
03598         positional arguments:
03599           spam  spam help
03600         '''
03601     version = ''
03602 
03603 
03604 class TestHelpSuppressOptionalGroup(HelpTestCase):
03605     """Test that optional groups can be suppressed in help messages"""
03606 
03607     parser_signature = Sig(prog='PROG')
03608     argument_signatures = [
03609         Sig('--foo', help='foo help'),
03610         Sig('spam', help='spam help'),
03611     ]
03612     argument_group_signatures = [
03613         (Sig('group'), [Sig('--bar', help=argparse.SUPPRESS)]),
03614     ]
03615     usage = '''\
03616         usage: PROG [-h] [--foo FOO] spam
03617         '''
03618     help = usage + '''\
03619 
03620         positional arguments:
03621           spam        spam help
03622 
03623         optional arguments:
03624           -h, --help  show this help message and exit
03625           --foo FOO   foo help
03626         '''
03627     version = ''
03628 
03629 
03630 class TestHelpSuppressPositional(HelpTestCase):
03631     """Test that positional arguments can be suppressed in help messages"""
03632 
03633     parser_signature = Sig(prog='PROG')
03634     argument_signatures = [
03635         Sig('--foo', help='foo help'),
03636         Sig('spam', help=argparse.SUPPRESS),
03637     ]
03638     argument_group_signatures = []
03639     usage = '''\
03640         usage: PROG [-h] [--foo FOO]
03641         '''
03642     help = usage + '''\
03643 
03644         optional arguments:
03645           -h, --help  show this help message and exit
03646           --foo FOO   foo help
03647         '''
03648     version = ''
03649 
03650 
03651 class TestHelpRequiredOptional(HelpTestCase):
03652     """Test that required options don't look optional"""
03653 
03654     parser_signature = Sig(prog='PROG')
03655     argument_signatures = [
03656         Sig('--foo', required=True, help='foo help'),
03657     ]
03658     argument_group_signatures = []
03659     usage = '''\
03660         usage: PROG [-h] --foo FOO
03661         '''
03662     help = usage + '''\
03663 
03664         optional arguments:
03665           -h, --help  show this help message and exit
03666           --foo FOO   foo help
03667         '''
03668     version = ''
03669 
03670 
03671 class TestHelpAlternatePrefixChars(HelpTestCase):
03672     """Test that options display with different prefix characters"""
03673 
03674     parser_signature = Sig(prog='PROG', prefix_chars='^;', add_help=False)
03675     argument_signatures = [
03676         Sig('^^foo', action='store_true', help='foo help'),
03677         Sig(';b', ';;bar', help='bar help'),
03678     ]
03679     argument_group_signatures = []
03680     usage = '''\
03681         usage: PROG [^^foo] [;b BAR]
03682         '''
03683     help = usage + '''\
03684 
03685         optional arguments:
03686           ^^foo              foo help
03687           ;b BAR, ;;bar BAR  bar help
03688         '''
03689     version = ''
03690 
03691 
03692 class TestHelpNoHelpOptional(HelpTestCase):
03693     """Test that the --help argument can be suppressed help messages"""
03694 
03695     parser_signature = Sig(prog='PROG', add_help=False)
03696     argument_signatures = [
03697         Sig('--foo', help='foo help'),
03698         Sig('spam', help='spam help'),
03699     ]
03700     argument_group_signatures = []
03701     usage = '''\
03702         usage: PROG [--foo FOO] spam
03703         '''
03704     help = usage + '''\
03705 
03706         positional arguments:
03707           spam       spam help
03708 
03709         optional arguments:
03710           --foo FOO  foo help
03711         '''
03712     version = ''
03713 
03714 
03715 class TestHelpVersionOptional(HelpTestCase):
03716     """Test that the --version argument can be suppressed help messages"""
03717 
03718     parser_signature = Sig(prog='PROG', version='1.0')
03719     argument_signatures = [
03720         Sig('--foo', help='foo help'),
03721         Sig('spam', help='spam help'),
03722     ]
03723     argument_group_signatures = []
03724     usage = '''\
03725         usage: PROG [-h] [-v] [--foo FOO] spam
03726         '''
03727     help = usage + '''\
03728 
03729         positional arguments:
03730           spam           spam help
03731 
03732         optional arguments:
03733           -h, --help     show this help message and exit
03734           -v, --version  show program's version number and exit
03735           --foo FOO      foo help
03736         '''
03737     version = '''\
03738         1.0
03739         '''
03740 
03741 
03742 class TestHelpNone(HelpTestCase):
03743     """Test that no errors occur if no help is specified"""
03744 
03745     parser_signature = Sig(prog='PROG')
03746     argument_signatures = [
03747         Sig('--foo'),
03748         Sig('spam'),
03749     ]
03750     argument_group_signatures = []
03751     usage = '''\
03752         usage: PROG [-h] [--foo FOO] spam
03753         '''
03754     help = usage + '''\
03755 
03756         positional arguments:
03757           spam
03758 
03759         optional arguments:
03760           -h, --help  show this help message and exit
03761           --foo FOO
03762         '''
03763     version = ''
03764 
03765 
03766 class TestHelpTupleMetavar(HelpTestCase):
03767     """Test specifying metavar as a tuple"""
03768 
03769     parser_signature = Sig(prog='PROG')
03770     argument_signatures = [
03771         Sig('-w', help='w', nargs='+', metavar=('W1', 'W2')),
03772         Sig('-x', help='x', nargs='*', metavar=('X1', 'X2')),
03773         Sig('-y', help='y', nargs=3, metavar=('Y1', 'Y2', 'Y3')),
03774         Sig('-z', help='z', nargs='?', metavar=('Z1', )),
03775     ]
03776     argument_group_signatures = []
03777     usage = '''\
03778         usage: PROG [-h] [-w W1 [W2 ...]] [-x [X1 [X2 ...]]] [-y Y1 Y2 Y3] \
03779 [-z [Z1]]
03780         '''
03781     help = usage + '''\
03782 
03783         optional arguments:
03784           -h, --help        show this help message and exit
03785           -w W1 [W2 ...]    w
03786           -x [X1 [X2 ...]]  x
03787           -y Y1 Y2 Y3       y
03788           -z [Z1]           z
03789         '''
03790     version = ''
03791 
03792 
03793 class TestHelpRawText(HelpTestCase):
03794     """Test the RawTextHelpFormatter"""
03795 
03796     parser_signature = Sig(
03797         prog='PROG', formatter_class=argparse.RawTextHelpFormatter,
03798         description='Keep the formatting\n'
03799                     '    exactly as it is written\n'
03800                     '\n'
03801                     'here\n')
03802 
03803     argument_signatures = [
03804         Sig('--foo', help='    foo help should also\n'
03805                           'appear as given here'),
03806         Sig('spam', help='spam help'),
03807     ]
03808     argument_group_signatures = [
03809         (Sig('title', description='    This text\n'
03810                                   '  should be indented\n'
03811                                   '    exactly like it is here\n'),
03812          [Sig('--bar', help='bar help')]),
03813     ]
03814     usage = '''\
03815         usage: PROG [-h] [--foo FOO] [--bar BAR] spam
03816         '''
03817     help = usage + '''\
03818 
03819         Keep the formatting
03820             exactly as it is written
03821 
03822         here
03823 
03824         positional arguments:
03825           spam        spam help
03826 
03827         optional arguments:
03828           -h, --help  show this help message and exit
03829           --foo FOO       foo help should also
03830                       appear as given here
03831 
03832         title:
03833               This text
03834             should be indented
03835               exactly like it is here
03836 
03837           --bar BAR   bar help
03838         '''
03839     version = ''
03840 
03841 
03842 class TestHelpRawDescription(HelpTestCase):
03843     """Test the RawTextHelpFormatter"""
03844 
03845     parser_signature = Sig(
03846         prog='PROG', formatter_class=argparse.RawDescriptionHelpFormatter,
03847         description='Keep the formatting\n'
03848                     '    exactly as it is written\n'
03849                     '\n'
03850                     'here\n')
03851 
03852     argument_signatures = [
03853         Sig('--foo', help='  foo help should not\n'
03854                           '    retain this odd formatting'),
03855         Sig('spam', help='spam help'),
03856     ]
03857     argument_group_signatures = [
03858         (Sig('title', description='    This text\n'
03859                                   '  should be indented\n'
03860                                   '    exactly like it is here\n'),
03861          [Sig('--bar', help='bar help')]),
03862     ]
03863     usage = '''\
03864         usage: PROG [-h] [--foo FOO] [--bar BAR] spam
03865         '''
03866     help = usage + '''\
03867 
03868         Keep the formatting
03869             exactly as it is written
03870 
03871         here
03872 
03873         positional arguments:
03874           spam        spam help
03875 
03876         optional arguments:
03877           -h, --help  show this help message and exit
03878           --foo FOO   foo help should not retain this odd formatting
03879 
03880         title:
03881               This text
03882             should be indented
03883               exactly like it is here
03884 
03885           --bar BAR   bar help
03886         '''
03887     version = ''
03888 
03889 
03890 class TestHelpArgumentDefaults(HelpTestCase):
03891     """Test the ArgumentDefaultsHelpFormatter"""
03892 
03893     parser_signature = Sig(
03894         prog='PROG', formatter_class=argparse.ArgumentDefaultsHelpFormatter,
03895         description='description')
03896 
03897     argument_signatures = [
03898         Sig('--foo', help='foo help - oh and by the way, %(default)s'),
03899         Sig('--bar', action='store_true', help='bar help'),
03900         Sig('spam', help='spam help'),
03901         Sig('badger', nargs='?', default='wooden', help='badger help'),
03902     ]
03903     argument_group_signatures = [
03904         (Sig('title', description='description'),
03905          [Sig('--baz', type=int, default=42, help='baz help')]),
03906     ]
03907     usage = '''\
03908         usage: PROG [-h] [--foo FOO] [--bar] [--baz BAZ] spam [badger]
03909         '''
03910     help = usage + '''\
03911 
03912         description
03913 
03914         positional arguments:
03915           spam        spam help
03916           badger      badger help (default: wooden)
03917 
03918         optional arguments:
03919           -h, --help  show this help message and exit
03920           --foo FOO   foo help - oh and by the way, None
03921           --bar       bar help (default: False)
03922 
03923         title:
03924           description
03925 
03926           --baz BAZ   baz help (default: 42)
03927         '''
03928     version = ''
03929 
03930 class TestHelpVersionAction(HelpTestCase):
03931     """Test the default help for the version action"""
03932 
03933     parser_signature = Sig(prog='PROG', description='description')
03934     argument_signatures = [Sig('-V', '--version', action='version', version='3.6')]
03935     argument_group_signatures = []
03936     usage = '''\
03937         usage: PROG [-h] [-V]
03938         '''
03939     help = usage + '''\
03940 
03941         description
03942 
03943         optional arguments:
03944           -h, --help     show this help message and exit
03945           -V, --version  show program's version number and exit
03946         '''
03947     version = ''
03948 
03949 class TestHelpSubparsersOrdering(HelpTestCase):
03950     """Test ordering of subcommands in help matches the code"""
03951     parser_signature = Sig(prog='PROG',
03952                            description='display some subcommands',
03953                            version='0.1')
03954 
03955     subparsers_signatures = [Sig(name=name)
03956                              for name in ('a', 'b', 'c', 'd', 'e')]
03957 
03958     usage = '''\
03959         usage: PROG [-h] [-v] {a,b,c,d,e} ...
03960         '''
03961 
03962     help = usage + '''\
03963 
03964         display some subcommands
03965 
03966         positional arguments:
03967           {a,b,c,d,e}
03968 
03969         optional arguments:
03970           -h, --help     show this help message and exit
03971           -v, --version  show program's version number and exit
03972         '''
03973 
03974     version = '''\
03975         0.1
03976         '''
03977 
03978 class TestHelpSubparsersWithHelpOrdering(HelpTestCase):
03979     """Test ordering of subcommands in help matches the code"""
03980     parser_signature = Sig(prog='PROG',
03981                            description='display some subcommands',
03982                            version='0.1')
03983 
03984     subcommand_data = (('a', 'a subcommand help'),
03985                        ('b', 'b subcommand help'),
03986                        ('c', 'c subcommand help'),
03987                        ('d', 'd subcommand help'),
03988                        ('e', 'e subcommand help'),
03989                        )
03990 
03991     subparsers_signatures = [Sig(name=name, help=help)
03992                              for name, help in subcommand_data]
03993 
03994     usage = '''\
03995         usage: PROG [-h] [-v] {a,b,c,d,e} ...
03996         '''
03997 
03998     help = usage + '''\
03999 
04000         display some subcommands
04001 
04002         positional arguments:
04003           {a,b,c,d,e}
04004             a            a subcommand help
04005             b            b subcommand help
04006             c            c subcommand help
04007             d            d subcommand help
04008             e            e subcommand help
04009 
04010         optional arguments:
04011           -h, --help     show this help message and exit
04012           -v, --version  show program's version number and exit
04013         '''
04014 
04015     version = '''\
04016         0.1
04017         '''
04018 
04019 
04020 # =====================================
04021 # Optional/Positional constructor tests
04022 # =====================================
04023 
04024 class TestInvalidArgumentConstructors(TestCase):
04025     """Test a bunch of invalid Argument constructors"""
04026 
04027     def assertTypeError(self, *args, **kwargs):
04028         parser = argparse.ArgumentParser()
04029         self.assertRaises(TypeError, parser.add_argument,
04030                           *args, **kwargs)
04031 
04032     def assertValueError(self, *args, **kwargs):
04033         parser = argparse.ArgumentParser()
04034         self.assertRaises(ValueError, parser.add_argument,
04035                           *args, **kwargs)
04036 
04037     def test_invalid_keyword_arguments(self):
04038         self.assertTypeError('-x', bar=None)
04039         self.assertTypeError('-y', callback='foo')
04040         self.assertTypeError('-y', callback_args=())
04041         self.assertTypeError('-y', callback_kwargs={})
04042 
04043     def test_missing_destination(self):
04044         self.assertTypeError()
04045         for action in ['append', 'store']:
04046             self.assertTypeError(action=action)
04047 
04048     def test_invalid_option_strings(self):
04049         self.assertValueError('--')
04050         self.assertValueError('---')
04051 
04052     def test_invalid_type(self):
04053         self.assertValueError('--foo', type='int')
04054         self.assertValueError('--foo', type=(int, float))
04055 
04056     def test_invalid_action(self):
04057         self.assertValueError('-x', action='foo')
04058         self.assertValueError('foo', action='baz')
04059         self.assertValueError('--foo', action=('store', 'append'))
04060         parser = argparse.ArgumentParser()
04061         try:
04062             parser.add_argument("--foo", action="store-true")
04063         except ValueError:
04064             e = sys.exc_info()[1]
04065             expected = 'unknown action'
04066             msg = 'expected %r, found %r' % (expected, e)
04067             self.assertTrue(expected in str(e), msg)
04068 
04069     def test_multiple_dest(self):
04070         parser = argparse.ArgumentParser()
04071         parser.add_argument(dest='foo')
04072         try:
04073             parser.add_argument('bar', dest='baz')
04074         except ValueError:
04075             e = sys.exc_info()[1]
04076             expected = 'dest supplied twice for positional argument'
04077             msg = 'expected %r, found %r' % (expected, e)
04078             self.assertTrue(expected in str(e), msg)
04079 
04080     def test_no_argument_actions(self):
04081         for action in ['store_const', 'store_true', 'store_false',
04082                        'append_const', 'count']:
04083             for attrs in [dict(type=int), dict(nargs='+'),
04084                           dict(choices='ab')]:
04085                 self.assertTypeError('-x', action=action, **attrs)
04086 
04087     def test_no_argument_no_const_actions(self):
04088         # options with zero arguments
04089         for action in ['store_true', 'store_false', 'count']:
04090 
04091             # const is always disallowed
04092             self.assertTypeError('-x', const='foo', action=action)
04093 
04094             # nargs is always disallowed
04095             self.assertTypeError('-x', nargs='*', action=action)
04096 
04097     def test_more_than_one_argument_actions(self):
04098         for action in ['store', 'append']:
04099 
04100             # nargs=0 is disallowed
04101             self.assertValueError('-x', nargs=0, action=action)
04102             self.assertValueError('spam', nargs=0, action=action)
04103 
04104             # const is disallowed with non-optional arguments
04105             for nargs in [1, '*', '+']:
04106                 self.assertValueError('-x', const='foo',
04107                                       nargs=nargs, action=action)
04108                 self.assertValueError('spam', const='foo',
04109                                       nargs=nargs, action=action)
04110 
04111     def test_required_const_actions(self):
04112         for action in ['store_const', 'append_const']:
04113 
04114             # nargs is always disallowed
04115             self.assertTypeError('-x', nargs='+', action=action)
04116 
04117     def test_parsers_action_missing_params(self):
04118         self.assertTypeError('command', action='parsers')
04119         self.assertTypeError('command', action='parsers', prog='PROG')
04120         self.assertTypeError('command', action='parsers',
04121                              parser_class=argparse.ArgumentParser)
04122 
04123     def test_required_positional(self):
04124         self.assertTypeError('foo', required=True)
04125 
04126     def test_user_defined_action(self):
04127 
04128         class Success(Exception):
04129             pass
04130 
04131         class Action(object):
04132 
04133             def __init__(self,
04134                          option_strings,
04135                          dest,
04136                          const,
04137                          default,
04138                          required=False):
04139                 if dest == 'spam':
04140                     if const is Success:
04141                         if default is Success:
04142                             raise Success()
04143 
04144             def __call__(self, *args, **kwargs):
04145                 pass
04146 
04147         parser = argparse.ArgumentParser()
04148         self.assertRaises(Success, parser.add_argument, '--spam',
04149                           action=Action, default=Success, const=Success)
04150         self.assertRaises(Success, parser.add_argument, 'spam',
04151                           action=Action, default=Success, const=Success)
04152 
04153 # ================================
04154 # Actions returned by add_argument
04155 # ================================
04156 
04157 class TestActionsReturned(TestCase):
04158 
04159     def test_dest(self):
04160         parser = argparse.ArgumentParser()
04161         action = parser.add_argument('--foo')
04162         self.assertEqual(action.dest, 'foo')
04163         action = parser.add_argument('-b', '--bar')
04164         self.assertEqual(action.dest, 'bar')
04165         action = parser.add_argument('-x', '-y')
04166         self.assertEqual(action.dest, 'x')
04167 
04168     def test_misc(self):
04169         parser = argparse.ArgumentParser()
04170         action = parser.add_argument('--foo', nargs='?', const=42,
04171                                      default=84, type=int, choices=[1, 2],
04172                                      help='FOO', metavar='BAR', dest='baz')
04173         self.assertEqual(action.nargs, '?')
04174         self.assertEqual(action.const, 42)
04175         self.assertEqual(action.default, 84)
04176         self.assertEqual(action.type, int)
04177         self.assertEqual(action.choices, [1, 2])
04178         self.assertEqual(action.help, 'FOO')
04179         self.assertEqual(action.metavar, 'BAR')
04180         self.assertEqual(action.dest, 'baz')
04181 
04182 
04183 # ================================
04184 # Argument conflict handling tests
04185 # ================================
04186 
04187 class TestConflictHandling(TestCase):
04188 
04189     def test_bad_type(self):
04190         self.assertRaises(ValueError, argparse.ArgumentParser,
04191                           conflict_handler='foo')
04192 
04193     def test_conflict_error(self):
04194         parser = argparse.ArgumentParser()
04195         parser.add_argument('-x')
04196         self.assertRaises(argparse.ArgumentError,
04197                           parser.add_argument, '-x')
04198         parser.add_argument('--spam')
04199         self.assertRaises(argparse.ArgumentError,
04200                           parser.add_argument, '--spam')
04201 
04202     def test_resolve_error(self):
04203         get_parser = argparse.ArgumentParser
04204         parser = get_parser(prog='PROG', conflict_handler='resolve')
04205 
04206         parser.add_argument('-x', help='OLD X')
04207         parser.add_argument('-x', help='NEW X')
04208         self.assertEqual(parser.format_help(), textwrap.dedent('''\
04209             usage: PROG [-h] [-x X]
04210 
04211             optional arguments:
04212               -h, --help  show this help message and exit
04213               -x X        NEW X
04214             '''))
04215 
04216         parser.add_argument('--spam', metavar='OLD_SPAM')
04217         parser.add_argument('--spam', metavar='NEW_SPAM')
04218         self.assertEqual(parser.format_help(), textwrap.dedent('''\
04219             usage: PROG [-h] [-x X] [--spam NEW_SPAM]
04220 
04221             optional arguments:
04222               -h, --help       show this help message and exit
04223               -x X             NEW X
04224               --spam NEW_SPAM
04225             '''))
04226 
04227 
04228 # =============================
04229 # Help and Version option tests
04230 # =============================
04231 
04232 class TestOptionalsHelpVersionActions(TestCase):
04233     """Test the help and version actions"""
04234 
04235     def _get_error(self, func, *args, **kwargs):
04236         try:
04237             func(*args, **kwargs)
04238         except ArgumentParserError:
04239             return sys.exc_info()[1]
04240         else:
04241             self.assertRaises(ArgumentParserError, func, *args, **kwargs)
04242 
04243     def assertPrintHelpExit(self, parser, args_str):
04244         self.assertEqual(
04245             parser.format_help(),
04246             self._get_error(parser.parse_args, args_str.split()).stdout)
04247 
04248     def assertPrintVersionExit(self, parser, args_str):
04249         self.assertEqual(
04250             parser.format_version(),
04251             self._get_error(parser.parse_args, args_str.split()).stderr)
04252 
04253     def assertArgumentParserError(self, parser, *args):
04254         self.assertRaises(ArgumentParserError, parser.parse_args, args)
04255 
04256     def test_version(self):
04257         parser = ErrorRaisingArgumentParser(version='1.0')
04258         self.assertPrintHelpExit(parser, '-h')
04259         self.assertPrintHelpExit(parser, '--help')
04260         self.assertPrintVersionExit(parser, '-v')
04261         self.assertPrintVersionExit(parser, '--version')
04262 
04263     def test_version_format(self):
04264         parser = ErrorRaisingArgumentParser(prog='PPP', version='%(prog)s 3.5')
04265         msg = self._get_error(parser.parse_args, ['-v']).stderr
04266         self.assertEqual('PPP 3.5\n', msg)
04267 
04268     def test_version_no_help(self):
04269         parser = ErrorRaisingArgumentParser(add_help=False, version='1.0')
04270         self.assertArgumentParserError(parser, '-h')
04271         self.assertArgumentParserError(parser, '--help')
04272         self.assertPrintVersionExit(parser, '-v')
04273         self.assertPrintVersionExit(parser, '--version')
04274 
04275     def test_version_action(self):
04276         parser = ErrorRaisingArgumentParser(prog='XXX')
04277         parser.add_argument('-V', action='version', version='%(prog)s 3.7')
04278         msg = self._get_error(parser.parse_args, ['-V']).stderr
04279         self.assertEqual('XXX 3.7\n', msg)
04280 
04281     def test_no_help(self):
04282         parser = ErrorRaisingArgumentParser(add_help=False)
04283         self.assertArgumentParserError(parser, '-h')
04284         self.assertArgumentParserError(parser, '--help')
04285         self.assertArgumentParserError(parser, '-v')
04286         self.assertArgumentParserError(parser, '--version')
04287 
04288     def test_alternate_help_version(self):
04289         parser = ErrorRaisingArgumentParser()
04290         parser.add_argument('-x', action='help')
04291         parser.add_argument('-y', action='version')
04292         self.assertPrintHelpExit(parser, '-x')
04293         self.assertPrintVersionExit(parser, '-y')
04294         self.assertArgumentParserError(parser, '-v')
04295         self.assertArgumentParserError(parser, '--version')
04296 
04297     def test_help_version_extra_arguments(self):
04298         parser = ErrorRaisingArgumentParser(version='1.0')
04299         parser.add_argument('-x', action='store_true')
04300         parser.add_argument('y')
04301 
04302         # try all combinations of valid prefixes and suffixes
04303         valid_prefixes = ['', '-x', 'foo', '-x bar', 'baz -x']
04304         valid_suffixes = valid_prefixes + ['--bad-option', 'foo bar baz']
04305         for prefix in valid_prefixes:
04306             for suffix in valid_suffixes:
04307                 format = '%s %%s %s' % (prefix, suffix)
04308             self.assertPrintHelpExit(parser, format % '-h')
04309             self.assertPrintHelpExit(parser, format % '--help')
04310             self.assertPrintVersionExit(parser, format % '-v')
04311             self.assertPrintVersionExit(parser, format % '--version')
04312 
04313 
04314 # ======================
04315 # str() and repr() tests
04316 # ======================
04317 
04318 class TestStrings(TestCase):
04319     """Test str()  and repr() on Optionals and Positionals"""
04320 
04321     def assertStringEqual(self, obj, result_string):
04322         for func in [str, repr]:
04323             self.assertEqual(func(obj), result_string)
04324 
04325     def test_optional(self):
04326         option = argparse.Action(
04327             option_strings=['--foo', '-a', '-b'],
04328             dest='b',
04329             type='int',
04330             nargs='+',
04331             default=42,
04332             choices=[1, 2, 3],
04333             help='HELP',
04334             metavar='METAVAR')
04335         string = (
04336             "Action(option_strings=['--foo', '-a', '-b'], dest='b', "
04337             "nargs='+', const=None, default=42, type='int', "
04338             "choices=[1, 2, 3], help='HELP', metavar='METAVAR')")
04339         self.assertStringEqual(option, string)
04340 
04341     def test_argument(self):
04342         argument = argparse.Action(
04343             option_strings=[],
04344             dest='x',
04345             type=float,
04346             nargs='?',
04347             default=2.5,
04348             choices=[0.5, 1.5, 2.5],
04349             help='H HH H',
04350             metavar='MV MV MV')
04351         string = (
04352             "Action(option_strings=[], dest='x', nargs='?', "
04353             "const=None, default=2.5, type=%r, choices=[0.5, 1.5, 2.5], "
04354             "help='H HH H', metavar='MV MV MV')" % float)
04355         self.assertStringEqual(argument, string)
04356 
04357     def test_namespace(self):
04358         ns = argparse.Namespace(foo=42, bar='spam')
04359         string = "Namespace(bar='spam', foo=42)"
04360         self.assertStringEqual(ns, string)
04361 
04362     def test_parser(self):
04363         parser = argparse.ArgumentParser(prog='PROG')
04364         string = (
04365             "ArgumentParser(prog='PROG', usage=None, description=None, "
04366             "version=None, formatter_class=%r, conflict_handler='error', "
04367             "add_help=True)" % argparse.HelpFormatter)
04368         self.assertStringEqual(parser, string)
04369 
04370 # ===============
04371 # Namespace tests
04372 # ===============
04373 
04374 class TestNamespace(TestCase):
04375 
04376     def test_constructor(self):
04377         ns = argparse.Namespace()
04378         self.assertRaises(AttributeError, getattr, ns, 'x')
04379 
04380         ns = argparse.Namespace(a=42, b='spam')
04381         self.assertEqual(ns.a, 42)
04382         self.assertEqual(ns.b, 'spam')
04383 
04384     def test_equality(self):
04385         ns1 = argparse.Namespace(a=1, b=2)
04386         ns2 = argparse.Namespace(b=2, a=1)
04387         ns3 = argparse.Namespace(a=1)
04388         ns4 = argparse.Namespace(b=2)
04389 
04390         self.assertEqual(ns1, ns2)
04391         self.assertNotEqual(ns1, ns3)
04392         self.assertNotEqual(ns1, ns4)
04393         self.assertNotEqual(ns2, ns3)
04394         self.assertNotEqual(ns2, ns4)
04395         self.assertTrue(ns1 != ns3)
04396         self.assertTrue(ns1 != ns4)
04397         self.assertTrue(ns2 != ns3)
04398         self.assertTrue(ns2 != ns4)
04399 
04400 
04401 # ===================
04402 # File encoding tests
04403 # ===================
04404 
04405 class TestEncoding(TestCase):
04406 
04407     def _test_module_encoding(self, path):
04408         path, _ = os.path.splitext(path)
04409         path += ".py"
04410         with codecs.open(path, 'r', 'utf8') as f:
04411             f.read()
04412 
04413     def test_argparse_module_encoding(self):
04414         self._test_module_encoding(argparse.__file__)
04415 
04416     def test_test_argparse_module_encoding(self):
04417         self._test_module_encoding(__file__)
04418 
04419 # ===================
04420 # ArgumentError tests
04421 # ===================
04422 
04423 class TestArgumentError(TestCase):
04424 
04425     def test_argument_error(self):
04426         msg = "my error here"
04427         error = argparse.ArgumentError(None, msg)
04428         self.assertEqual(str(error), msg)
04429 
04430 # =======================
04431 # ArgumentTypeError tests
04432 # =======================
04433 
04434 class TestArgumentTypeError(TestCase):
04435 
04436     def test_argument_type_error(self):
04437 
04438         def spam(string):
04439             raise argparse.ArgumentTypeError('spam!')
04440 
04441         parser = ErrorRaisingArgumentParser(prog='PROG', add_help=False)
04442         parser.add_argument('x', type=spam)
04443         try:
04444             parser.parse_args(['XXX'])
04445         except ArgumentParserError:
04446             expected = 'usage: PROG x\nPROG: error: argument x: spam!\n'
04447             msg = sys.exc_info()[1].stderr
04448             self.assertEqual(expected, msg)
04449         else:
04450             self.fail()
04451 
04452 # ======================
04453 # parse_known_args tests
04454 # ======================
04455 
04456 class TestParseKnownArgs(TestCase):
04457 
04458     def test_optionals(self):
04459         parser = argparse.ArgumentParser()
04460         parser.add_argument('--foo')
04461         args, extras = parser.parse_known_args('--foo F --bar --baz'.split())
04462         self.assertEqual(NS(foo='F'), args)
04463         self.assertEqual(['--bar', '--baz'], extras)
04464 
04465     def test_mixed(self):
04466         parser = argparse.ArgumentParser()
04467         parser.add_argument('-v', nargs='?', const=1, type=int)
04468         parser.add_argument('--spam', action='store_false')
04469         parser.add_argument('badger')
04470 
04471         argv = ["B", "C", "--foo", "-v", "3", "4"]
04472         args, extras = parser.parse_known_args(argv)
04473         self.assertEqual(NS(v=3, spam=True, badger="B"), args)
04474         self.assertEqual(["C", "--foo", "4"], extras)
04475 
04476 # ==========================
04477 # add_argument metavar tests
04478 # ==========================
04479 
04480 class TestAddArgumentMetavar(TestCase):
04481 
04482     EXPECTED_MESSAGE = "length of metavar tuple does not match nargs"
04483 
04484     def do_test_no_exception(self, nargs, metavar):
04485         parser = argparse.ArgumentParser()
04486         parser.add_argument("--foo", nargs=nargs, metavar=metavar)
04487 
04488     def do_test_exception(self, nargs, metavar):
04489         parser = argparse.ArgumentParser()
04490         with self.assertRaises(ValueError) as cm:
04491             parser.add_argument("--foo", nargs=nargs, metavar=metavar)
04492         self.assertEqual(cm.exception.args[0], self.EXPECTED_MESSAGE)
04493 
04494     # Unit tests for different values of metavar when nargs=None
04495 
04496     def test_nargs_None_metavar_string(self):
04497         self.do_test_no_exception(nargs=None, metavar="1")
04498 
04499     def test_nargs_None_metavar_length0(self):
04500         self.do_test_exception(nargs=None, metavar=tuple())
04501 
04502     def test_nargs_None_metavar_length1(self):
04503         self.do_test_no_exception(nargs=None, metavar=("1"))
04504 
04505     def test_nargs_None_metavar_length2(self):
04506         self.do_test_exception(nargs=None, metavar=("1", "2"))
04507 
04508     def test_nargs_None_metavar_length3(self):
04509         self.do_test_exception(nargs=None, metavar=("1", "2", "3"))
04510 
04511     # Unit tests for different values of metavar when nargs=?
04512 
04513     def test_nargs_optional_metavar_string(self):
04514         self.do_test_no_exception(nargs="?", metavar="1")
04515 
04516     def test_nargs_optional_metavar_length0(self):
04517         self.do_test_exception(nargs="?", metavar=tuple())
04518 
04519     def test_nargs_optional_metavar_length1(self):
04520         self.do_test_no_exception(nargs="?", metavar=("1"))
04521 
04522     def test_nargs_optional_metavar_length2(self):
04523         self.do_test_exception(nargs="?", metavar=("1", "2"))
04524 
04525     def test_nargs_optional_metavar_length3(self):
04526         self.do_test_exception(nargs="?", metavar=("1", "2", "3"))
04527 
04528     # Unit tests for different values of metavar when nargs=*
04529 
04530     def test_nargs_zeroormore_metavar_string(self):
04531         self.do_test_no_exception(nargs="*", metavar="1")
04532 
04533     def test_nargs_zeroormore_metavar_length0(self):
04534         self.do_test_exception(nargs="*", metavar=tuple())
04535 
04536     def test_nargs_zeroormore_metavar_length1(self):
04537         self.do_test_no_exception(nargs="*", metavar=("1"))
04538 
04539     def test_nargs_zeroormore_metavar_length2(self):
04540         self.do_test_no_exception(nargs="*", metavar=("1", "2"))
04541 
04542     def test_nargs_zeroormore_metavar_length3(self):
04543         self.do_test_exception(nargs="*", metavar=("1", "2", "3"))
04544 
04545     # Unit tests for different values of metavar when nargs=+
04546 
04547     def test_nargs_oneormore_metavar_string(self):
04548         self.do_test_no_exception(nargs="+", metavar="1")
04549 
04550     def test_nargs_oneormore_metavar_length0(self):
04551         self.do_test_exception(nargs="+", metavar=tuple())
04552 
04553     def test_nargs_oneormore_metavar_length1(self):
04554         self.do_test_no_exception(nargs="+", metavar=("1"))
04555 
04556     def test_nargs_oneormore_metavar_length2(self):
04557         self.do_test_no_exception(nargs="+", metavar=("1", "2"))
04558 
04559     def test_nargs_oneormore_metavar_length3(self):
04560         self.do_test_exception(nargs="+", metavar=("1", "2", "3"))
04561 
04562     # Unit tests for different values of metavar when nargs=...
04563 
04564     def test_nargs_remainder_metavar_string(self):
04565         self.do_test_no_exception(nargs="...", metavar="1")
04566 
04567     def test_nargs_remainder_metavar_length0(self):
04568         self.do_test_no_exception(nargs="...", metavar=tuple())
04569 
04570     def test_nargs_remainder_metavar_length1(self):
04571         self.do_test_no_exception(nargs="...", metavar=("1"))
04572 
04573     def test_nargs_remainder_metavar_length2(self):
04574         self.do_test_no_exception(nargs="...", metavar=("1", "2"))
04575 
04576     def test_nargs_remainder_metavar_length3(self):
04577         self.do_test_no_exception(nargs="...", metavar=("1", "2", "3"))
04578 
04579     # Unit tests for different values of metavar when nargs=A...
04580 
04581     def test_nargs_parser_metavar_string(self):
04582         self.do_test_no_exception(nargs="A...", metavar="1")
04583 
04584     def test_nargs_parser_metavar_length0(self):
04585         self.do_test_exception(nargs="A...", metavar=tuple())
04586 
04587     def test_nargs_parser_metavar_length1(self):
04588         self.do_test_no_exception(nargs="A...", metavar=("1"))
04589 
04590     def test_nargs_parser_metavar_length2(self):
04591         self.do_test_exception(nargs="A...", metavar=("1", "2"))
04592 
04593     def test_nargs_parser_metavar_length3(self):
04594         self.do_test_exception(nargs="A...", metavar=("1", "2", "3"))
04595 
04596     # Unit tests for different values of metavar when nargs=1
04597 
04598     def test_nargs_1_metavar_string(self):
04599         self.do_test_no_exception(nargs=1, metavar="1")
04600 
04601     def test_nargs_1_metavar_length0(self):
04602         self.do_test_exception(nargs=1, metavar=tuple())
04603 
04604     def test_nargs_1_metavar_length1(self):
04605         self.do_test_no_exception(nargs=1, metavar=("1"))
04606 
04607     def test_nargs_1_metavar_length2(self):
04608         self.do_test_exception(nargs=1, metavar=("1", "2"))
04609 
04610     def test_nargs_1_metavar_length3(self):
04611         self.do_test_exception(nargs=1, metavar=("1", "2", "3"))
04612 
04613     # Unit tests for different values of metavar when nargs=2
04614 
04615     def test_nargs_2_metavar_string(self):
04616         self.do_test_no_exception(nargs=2, metavar="1")
04617 
04618     def test_nargs_2_metavar_length0(self):
04619         self.do_test_exception(nargs=2, metavar=tuple())
04620 
04621     def test_nargs_2_metavar_length1(self):
04622         self.do_test_no_exception(nargs=2, metavar=("1"))
04623 
04624     def test_nargs_2_metavar_length2(self):
04625         self.do_test_no_exception(nargs=2, metavar=("1", "2"))
04626 
04627     def test_nargs_2_metavar_length3(self):
04628         self.do_test_exception(nargs=2, metavar=("1", "2", "3"))
04629 
04630     # Unit tests for different values of metavar when nargs=3
04631 
04632     def test_nargs_3_metavar_string(self):
04633         self.do_test_no_exception(nargs=3, metavar="1")
04634 
04635     def test_nargs_3_metavar_length0(self):
04636         self.do_test_exception(nargs=3, metavar=tuple())
04637 
04638     def test_nargs_3_metavar_length1(self):
04639         self.do_test_no_exception(nargs=3, metavar=("1"))
04640 
04641     def test_nargs_3_metavar_length2(self):
04642         self.do_test_exception(nargs=3, metavar=("1", "2"))
04643 
04644     def test_nargs_3_metavar_length3(self):
04645         self.do_test_no_exception(nargs=3, metavar=("1", "2", "3"))
04646 
04647 # ============================
04648 # from argparse import * tests
04649 # ============================
04650 
04651 class TestImportStar(TestCase):
04652 
04653     def test(self):
04654         for name in argparse.__all__:
04655             self.assertTrue(hasattr(argparse, name))
04656 
04657     def test_all_exports_everything_but_modules(self):
04658         items = [
04659             name
04660             for name, value in vars(argparse).items()
04661             if not (name.startswith("_") or name == 'ngettext')
04662             if not inspect.ismodule(value)
04663         ]
04664         self.assertEqual(sorted(items), sorted(argparse.__all__))
04665 
04666 def test_main():
04667     # silence warnings about version argument - these are expected
04668     with support.check_warnings(
04669             ('The "version" argument to ArgumentParser is deprecated.',
04670              DeprecationWarning),
04671             ('The (format|print)_version method is deprecated',
04672              DeprecationWarning)):
04673         support.run_unittest(__name__)
04674     # Remove global references to avoid looking like we have refleaks.
04675     RFile.seen = {}
04676     WFile.seen = set()
04677 
04678 
04679 
04680 if __name__ == '__main__':
04681     test_main()