1 # Author: Steven J. Bethard <steven.bethard@gmail.com>.
14 from StringIO
import StringIO
16 class StdIOBuffer(StringIO
):
19 from test
import test_support
21 class TestCase(unittest
.TestCase
):
23 def assertEqual(self
, obj1
, obj2
):
30 super(TestCase
, self
).assertEqual(obj1
, obj2
)
33 # The tests assume that line wrapping occurs at 80 columns, but this
34 # behaviour can be overridden by setting the COLUMNS environment
35 # variable. To ensure that this assumption is true, unset COLUMNS.
36 env
= test_support
.EnvironmentVarGuard()
38 self
.addCleanup(env
.__exit
__)
41 class TempDirMixin(object):
44 self
.temp_dir
= tempfile
.mkdtemp()
45 self
.old_dir
= os
.getcwd()
46 os
.chdir(self
.temp_dir
)
49 os
.chdir(self
.old_dir
)
50 shutil
.rmtree(self
.temp_dir
, True)
52 def create_readonly_file(self
, filename
):
53 file_path
= os
.path
.join(self
.temp_dir
, filename
)
54 with
open(file_path
, 'w') as file:
56 os
.chmod(file_path
, stat
.S_IREAD
)
60 def __init__(self
, *args
, **kwargs
):
67 def __init__(self
, **kwargs
):
68 self
.__dict
__.update(kwargs
)
71 sorted_items
= sorted(self
.__dict
__.items())
72 kwarg_str
= ', '.join(['%s=%r' % tup
for tup
in sorted_items
])
73 return '%s(%s)' % (type(self
).__name
__, kwarg_str
)
77 def __eq__(self
, other
):
78 return vars(self
) == vars(other
)
80 def __ne__(self
, other
):
81 return not (self
== other
)
84 class ArgumentParserError(Exception):
86 def __init__(self
, message
, stdout
=None, stderr
=None, error_code
=None):
87 Exception.__init
__(self
, message
, stdout
, stderr
)
88 self
.message
= message
91 self
.error_code
= error_code
94 def stderr_to_parser_error(parse_args
, *args
, **kwargs
):
95 # if this is being called recursively and stderr or stdout is already being
96 # redirected, simply call the function and let the enclosing function
98 if isinstance(sys
.stderr
, StdIOBuffer
) or isinstance(sys
.stdout
, StdIOBuffer
):
99 return parse_args(*args
, **kwargs
)
101 # if this is not being called recursively, redirect stderr and
102 # use it as the ArgumentParserError message
103 old_stdout
= sys
.stdout
104 old_stderr
= sys
.stderr
105 sys
.stdout
= StdIOBuffer()
106 sys
.stderr
= StdIOBuffer()
109 result
= parse_args(*args
, **kwargs
)
110 for key
in list(vars(result
)):
111 if getattr(result
, key
) is sys
.stdout
:
112 setattr(result
, key
, old_stdout
)
113 if getattr(result
, key
) is sys
.stderr
:
114 setattr(result
, key
, old_stderr
)
117 code
= sys
.exc_info()[1].code
118 stdout
= sys
.stdout
.getvalue()
119 stderr
= sys
.stderr
.getvalue()
120 raise ArgumentParserError("SystemExit", stdout
, stderr
, code
)
122 sys
.stdout
= old_stdout
123 sys
.stderr
= old_stderr
126 class ErrorRaisingArgumentParser(argparse
.ArgumentParser
):
128 def parse_args(self
, *args
, **kwargs
):
129 parse_args
= super(ErrorRaisingArgumentParser
, self
).parse_args
130 return stderr_to_parser_error(parse_args
, *args
, **kwargs
)
132 def exit(self
, *args
, **kwargs
):
133 exit
= super(ErrorRaisingArgumentParser
, self
).exit
134 return stderr_to_parser_error(exit
, *args
, **kwargs
)
136 def error(self
, *args
, **kwargs
):
137 error
= super(ErrorRaisingArgumentParser
, self
).error
138 return stderr_to_parser_error(error
, *args
, **kwargs
)
141 class ParserTesterMetaclass(type):
142 """Adds parser tests using the class attributes.
144 Classes of this type should specify the following attributes:
146 argument_signatures -- a list of Sig objects which specify
147 the signatures of Argument objects to be created
148 failures -- a list of args lists that should cause the parser
150 successes -- a list of (initial_args, options, remaining_args) tuples
151 where initial_args specifies the string args to be parsed,
152 options is a dict that should match the vars() of the options
153 parsed out of initial_args, and remaining_args should be any
154 remaining unparsed arguments
157 def __init__(cls
, name
, bases
, bodydict
):
158 if name
== 'ParserTestCase':
161 # default parser signature is empty
162 if not hasattr(cls
, 'parser_signature'):
163 cls
.parser_signature
= Sig()
164 if not hasattr(cls
, 'parser_class'):
165 cls
.parser_class
= ErrorRaisingArgumentParser
167 # ---------------------------------------
168 # functions for adding optional arguments
169 # ---------------------------------------
170 def no_groups(parser
, argument_signatures
):
171 """Add all arguments directly to the parser"""
172 for sig
in argument_signatures
:
173 parser
.add_argument(*sig
.args
, **sig
.kwargs
)
175 def one_group(parser
, argument_signatures
):
176 """Add all arguments under a single group in the parser"""
177 group
= parser
.add_argument_group('foo')
178 for sig
in argument_signatures
:
179 group
.add_argument(*sig
.args
, **sig
.kwargs
)
181 def many_groups(parser
, argument_signatures
):
182 """Add each argument in its own group to the parser"""
183 for i
, sig
in enumerate(argument_signatures
):
184 group
= parser
.add_argument_group('foo:%i' % i
)
185 group
.add_argument(*sig
.args
, **sig
.kwargs
)
187 # --------------------------
188 # functions for parsing args
189 # --------------------------
190 def listargs(parser
, args
):
191 """Parse the args by passing in a list"""
192 return parser
.parse_args(args
)
194 def sysargs(parser
, args
):
195 """Parse the args by defaulting to sys.argv"""
196 old_sys_argv
= sys
.argv
197 sys
.argv
= [old_sys_argv
[0]] + args
199 return parser
.parse_args()
201 sys
.argv
= old_sys_argv
203 # class that holds the combination of one optional argument
204 # addition method and one arg parsing method
205 class AddTests(object):
207 def __init__(self
, tester_cls
, add_arguments
, parse_args
):
208 self
._add
_arguments
= add_arguments
209 self
._parse
_args
= parse_args
211 add_arguments_name
= self
._add
_arguments
.__name
__
212 parse_args_name
= self
._parse
_args
.__name
__
213 for test_func
in [self
.test_failures
, self
.test_successes
]:
214 func_name
= test_func
.__name
__
215 names
= func_name
, add_arguments_name
, parse_args_name
216 test_name
= '_'.join(names
)
218 def wrapper(self
, test_func
=test_func
):
221 wrapper
.__name
__ = test_name
224 setattr(tester_cls
, test_name
, wrapper
)
226 def _get_parser(self
, tester
):
227 args
= tester
.parser_signature
.args
228 kwargs
= tester
.parser_signature
.kwargs
229 parser
= tester
.parser_class(*args
, **kwargs
)
230 self
._add
_arguments
(parser
, tester
.argument_signatures
)
233 def test_failures(self
, tester
):
234 parser
= self
._get
_parser
(tester
)
235 for args_str
in tester
.failures
:
236 args
= args_str
.split()
237 raises
= tester
.assertRaises
238 raises(ArgumentParserError
, parser
.parse_args
, args
)
240 def test_successes(self
, tester
):
241 parser
= self
._get
_parser
(tester
)
242 for args
, expected_ns
in tester
.successes
:
243 if isinstance(args
, str):
245 result_ns
= self
._parse
_args
(parser
, args
)
246 tester
.assertEqual(expected_ns
, result_ns
)
248 # add tests for each combination of an optionals adding method
249 # and an arg parsing method
250 for add_arguments
in [no_groups
, one_group
, many_groups
]:
251 for parse_args
in [listargs
, sysargs
]:
252 AddTests(cls
, add_arguments
, parse_args
)
255 ParserTestCase
= ParserTesterMetaclass('ParserTestCase', bases
, {})
261 class TestOptionalsSingleDash(ParserTestCase
):
262 """Test an Optional with a single-dash option string"""
264 argument_signatures
= [Sig('-x')]
265 failures
= ['-x', 'a', '--foo', '-x --foo', '-x -y']
270 ('-x -1', NS(x
='-1')),
271 ('-x-1', NS(x
='-1')),
275 class TestOptionalsSingleDashCombined(ParserTestCase
):
276 """Test an Optional with a single-dash option string"""
278 argument_signatures
= [
279 Sig('-x', action
='store_true'),
280 Sig('-yyy', action
='store_const', const
=42),
283 failures
= ['a', '--foo', '-xa', '-x --foo', '-x -z', '-z -x',
284 '-yx', '-yz a', '-yyyx', '-yyyza', '-xyza']
286 ('', NS(x
=False, yyy
=None, z
=None)),
287 ('-x', NS(x
=True, yyy
=None, z
=None)),
288 ('-za', NS(x
=False, yyy
=None, z
='a')),
289 ('-z a', NS(x
=False, yyy
=None, z
='a')),
290 ('-xza', NS(x
=True, yyy
=None, z
='a')),
291 ('-xz a', NS(x
=True, yyy
=None, z
='a')),
292 ('-x -za', NS(x
=True, yyy
=None, z
='a')),
293 ('-x -z a', NS(x
=True, yyy
=None, z
='a')),
294 ('-y', NS(x
=False, yyy
=42, z
=None)),
295 ('-yyy', NS(x
=False, yyy
=42, z
=None)),
296 ('-x -yyy -za', NS(x
=True, yyy
=42, z
='a')),
297 ('-x -yyy -z a', NS(x
=True, yyy
=42, z
='a')),
301 class TestOptionalsSingleDashLong(ParserTestCase
):
302 """Test an Optional with a multi-character single-dash option string"""
304 argument_signatures
= [Sig('-foo')]
305 failures
= ['-foo', 'a', '--foo', '-foo --foo', '-foo -y', '-fooa']
308 ('-foo a', NS(foo
='a')),
309 ('-foo -1', NS(foo
='-1')),
310 ('-fo a', NS(foo
='a')),
311 ('-f a', NS(foo
='a')),
315 class TestOptionalsSingleDashSubsetAmbiguous(ParserTestCase
):
316 """Test Optionals where option strings are subsets of each other"""
318 argument_signatures
= [Sig('-f'), Sig('-foobar'), Sig('-foorab')]
319 failures
= ['-f', '-foo', '-fo', '-foo b', '-foob', '-fooba', '-foora']
321 ('', NS(f
=None, foobar
=None, foorab
=None)),
322 ('-f a', NS(f
='a', foobar
=None, foorab
=None)),
323 ('-fa', NS(f
='a', foobar
=None, foorab
=None)),
324 ('-foa', NS(f
='oa', foobar
=None, foorab
=None)),
325 ('-fooa', NS(f
='ooa', foobar
=None, foorab
=None)),
326 ('-foobar a', NS(f
=None, foobar
='a', foorab
=None)),
327 ('-foorab a', NS(f
=None, foobar
=None, foorab
='a')),
331 class TestOptionalsSingleDashAmbiguous(ParserTestCase
):
332 """Test Optionals that partially match but are not subsets"""
334 argument_signatures
= [Sig('-foobar'), Sig('-foorab')]
335 failures
= ['-f', '-f a', '-fa', '-foa', '-foo', '-fo', '-foo b']
337 ('', NS(foobar
=None, foorab
=None)),
338 ('-foob a', NS(foobar
='a', foorab
=None)),
339 ('-foor a', NS(foobar
=None, foorab
='a')),
340 ('-fooba a', NS(foobar
='a', foorab
=None)),
341 ('-foora a', NS(foobar
=None, foorab
='a')),
342 ('-foobar a', NS(foobar
='a', foorab
=None)),
343 ('-foorab a', NS(foobar
=None, foorab
='a')),
347 class TestOptionalsNumeric(ParserTestCase
):
348 """Test an Optional with a short opt string"""
350 argument_signatures
= [Sig('-1', dest
='one')]
351 failures
= ['-1', 'a', '-1 --foo', '-1 -y', '-1 -1', '-1 -2']
354 ('-1 a', NS(one
='a')),
355 ('-1a', NS(one
='a')),
356 ('-1-2', NS(one
='-2')),
360 class TestOptionalsDoubleDash(ParserTestCase
):
361 """Test an Optional with a double-dash option string"""
363 argument_signatures
= [Sig('--foo')]
364 failures
= ['--foo', '-f', '-f a', 'a', '--foo -x', '--foo --bar']
367 ('--foo a', NS(foo
='a')),
368 ('--foo=a', NS(foo
='a')),
369 ('--foo -2.5', NS(foo
='-2.5')),
370 ('--foo=-2.5', NS(foo
='-2.5')),
374 class TestOptionalsDoubleDashPartialMatch(ParserTestCase
):
375 """Tests partial matching with a double-dash option string"""
377 argument_signatures
= [
378 Sig('--badger', action
='store_true'),
381 failures
= ['--bar', '--b', '--ba', '--b=2', '--ba=4', '--badge 5']
383 ('', NS(badger
=False, bat
=None)),
384 ('--bat X', NS(badger
=False, bat
='X')),
385 ('--bad', NS(badger
=True, bat
=None)),
386 ('--badg', NS(badger
=True, bat
=None)),
387 ('--badge', NS(badger
=True, bat
=None)),
388 ('--badger', NS(badger
=True, bat
=None)),
392 class TestOptionalsDoubleDashPrefixMatch(ParserTestCase
):
393 """Tests when one double-dash option string is a prefix of another"""
395 argument_signatures
= [
396 Sig('--badger', action
='store_true'),
399 failures
= ['--bar', '--b', '--ba', '--b=2', '--badge 5']
401 ('', NS(badger
=False, ba
=None)),
402 ('--ba X', NS(badger
=False, ba
='X')),
403 ('--ba=X', NS(badger
=False, ba
='X')),
404 ('--bad', NS(badger
=True, ba
=None)),
405 ('--badg', NS(badger
=True, ba
=None)),
406 ('--badge', NS(badger
=True, ba
=None)),
407 ('--badger', NS(badger
=True, ba
=None)),
411 class TestOptionalsSingleDoubleDash(ParserTestCase
):
412 """Test an Optional with single- and double-dash option strings"""
414 argument_signatures
= [
415 Sig('-f', action
='store_true'),
417 Sig('-baz', action
='store_const', const
=42),
419 failures
= ['--bar', '-fbar', '-fbaz', '-bazf', '-b B', 'B']
421 ('', NS(f
=False, bar
=None, baz
=None)),
422 ('-f', NS(f
=True, bar
=None, baz
=None)),
423 ('--ba B', NS(f
=False, bar
='B', baz
=None)),
424 ('-f --bar B', NS(f
=True, bar
='B', baz
=None)),
425 ('-f -b', NS(f
=True, bar
=None, baz
=42)),
426 ('-ba -f', NS(f
=True, bar
=None, baz
=42)),
430 class TestOptionalsAlternatePrefixChars(ParserTestCase
):
431 """Test an Optional with option strings with custom prefixes"""
433 parser_signature
= Sig(prefix_chars
='+:/', add_help
=False)
434 argument_signatures
= [
435 Sig('+f', action
='store_true'),
437 Sig('/baz', action
='store_const', const
=42),
439 failures
= ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz', '-h', '--help', '+h', '::help', '/help']
441 ('', NS(f
=False, bar
=None, baz
=None)),
442 ('+f', NS(f
=True, bar
=None, baz
=None)),
443 ('::ba B', NS(f
=False, bar
='B', baz
=None)),
444 ('+f ::bar B', NS(f
=True, bar
='B', baz
=None)),
445 ('+f /b', NS(f
=True, bar
=None, baz
=42)),
446 ('/ba +f', NS(f
=True, bar
=None, baz
=42)),
450 class TestOptionalsAlternatePrefixCharsAddedHelp(ParserTestCase
):
451 """When ``-`` not in prefix_chars, default operators created for help
452 should use the prefix_chars in use rather than - or --
453 http://bugs.python.org/issue9444"""
455 parser_signature
= Sig(prefix_chars
='+:/', add_help
=True)
456 argument_signatures
= [
457 Sig('+f', action
='store_true'),
459 Sig('/baz', action
='store_const', const
=42),
461 failures
= ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz']
463 ('', NS(f
=False, bar
=None, baz
=None)),
464 ('+f', NS(f
=True, bar
=None, baz
=None)),
465 ('::ba B', NS(f
=False, bar
='B', baz
=None)),
466 ('+f ::bar B', NS(f
=True, bar
='B', baz
=None)),
467 ('+f /b', NS(f
=True, bar
=None, baz
=42)),
468 ('/ba +f', NS(f
=True, bar
=None, baz
=42))
472 class TestOptionalsAlternatePrefixCharsMultipleShortArgs(ParserTestCase
):
473 """Verify that Optionals must be called with their defined prefixes"""
475 parser_signature
= Sig(prefix_chars
='+-', add_help
=False)
476 argument_signatures
= [
477 Sig('-x', action
='store_true'),
478 Sig('+y', action
='store_true'),
479 Sig('+z', action
='store_true'),
488 ('', NS(x
=False, y
=False, z
=False)),
489 ('-x', NS(x
=True, y
=False, z
=False)),
490 ('+y -x', NS(x
=True, y
=True, z
=False)),
491 ('+yz -x', NS(x
=True, y
=True, z
=True)),
495 class TestOptionalsShortLong(ParserTestCase
):
496 """Test a combination of single- and double-dash option strings"""
498 argument_signatures
= [
499 Sig('-v', '--verbose', '-n', '--noisy', action
='store_true'),
501 failures
= ['--x --verbose', '-N', 'a', '-v x']
503 ('', NS(verbose
=False)),
504 ('-v', NS(verbose
=True)),
505 ('--verbose', NS(verbose
=True)),
506 ('-n', NS(verbose
=True)),
507 ('--noisy', NS(verbose
=True)),
511 class TestOptionalsDest(ParserTestCase
):
512 """Tests various means of setting destination"""
514 argument_signatures
= [Sig('--foo-bar'), Sig('--baz', dest
='zabbaz')]
517 ('--foo-bar f', NS(foo_bar
='f', zabbaz
=None)),
518 ('--baz g', NS(foo_bar
=None, zabbaz
='g')),
519 ('--foo-bar h --baz i', NS(foo_bar
='h', zabbaz
='i')),
520 ('--baz j --foo-bar k', NS(foo_bar
='k', zabbaz
='j')),
524 class TestOptionalsDefault(ParserTestCase
):
525 """Tests specifying a default for an Optional"""
527 argument_signatures
= [Sig('-x'), Sig('-y', default
=42)]
530 ('', NS(x
=None, y
=42)),
531 ('-xx', NS(x
='x', y
=42)),
532 ('-yy', NS(x
=None, y
='y')),
536 class TestOptionalsNargsDefault(ParserTestCase
):
537 """Tests not specifying the number of args for an Optional"""
539 argument_signatures
= [Sig('-x')]
540 failures
= ['a', '-x']
547 class TestOptionalsNargs1(ParserTestCase
):
548 """Tests specifying the 1 arg for an Optional"""
550 argument_signatures
= [Sig('-x', nargs
=1)]
551 failures
= ['a', '-x']
554 ('-x a', NS(x
=['a'])),
558 class TestOptionalsNargs3(ParserTestCase
):
559 """Tests specifying the 3 args for an Optional"""
561 argument_signatures
= [Sig('-x', nargs
=3)]
562 failures
= ['a', '-x', '-x a', '-x a b', 'a -x', 'a -x b']
565 ('-x a b c', NS(x
=['a', 'b', 'c'])),
569 class TestOptionalsNargsOptional(ParserTestCase
):
570 """Tests specifying an Optional arg for an Optional"""
572 argument_signatures
= [
573 Sig('-w', nargs
='?'),
574 Sig('-x', nargs
='?', const
=42),
575 Sig('-y', nargs
='?', default
='spam'),
576 Sig('-z', nargs
='?', type=int, const
='42', default
='84'),
580 ('', NS(w
=None, x
=None, y
='spam', z
=84)),
581 ('-w', NS(w
=None, x
=None, y
='spam', z
=84)),
582 ('-w 2', NS(w
='2', x
=None, y
='spam', z
=84)),
583 ('-x', NS(w
=None, x
=42, y
='spam', z
=84)),
584 ('-x 2', NS(w
=None, x
='2', y
='spam', z
=84)),
585 ('-y', NS(w
=None, x
=None, y
=None, z
=84)),
586 ('-y 2', NS(w
=None, x
=None, y
='2', z
=84)),
587 ('-z', NS(w
=None, x
=None, y
='spam', z
=42)),
588 ('-z 2', NS(w
=None, x
=None, y
='spam', z
=2)),
592 class TestOptionalsNargsZeroOrMore(ParserTestCase
):
593 """Tests specifying an args for an Optional that accepts zero or more"""
595 argument_signatures
= [
596 Sig('-x', nargs
='*'),
597 Sig('-y', nargs
='*', default
='spam'),
601 ('', NS(x
=None, y
='spam')),
602 ('-x', NS(x
=[], y
='spam')),
603 ('-x a', NS(x
=['a'], y
='spam')),
604 ('-x a b', NS(x
=['a', 'b'], y
='spam')),
605 ('-y', NS(x
=None, y
=[])),
606 ('-y a', NS(x
=None, y
=['a'])),
607 ('-y a b', NS(x
=None, y
=['a', 'b'])),
611 class TestOptionalsNargsOneOrMore(ParserTestCase
):
612 """Tests specifying an args for an Optional that accepts one or more"""
614 argument_signatures
= [
615 Sig('-x', nargs
='+'),
616 Sig('-y', nargs
='+', default
='spam'),
618 failures
= ['a', '-x', '-y', 'a -x', 'a -y b']
620 ('', NS(x
=None, y
='spam')),
621 ('-x a', NS(x
=['a'], y
='spam')),
622 ('-x a b', NS(x
=['a', 'b'], y
='spam')),
623 ('-y a', NS(x
=None, y
=['a'])),
624 ('-y a b', NS(x
=None, y
=['a', 'b'])),
628 class TestOptionalsChoices(ParserTestCase
):
629 """Tests specifying the choices for an Optional"""
631 argument_signatures
= [
632 Sig('-f', choices
='abc'),
633 Sig('-g', type=int, choices
=range(5))]
634 failures
= ['a', '-f d', '-fad', '-ga', '-g 6']
636 ('', NS(f
=None, g
=None)),
637 ('-f a', NS(f
='a', g
=None)),
638 ('-f c', NS(f
='c', g
=None)),
639 ('-g 0', NS(f
=None, g
=0)),
640 ('-g 03', NS(f
=None, g
=3)),
641 ('-fb -g4', NS(f
='b', g
=4)),
645 class TestOptionalsRequired(ParserTestCase
):
646 """Tests the an optional action that is required"""
648 argument_signatures
= [
649 Sig('-x', type=int, required
=True),
658 class TestOptionalsActionStore(ParserTestCase
):
659 """Tests the store action for an Optional"""
661 argument_signatures
= [Sig('-x', action
='store')]
662 failures
= ['a', 'a -x']
665 ('-xfoo', NS(x
='foo')),
669 class TestOptionalsActionStoreConst(ParserTestCase
):
670 """Tests the store_const action for an Optional"""
672 argument_signatures
= [Sig('-y', action
='store_const', const
=object)]
676 ('-y', NS(y
=object)),
680 class TestOptionalsActionStoreFalse(ParserTestCase
):
681 """Tests the store_false action for an Optional"""
683 argument_signatures
= [Sig('-z', action
='store_false')]
684 failures
= ['a', '-za', '-z a']
691 class TestOptionalsActionStoreTrue(ParserTestCase
):
692 """Tests the store_true action for an Optional"""
694 argument_signatures
= [Sig('--apple', action
='store_true')]
695 failures
= ['a', '--apple=b', '--apple b']
697 ('', NS(apple
=False)),
698 ('--apple', NS(apple
=True)),
702 class TestOptionalsActionAppend(ParserTestCase
):
703 """Tests the append action for an Optional"""
705 argument_signatures
= [Sig('--baz', action
='append')]
706 failures
= ['a', '--baz', 'a --baz', '--baz a b']
709 ('--baz a', NS(baz
=['a'])),
710 ('--baz a --baz b', NS(baz
=['a', 'b'])),
714 class TestOptionalsActionAppendWithDefault(ParserTestCase
):
715 """Tests the append action for an Optional"""
717 argument_signatures
= [Sig('--baz', action
='append', default
=['X'])]
718 failures
= ['a', '--baz', 'a --baz', '--baz a b']
721 ('--baz a', NS(baz
=['X', 'a'])),
722 ('--baz a --baz b', NS(baz
=['X', 'a', 'b'])),
726 class TestOptionalsActionAppendConst(ParserTestCase
):
727 """Tests the append_const action for an Optional"""
729 argument_signatures
= [
730 Sig('-b', action
='append_const', const
=Exception),
731 Sig('-c', action
='append', dest
='b'),
733 failures
= ['a', '-c', 'a -c', '-bx', '-b x']
736 ('-b', NS(b
=[Exception])),
737 ('-b -cx -b -cyz', NS(b
=[Exception, 'x', Exception, 'yz'])),
741 class TestOptionalsActionAppendConstWithDefault(ParserTestCase
):
742 """Tests the append_const action for an Optional"""
744 argument_signatures
= [
745 Sig('-b', action
='append_const', const
=Exception, default
=['X']),
746 Sig('-c', action
='append', dest
='b'),
748 failures
= ['a', '-c', 'a -c', '-bx', '-b x']
751 ('-b', NS(b
=['X', Exception])),
752 ('-b -cx -b -cyz', NS(b
=['X', Exception, 'x', Exception, 'yz'])),
756 class TestOptionalsActionCount(ParserTestCase
):
757 """Tests the count action for an Optional"""
759 argument_signatures
= [Sig('-x', action
='count')]
760 failures
= ['a', '-x a', '-x b', '-x a -x b']
771 class TestPositionalsNargsNone(ParserTestCase
):
772 """Test a Positional that doesn't specify nargs"""
774 argument_signatures
= [Sig('foo')]
775 failures
= ['', '-x', 'a b']
781 class TestPositionalsNargs1(ParserTestCase
):
782 """Test a Positional that specifies an nargs of 1"""
784 argument_signatures
= [Sig('foo', nargs
=1)]
785 failures
= ['', '-x', 'a b']
787 ('a', NS(foo
=['a'])),
791 class TestPositionalsNargs2(ParserTestCase
):
792 """Test a Positional that specifies an nargs of 2"""
794 argument_signatures
= [Sig('foo', nargs
=2)]
795 failures
= ['', 'a', '-x', 'a b c']
797 ('a b', NS(foo
=['a', 'b'])),
801 class TestPositionalsNargsZeroOrMore(ParserTestCase
):
802 """Test a Positional that specifies unlimited nargs"""
804 argument_signatures
= [Sig('foo', nargs
='*')]
808 ('a', NS(foo
=['a'])),
809 ('a b', NS(foo
=['a', 'b'])),
813 class TestPositionalsNargsZeroOrMoreDefault(ParserTestCase
):
814 """Test a Positional that specifies unlimited nargs and a default"""
816 argument_signatures
= [Sig('foo', nargs
='*', default
='bar')]
820 ('a', NS(foo
=['a'])),
821 ('a b', NS(foo
=['a', 'b'])),
825 class TestPositionalsNargsOneOrMore(ParserTestCase
):
826 """Test a Positional that specifies one or more nargs"""
828 argument_signatures
= [Sig('foo', nargs
='+')]
829 failures
= ['', '-x']
831 ('a', NS(foo
=['a'])),
832 ('a b', NS(foo
=['a', 'b'])),
836 class TestPositionalsNargsOptional(ParserTestCase
):
837 """Tests an Optional Positional"""
839 argument_signatures
= [Sig('foo', nargs
='?')]
840 failures
= ['-x', 'a b']
847 class TestPositionalsNargsOptionalDefault(ParserTestCase
):
848 """Tests an Optional Positional with a default value"""
850 argument_signatures
= [Sig('foo', nargs
='?', default
=42)]
851 failures
= ['-x', 'a b']
858 class TestPositionalsNargsOptionalConvertedDefault(ParserTestCase
):
859 """Tests an Optional Positional with a default value
860 that needs to be converted to the appropriate type.
863 argument_signatures
= [
864 Sig('foo', nargs
='?', type=int, default
='42'),
866 failures
= ['-x', 'a b', '1 2']
873 class TestPositionalsNargsNoneNone(ParserTestCase
):
874 """Test two Positionals that don't specify nargs"""
876 argument_signatures
= [Sig('foo'), Sig('bar')]
877 failures
= ['', '-x', 'a', 'a b c']
879 ('a b', NS(foo
='a', bar
='b')),
883 class TestPositionalsNargsNone1(ParserTestCase
):
884 """Test a Positional with no nargs followed by one with 1"""
886 argument_signatures
= [Sig('foo'), Sig('bar', nargs
=1)]
887 failures
= ['', '--foo', 'a', 'a b c']
889 ('a b', NS(foo
='a', bar
=['b'])),
893 class TestPositionalsNargs2None(ParserTestCase
):
894 """Test a Positional with 2 nargs followed by one with none"""
896 argument_signatures
= [Sig('foo', nargs
=2), Sig('bar')]
897 failures
= ['', '--foo', 'a', 'a b', 'a b c d']
899 ('a b c', NS(foo
=['a', 'b'], bar
='c')),
903 class TestPositionalsNargsNoneZeroOrMore(ParserTestCase
):
904 """Test a Positional with no nargs followed by one with unlimited"""
906 argument_signatures
= [Sig('foo'), Sig('bar', nargs
='*')]
907 failures
= ['', '--foo']
909 ('a', NS(foo
='a', bar
=[])),
910 ('a b', NS(foo
='a', bar
=['b'])),
911 ('a b c', NS(foo
='a', bar
=['b', 'c'])),
915 class TestPositionalsNargsNoneOneOrMore(ParserTestCase
):
916 """Test a Positional with no nargs followed by one with one or more"""
918 argument_signatures
= [Sig('foo'), Sig('bar', nargs
='+')]
919 failures
= ['', '--foo', 'a']
921 ('a b', NS(foo
='a', bar
=['b'])),
922 ('a b c', NS(foo
='a', bar
=['b', 'c'])),
926 class TestPositionalsNargsNoneOptional(ParserTestCase
):
927 """Test a Positional with no nargs followed by one with an Optional"""
929 argument_signatures
= [Sig('foo'), Sig('bar', nargs
='?')]
930 failures
= ['', '--foo', 'a b c']
932 ('a', NS(foo
='a', bar
=None)),
933 ('a b', NS(foo
='a', bar
='b')),
937 class TestPositionalsNargsZeroOrMoreNone(ParserTestCase
):
938 """Test a Positional with unlimited nargs followed by one with none"""
940 argument_signatures
= [Sig('foo', nargs
='*'), Sig('bar')]
941 failures
= ['', '--foo']
943 ('a', NS(foo
=[], bar
='a')),
944 ('a b', NS(foo
=['a'], bar
='b')),
945 ('a b c', NS(foo
=['a', 'b'], bar
='c')),
949 class TestPositionalsNargsOneOrMoreNone(ParserTestCase
):
950 """Test a Positional with one or more nargs followed by one with none"""
952 argument_signatures
= [Sig('foo', nargs
='+'), Sig('bar')]
953 failures
= ['', '--foo', 'a']
955 ('a b', NS(foo
=['a'], bar
='b')),
956 ('a b c', NS(foo
=['a', 'b'], bar
='c')),
960 class TestPositionalsNargsOptionalNone(ParserTestCase
):
961 """Test a Positional with an Optional nargs followed by one with none"""
963 argument_signatures
= [Sig('foo', nargs
='?', default
=42), Sig('bar')]
964 failures
= ['', '--foo', 'a b c']
966 ('a', NS(foo
=42, bar
='a')),
967 ('a b', NS(foo
='a', bar
='b')),
971 class TestPositionalsNargs2ZeroOrMore(ParserTestCase
):
972 """Test a Positional with 2 nargs followed by one with unlimited"""
974 argument_signatures
= [Sig('foo', nargs
=2), Sig('bar', nargs
='*')]
975 failures
= ['', '--foo', 'a']
977 ('a b', NS(foo
=['a', 'b'], bar
=[])),
978 ('a b c', NS(foo
=['a', 'b'], bar
=['c'])),
982 class TestPositionalsNargs2OneOrMore(ParserTestCase
):
983 """Test a Positional with 2 nargs followed by one with one or more"""
985 argument_signatures
= [Sig('foo', nargs
=2), Sig('bar', nargs
='+')]
986 failures
= ['', '--foo', 'a', 'a b']
988 ('a b c', NS(foo
=['a', 'b'], bar
=['c'])),
992 class TestPositionalsNargs2Optional(ParserTestCase
):
993 """Test a Positional with 2 nargs followed by one optional"""
995 argument_signatures
= [Sig('foo', nargs
=2), Sig('bar', nargs
='?')]
996 failures
= ['', '--foo', 'a', 'a b c d']
998 ('a b', NS(foo
=['a', 'b'], bar
=None)),
999 ('a b c', NS(foo
=['a', 'b'], bar
='c')),
1003 class TestPositionalsNargsZeroOrMore1(ParserTestCase
):
1004 """Test a Positional with unlimited nargs followed by one with 1"""
1006 argument_signatures
= [Sig('foo', nargs
='*'), Sig('bar', nargs
=1)]
1007 failures
= ['', '--foo', ]
1009 ('a', NS(foo
=[], bar
=['a'])),
1010 ('a b', NS(foo
=['a'], bar
=['b'])),
1011 ('a b c', NS(foo
=['a', 'b'], bar
=['c'])),
1015 class TestPositionalsNargsOneOrMore1(ParserTestCase
):
1016 """Test a Positional with one or more nargs followed by one with 1"""
1018 argument_signatures
= [Sig('foo', nargs
='+'), Sig('bar', nargs
=1)]
1019 failures
= ['', '--foo', 'a']
1021 ('a b', NS(foo
=['a'], bar
=['b'])),
1022 ('a b c', NS(foo
=['a', 'b'], bar
=['c'])),
1026 class TestPositionalsNargsOptional1(ParserTestCase
):
1027 """Test a Positional with an Optional nargs followed by one with 1"""
1029 argument_signatures
= [Sig('foo', nargs
='?'), Sig('bar', nargs
=1)]
1030 failures
= ['', '--foo', 'a b c']
1032 ('a', NS(foo
=None, bar
=['a'])),
1033 ('a b', NS(foo
='a', bar
=['b'])),
1037 class TestPositionalsNargsNoneZeroOrMore1(ParserTestCase
):
1038 """Test three Positionals: no nargs, unlimited nargs and 1 nargs"""
1040 argument_signatures
= [
1042 Sig('bar', nargs
='*'),
1043 Sig('baz', nargs
=1),
1045 failures
= ['', '--foo', 'a']
1047 ('a b', NS(foo
='a', bar
=[], baz
=['b'])),
1048 ('a b c', NS(foo
='a', bar
=['b'], baz
=['c'])),
1052 class TestPositionalsNargsNoneOneOrMore1(ParserTestCase
):
1053 """Test three Positionals: no nargs, one or more nargs and 1 nargs"""
1055 argument_signatures
= [
1057 Sig('bar', nargs
='+'),
1058 Sig('baz', nargs
=1),
1060 failures
= ['', '--foo', 'a', 'b']
1062 ('a b c', NS(foo
='a', bar
=['b'], baz
=['c'])),
1063 ('a b c d', NS(foo
='a', bar
=['b', 'c'], baz
=['d'])),
1067 class TestPositionalsNargsNoneOptional1(ParserTestCase
):
1068 """Test three Positionals: no nargs, optional narg and 1 nargs"""
1070 argument_signatures
= [
1072 Sig('bar', nargs
='?', default
=0.625),
1073 Sig('baz', nargs
=1),
1075 failures
= ['', '--foo', 'a']
1077 ('a b', NS(foo
='a', bar
=0.625, baz
=['b'])),
1078 ('a b c', NS(foo
='a', bar
='b', baz
=['c'])),
1082 class TestPositionalsNargsOptionalOptional(ParserTestCase
):
1083 """Test two optional nargs"""
1085 argument_signatures
= [
1086 Sig('foo', nargs
='?'),
1087 Sig('bar', nargs
='?', default
=42),
1089 failures
= ['--foo', 'a b c']
1091 ('', NS(foo
=None, bar
=42)),
1092 ('a', NS(foo
='a', bar
=42)),
1093 ('a b', NS(foo
='a', bar
='b')),
1097 class TestPositionalsNargsOptionalZeroOrMore(ParserTestCase
):
1098 """Test an Optional narg followed by unlimited nargs"""
1100 argument_signatures
= [Sig('foo', nargs
='?'), Sig('bar', nargs
='*')]
1101 failures
= ['--foo']
1103 ('', NS(foo
=None, bar
=[])),
1104 ('a', NS(foo
='a', bar
=[])),
1105 ('a b', NS(foo
='a', bar
=['b'])),
1106 ('a b c', NS(foo
='a', bar
=['b', 'c'])),
1110 class TestPositionalsNargsOptionalOneOrMore(ParserTestCase
):
1111 """Test an Optional narg followed by one or more nargs"""
1113 argument_signatures
= [Sig('foo', nargs
='?'), Sig('bar', nargs
='+')]
1114 failures
= ['', '--foo']
1116 ('a', NS(foo
=None, bar
=['a'])),
1117 ('a b', NS(foo
='a', bar
=['b'])),
1118 ('a b c', NS(foo
='a', bar
=['b', 'c'])),
1122 class TestPositionalsChoicesString(ParserTestCase
):
1123 """Test a set of single-character choices"""
1125 argument_signatures
= [Sig('spam', choices
=set('abcdefg'))]
1126 failures
= ['', '--foo', 'h', '42', 'ef']
1128 ('a', NS(spam
='a')),
1129 ('g', NS(spam
='g')),
1133 class TestPositionalsChoicesInt(ParserTestCase
):
1134 """Test a set of integer choices"""
1136 argument_signatures
= [Sig('spam', type=int, choices
=range(20))]
1137 failures
= ['', '--foo', 'h', '42', 'ef']
1140 ('15', NS(spam
=15)),
1144 class TestPositionalsActionAppend(ParserTestCase
):
1145 """Test the 'append' action"""
1147 argument_signatures
= [
1148 Sig('spam', action
='append'),
1149 Sig('spam', action
='append', nargs
=2),
1151 failures
= ['', '--foo', 'a', 'a b', 'a b c d']
1153 ('a b c', NS(spam
=['a', ['b', 'c']])),
1156 # ========================================
1157 # Combined optionals and positionals tests
1158 # ========================================
1160 class TestOptionalsNumericAndPositionals(ParserTestCase
):
1161 """Tests negative number args when numeric options are present"""
1163 argument_signatures
= [
1164 Sig('x', nargs
='?'),
1165 Sig('-4', dest
='y', action
='store_true'),
1167 failures
= ['-2', '-315']
1169 ('', NS(x
=None, y
=False)),
1170 ('a', NS(x
='a', y
=False)),
1171 ('-4', NS(x
=None, y
=True)),
1172 ('-4 a', NS(x
='a', y
=True)),
1176 class TestOptionalsAlmostNumericAndPositionals(ParserTestCase
):
1177 """Tests negative number args when almost numeric options are present"""
1179 argument_signatures
= [
1180 Sig('x', nargs
='?'),
1181 Sig('-k4', dest
='y', action
='store_true'),
1185 ('', NS(x
=None, y
=False)),
1186 ('-2', NS(x
='-2', y
=False)),
1187 ('a', NS(x
='a', y
=False)),
1188 ('-k4', NS(x
=None, y
=True)),
1189 ('-k4 a', NS(x
='a', y
=True)),
1193 class TestEmptyAndSpaceContainingArguments(ParserTestCase
):
1195 argument_signatures
= [
1196 Sig('x', nargs
='?'),
1197 Sig('-y', '--yyy', dest
='y'),
1201 ([''], NS(x
='', y
=None)),
1202 (['a badger'], NS(x
='a badger', y
=None)),
1203 (['-a badger'], NS(x
='-a badger', y
=None)),
1204 (['-y', ''], NS(x
=None, y
='')),
1205 (['-y', 'a badger'], NS(x
=None, y
='a badger')),
1206 (['-y', '-a badger'], NS(x
=None, y
='-a badger')),
1207 (['--yyy=a badger'], NS(x
=None, y
='a badger')),
1208 (['--yyy=-a badger'], NS(x
=None, y
='-a badger')),
1212 class TestPrefixCharacterOnlyArguments(ParserTestCase
):
1214 parser_signature
= Sig(prefix_chars
='-+')
1215 argument_signatures
= [
1216 Sig('-', dest
='x', nargs
='?', const
='badger'),
1217 Sig('+', dest
='y', type=int, default
=42),
1218 Sig('-+-', dest
='z', action
='store_true'),
1220 failures
= ['-y', '+ -']
1222 ('', NS(x
=None, y
=42, z
=False)),
1223 ('-', NS(x
='badger', y
=42, z
=False)),
1224 ('- X', NS(x
='X', y
=42, z
=False)),
1225 ('+ -3', NS(x
=None, y
=-3, z
=False)),
1226 ('-+-', NS(x
=None, y
=42, z
=True)),
1227 ('- ===', NS(x
='===', y
=42, z
=False)),
1231 class TestNargsZeroOrMore(ParserTestCase
):
1232 """Tests specifying an args for an Optional that accepts zero or more"""
1234 argument_signatures
= [Sig('-x', nargs
='*'), Sig('y', nargs
='*')]
1237 ('', NS(x
=None, y
=[])),
1238 ('-x', NS(x
=[], y
=[])),
1239 ('-x a', NS(x
=['a'], y
=[])),
1240 ('-x a -- b', NS(x
=['a'], y
=['b'])),
1241 ('a', NS(x
=None, y
=['a'])),
1242 ('a -x', NS(x
=[], y
=['a'])),
1243 ('a -x b', NS(x
=['b'], y
=['a'])),
1247 class TestNargsRemainder(ParserTestCase
):
1248 """Tests specifying a positional with nargs=REMAINDER"""
1250 argument_signatures
= [Sig('x'), Sig('y', nargs
='...'), Sig('-z')]
1251 failures
= ['', '-z', '-z Z']
1253 ('X', NS(x
='X', y
=[], z
=None)),
1254 ('-z Z X', NS(x
='X', y
=[], z
='Z')),
1255 ('X A B -z Z', NS(x
='X', y
=['A', 'B', '-z', 'Z'], z
=None)),
1256 ('X Y --foo', NS(x
='X', y
=['Y', '--foo'], z
=None)),
1260 class TestOptionLike(ParserTestCase
):
1261 """Tests options that may or may not be arguments"""
1263 argument_signatures
= [
1264 Sig('-x', type=float),
1265 Sig('-3', type=float, dest
='y'),
1266 Sig('z', nargs
='*'),
1268 failures
= ['-x', '-y2.5', '-xa', '-x -a',
1269 '-x -3', '-x -3.5', '-3 -3.5',
1270 '-x -2.5', '-x -2.5 a', '-3 -.5',
1271 'a x -1', '-x -1 a', '-3 -1 a']
1273 ('', NS(x
=None, y
=None, z
=[])),
1274 ('-x 2.5', NS(x
=2.5, y
=None, z
=[])),
1275 ('-x 2.5 a', NS(x
=2.5, y
=None, z
=['a'])),
1276 ('-3.5', NS(x
=None, y
=0.5, z
=[])),
1277 ('-3-.5', NS(x
=None, y
=-0.5, z
=[])),
1278 ('-3 .5', NS(x
=None, y
=0.5, z
=[])),
1279 ('a -3.5', NS(x
=None, y
=0.5, z
=['a'])),
1280 ('a', NS(x
=None, y
=None, z
=['a'])),
1281 ('a -x 1', NS(x
=1.0, y
=None, z
=['a'])),
1282 ('-x 1 a', NS(x
=1.0, y
=None, z
=['a'])),
1283 ('-3 1 a', NS(x
=None, y
=1.0, z
=['a'])),
1287 class TestDefaultSuppress(ParserTestCase
):
1288 """Test actions with suppressed defaults"""
1290 argument_signatures
= [
1291 Sig('foo', nargs
='?', default
=argparse
.SUPPRESS
),
1292 Sig('bar', nargs
='*', default
=argparse
.SUPPRESS
),
1293 Sig('--baz', action
='store_true', default
=argparse
.SUPPRESS
),
1299 ('a b', NS(foo
='a', bar
=['b'])),
1300 ('--baz', NS(baz
=True)),
1301 ('a --baz', NS(foo
='a', baz
=True)),
1302 ('--baz a b', NS(foo
='a', bar
=['b'], baz
=True)),
1306 class TestParserDefaultSuppress(ParserTestCase
):
1307 """Test actions with a parser-level default of SUPPRESS"""
1309 parser_signature
= Sig(argument_default
=argparse
.SUPPRESS
)
1310 argument_signatures
= [
1311 Sig('foo', nargs
='?'),
1312 Sig('bar', nargs
='*'),
1313 Sig('--baz', action
='store_true'),
1319 ('a b', NS(foo
='a', bar
=['b'])),
1320 ('--baz', NS(baz
=True)),
1321 ('a --baz', NS(foo
='a', baz
=True)),
1322 ('--baz a b', NS(foo
='a', bar
=['b'], baz
=True)),
1326 class TestParserDefault42(ParserTestCase
):
1327 """Test actions with a parser-level default of 42"""
1329 parser_signature
= Sig(argument_default
=42, version
='1.0')
1330 argument_signatures
= [
1331 Sig('foo', nargs
='?'),
1332 Sig('bar', nargs
='*'),
1333 Sig('--baz', action
='store_true'),
1337 ('', NS(foo
=42, bar
=42, baz
=42)),
1338 ('a', NS(foo
='a', bar
=42, baz
=42)),
1339 ('a b', NS(foo
='a', bar
=['b'], baz
=42)),
1340 ('--baz', NS(foo
=42, bar
=42, baz
=True)),
1341 ('a --baz', NS(foo
='a', bar
=42, baz
=True)),
1342 ('--baz a b', NS(foo
='a', bar
=['b'], baz
=True)),
1346 class TestArgumentsFromFile(TempDirMixin
, ParserTestCase
):
1347 """Test reading arguments from a file"""
1350 super(TestArgumentsFromFile
, self
).setUp()
1352 ('hello', 'hello world!\n'),
1353 ('recursive', '-a\n'
1356 ('invalid', '@no-such-path\n'),
1358 for path
, text
in file_texts
:
1359 file = open(path
, 'w')
1363 parser_signature
= Sig(fromfile_prefix_chars
='@')
1364 argument_signatures
= [
1367 Sig('y', nargs
='+'),
1369 failures
= ['', '-b', 'X', '@invalid', '@missing']
1371 ('X Y', NS(a
=None, x
='X', y
=['Y'])),
1372 ('X -a A Y Z', NS(a
='A', x
='X', y
=['Y', 'Z'])),
1373 ('@hello X', NS(a
=None, x
='hello world!', y
=['X'])),
1374 ('X @hello', NS(a
=None, x
='X', y
=['hello world!'])),
1375 ('-a B @recursive Y Z', NS(a
='A', x
='hello world!', y
=['Y', 'Z'])),
1376 ('X @recursive Z -a B', NS(a
='B', x
='X', y
=['hello world!', 'Z'])),
1380 class TestArgumentsFromFileConverter(TempDirMixin
, ParserTestCase
):
1381 """Test reading arguments from a file"""
1384 super(TestArgumentsFromFileConverter
, self
).setUp()
1386 ('hello', 'hello world!\n'),
1388 for path
, text
in file_texts
:
1389 file = open(path
, 'w')
1393 class FromFileConverterArgumentParser(ErrorRaisingArgumentParser
):
1395 def convert_arg_line_to_args(self
, arg_line
):
1396 for arg
in arg_line
.split():
1400 parser_class
= FromFileConverterArgumentParser
1401 parser_signature
= Sig(fromfile_prefix_chars
='@')
1402 argument_signatures
= [
1403 Sig('y', nargs
='+'),
1407 ('@hello X', NS(y
=['hello', 'world!', 'X'])),
1411 # =====================
1412 # Type conversion tests
1413 # =====================
1415 class TestFileTypeRepr(TestCase
):
1418 type = argparse
.FileType('r')
1419 self
.assertEqual("FileType('r')", repr(type))
1421 def test_wb_1(self
):
1422 type = argparse
.FileType('wb', 1)
1423 self
.assertEqual("FileType('wb', 1)", repr(type))
1426 class RFile(object):
1429 def __init__(self
, name
):
1434 def __eq__(self
, other
):
1435 if other
in self
.seen
:
1436 text
= self
.seen
[other
]
1438 text
= self
.seen
[other
] = other
.read()
1440 if not isinstance(text
, str):
1441 text
= text
.decode('ascii')
1442 return self
.name
== other
.name
== text
1445 class TestFileTypeR(TempDirMixin
, ParserTestCase
):
1446 """Test the FileType option/argument type for reading files"""
1449 super(TestFileTypeR
, self
).setUp()
1450 for file_name
in ['foo', 'bar']:
1451 file = open(os
.path
.join(self
.temp_dir
, file_name
), 'w')
1452 file.write(file_name
)
1454 self
.create_readonly_file('readonly')
1456 argument_signatures
= [
1457 Sig('-x', type=argparse
.FileType()),
1458 Sig('spam', type=argparse
.FileType('r')),
1460 failures
= ['-x', '-x bar', 'non-existent-file.txt']
1462 ('foo', NS(x
=None, spam
=RFile('foo'))),
1463 ('-x foo bar', NS(x
=RFile('foo'), spam
=RFile('bar'))),
1464 ('bar -x foo', NS(x
=RFile('foo'), spam
=RFile('bar'))),
1465 ('-x - -', NS(x
=sys
.stdin
, spam
=sys
.stdin
)),
1466 ('readonly', NS(x
=None, spam
=RFile('readonly'))),
1470 class TestFileTypeRB(TempDirMixin
, ParserTestCase
):
1471 """Test the FileType option/argument type for reading files"""
1474 super(TestFileTypeRB
, self
).setUp()
1475 for file_name
in ['foo', 'bar']:
1476 file = open(os
.path
.join(self
.temp_dir
, file_name
), 'w')
1477 file.write(file_name
)
1480 argument_signatures
= [
1481 Sig('-x', type=argparse
.FileType('rb')),
1482 Sig('spam', type=argparse
.FileType('rb')),
1484 failures
= ['-x', '-x bar']
1486 ('foo', NS(x
=None, spam
=RFile('foo'))),
1487 ('-x foo bar', NS(x
=RFile('foo'), spam
=RFile('bar'))),
1488 ('bar -x foo', NS(x
=RFile('foo'), spam
=RFile('bar'))),
1489 ('-x - -', NS(x
=sys
.stdin
, spam
=sys
.stdin
)),
1493 class WFile(object):
1496 def __init__(self
, name
):
1501 def __eq__(self
, other
):
1502 if other
not in self
.seen
:
1503 text
= 'Check that file is writable.'
1504 if 'b' in other
.mode
:
1505 text
= text
.encode('ascii')
1508 self
.seen
.add(other
)
1509 return self
.name
== other
.name
1512 class TestFileTypeW(TempDirMixin
, ParserTestCase
):
1513 """Test the FileType option/argument type for writing files"""
1516 super(TestFileTypeW
, self
).setUp()
1517 self
.create_readonly_file('readonly')
1519 argument_signatures
= [
1520 Sig('-x', type=argparse
.FileType('w')),
1521 Sig('spam', type=argparse
.FileType('w')),
1523 failures
= ['-x', '-x bar']
1524 failures
= ['-x', '-x bar', 'readonly']
1526 ('foo', NS(x
=None, spam
=WFile('foo'))),
1527 ('-x foo bar', NS(x
=WFile('foo'), spam
=WFile('bar'))),
1528 ('bar -x foo', NS(x
=WFile('foo'), spam
=WFile('bar'))),
1529 ('-x - -', NS(x
=sys
.stdout
, spam
=sys
.stdout
)),
1533 class TestFileTypeWB(TempDirMixin
, ParserTestCase
):
1535 argument_signatures
= [
1536 Sig('-x', type=argparse
.FileType('wb')),
1537 Sig('spam', type=argparse
.FileType('wb')),
1539 failures
= ['-x', '-x bar']
1541 ('foo', NS(x
=None, spam
=WFile('foo'))),
1542 ('-x foo bar', NS(x
=WFile('foo'), spam
=WFile('bar'))),
1543 ('bar -x foo', NS(x
=WFile('foo'), spam
=WFile('bar'))),
1544 ('-x - -', NS(x
=sys
.stdout
, spam
=sys
.stdout
)),
1548 class TestTypeCallable(ParserTestCase
):
1549 """Test some callables as option/argument types"""
1551 argument_signatures
= [
1552 Sig('--eggs', type=complex),
1553 Sig('spam', type=float),
1555 failures
= ['a', '42j', '--eggs a', '--eggs 2i']
1557 ('--eggs=42 42', NS(eggs
=42, spam
=42.0)),
1558 ('--eggs 2j -- -1.5', NS(eggs
=2j
, spam
=-1.5)),
1559 ('1024.675', NS(eggs
=None, spam
=1024.675)),
1563 class TestTypeUserDefined(ParserTestCase
):
1564 """Test a user-defined option/argument type"""
1566 class MyType(TestCase
):
1568 def __init__(self
, value
):
1573 def __eq__(self
, other
):
1574 return (type(self
), self
.value
) == (type(other
), other
.value
)
1576 argument_signatures
= [
1577 Sig('-x', type=MyType
),
1578 Sig('spam', type=MyType
),
1582 ('a -x b', NS(x
=MyType('b'), spam
=MyType('a'))),
1583 ('-xf g', NS(x
=MyType('f'), spam
=MyType('g'))),
1587 class TestTypeClassicClass(ParserTestCase
):
1588 """Test a classic class type"""
1592 def __init__(self
, value
):
1597 def __eq__(self
, other
):
1598 return (type(self
), self
.value
) == (type(other
), other
.value
)
1600 argument_signatures
= [
1602 Sig('spam', type=C
),
1606 ('a -x b', NS(x
=C('b'), spam
=C('a'))),
1607 ('-xf g', NS(x
=C('f'), spam
=C('g'))),
1611 class TestTypeRegistration(TestCase
):
1612 """Test a user-defined type by registering it"""
1616 def get_my_type(string
):
1617 return 'my_type{%s}' % string
1619 parser
= argparse
.ArgumentParser()
1620 parser
.register('type', 'my_type', get_my_type
)
1621 parser
.add_argument('-x', type='my_type')
1622 parser
.add_argument('y', type='my_type')
1624 self
.assertEqual(parser
.parse_args('1'.split()),
1625 NS(x
=None, y
='my_type{1}'))
1626 self
.assertEqual(parser
.parse_args('-x 1 42'.split()),
1627 NS(x
='my_type{1}', y
='my_type{42}'))
1634 class TestActionUserDefined(ParserTestCase
):
1635 """Test a user-defined option/argument action"""
1637 class OptionalAction(argparse
.Action
):
1639 def __call__(self
, parser
, namespace
, value
, option_string
=None):
1641 # check destination and option string
1642 assert self
.dest
== 'spam', 'dest: %s' % self
.dest
1643 assert option_string
== '-s', 'flag: %s' % option_string
1644 # when option is before argument, badger=2, and when
1645 # option is after argument, badger=<whatever was set>
1646 expected_ns
= NS(spam
=0.25)
1647 if value
in [0.125, 0.625]:
1648 expected_ns
.badger
= 2
1649 elif value
in [2.0]:
1650 expected_ns
.badger
= 84
1652 raise AssertionError('value: %s' % value
)
1653 assert expected_ns
== namespace
, ('expected %s, got %s' %
1654 (expected_ns
, namespace
))
1655 except AssertionError:
1656 e
= sys
.exc_info()[1]
1657 raise ArgumentParserError('opt_action failed: %s' % e
)
1658 setattr(namespace
, 'spam', value
)
1660 class PositionalAction(argparse
.Action
):
1662 def __call__(self
, parser
, namespace
, value
, option_string
=None):
1664 assert option_string
is None, ('option_string: %s' %
1667 assert self
.dest
== 'badger', 'dest: %s' % self
.dest
1668 # when argument is before option, spam=0.25, and when
1669 # option is after argument, spam=<whatever was set>
1670 expected_ns
= NS(badger
=2)
1671 if value
in [42, 84]:
1672 expected_ns
.spam
= 0.25
1674 expected_ns
.spam
= 0.625
1676 expected_ns
.spam
= 0.125
1678 raise AssertionError('value: %s' % value
)
1679 assert expected_ns
== namespace
, ('expected %s, got %s' %
1680 (expected_ns
, namespace
))
1681 except AssertionError:
1682 e
= sys
.exc_info()[1]
1683 raise ArgumentParserError('arg_action failed: %s' % e
)
1684 setattr(namespace
, 'badger', value
)
1686 argument_signatures
= [
1687 Sig('-s', dest
='spam', action
=OptionalAction
,
1688 type=float, default
=0.25),
1689 Sig('badger', action
=PositionalAction
,
1690 type=int, nargs
='?', default
=2),
1694 ('-s0.125', NS(spam
=0.125, badger
=2)),
1695 ('42', NS(spam
=0.25, badger
=42)),
1696 ('-s 0.625 1', NS(spam
=0.625, badger
=1)),
1697 ('84 -s2', NS(spam
=2.0, badger
=84)),
1701 class TestActionRegistration(TestCase
):
1702 """Test a user-defined action supplied by registering it"""
1704 class MyAction(argparse
.Action
):
1706 def __call__(self
, parser
, namespace
, values
, option_string
=None):
1707 setattr(namespace
, self
.dest
, 'foo[%s]' % values
)
1711 parser
= argparse
.ArgumentParser()
1712 parser
.register('action', 'my_action', self
.MyAction
)
1713 parser
.add_argument('badger', action
='my_action')
1715 self
.assertEqual(parser
.parse_args(['1']), NS(badger
='foo[1]'))
1716 self
.assertEqual(parser
.parse_args(['42']), NS(badger
='foo[42]'))
1723 class TestAddSubparsers(TestCase
):
1724 """Test the add_subparsers method"""
1726 def assertArgumentParserError(self
, *args
, **kwargs
):
1727 self
.assertRaises(ArgumentParserError
, *args
, **kwargs
)
1729 def _get_parser(self
, subparser_help
=False, prefix_chars
=None):
1730 # create a parser with a subparsers argument
1732 parser
= ErrorRaisingArgumentParser(
1733 prog
='PROG', description
='main description', prefix_chars
=prefix_chars
)
1734 parser
.add_argument(
1735 prefix_chars
[0] * 2 + 'foo', action
='store_true', help='foo help')
1737 parser
= ErrorRaisingArgumentParser(
1738 prog
='PROG', description
='main description')
1739 parser
.add_argument(
1740 '--foo', action
='store_true', help='foo help')
1741 parser
.add_argument(
1742 'bar', type=float, help='bar help')
1744 # check that only one subparsers argument can be added
1745 subparsers
= parser
.add_subparsers(help='command help')
1746 self
.assertArgumentParserError(parser
.add_subparsers
)
1748 # add first sub-parser
1749 parser1_kwargs
= dict(description
='1 description')
1751 parser1_kwargs
['help'] = '1 help'
1752 parser1
= subparsers
.add_parser('1', **parser1_kwargs
)
1753 parser1
.add_argument('-w', type=int, help='w help')
1754 parser1
.add_argument('x', choices
='abc', help='x help')
1756 # add second sub-parser
1757 parser2_kwargs
= dict(description
='2 description')
1759 parser2_kwargs
['help'] = '2 help'
1760 parser2
= subparsers
.add_parser('2', **parser2_kwargs
)
1761 parser2
.add_argument('-y', choices
='123', help='y help')
1762 parser2
.add_argument('z', type=complex, nargs
='*', help='z help')
1764 # return the main parser
1768 super(TestAddSubparsers
, self
).setUp()
1769 self
.parser
= self
._get
_parser
()
1770 self
.command_help_parser
= self
._get
_parser
(subparser_help
=True)
1772 def test_parse_args_failures(self
):
1773 # check some failure cases:
1774 for args_str
in ['', 'a', 'a a', '0.5 a', '0.5 1',
1775 '0.5 1 -y', '0.5 2 -w']:
1776 args
= args_str
.split()
1777 self
.assertArgumentParserError(self
.parser
.parse_args
, args
)
1779 def test_parse_args(self
):
1780 # check some non-failure cases:
1782 self
.parser
.parse_args('0.5 1 b -w 7'.split()),
1783 NS(foo
=False, bar
=0.5, w
=7, x
='b'),
1786 self
.parser
.parse_args('0.25 --foo 2 -y 2 3j -- -1j'.split()),
1787 NS(foo
=True, bar
=0.25, y
='2', z
=[3j
, -1j
]),
1790 self
.parser
.parse_args('--foo 0.125 1 c'.split()),
1791 NS(foo
=True, bar
=0.125, w
=None, x
='c'),
1794 def test_parse_known_args(self
):
1796 self
.parser
.parse_known_args('0.5 1 b -w 7'.split()),
1797 (NS(foo
=False, bar
=0.5, w
=7, x
='b'), []),
1800 self
.parser
.parse_known_args('0.5 -p 1 b -w 7'.split()),
1801 (NS(foo
=False, bar
=0.5, w
=7, x
='b'), ['-p']),
1804 self
.parser
.parse_known_args('0.5 1 b -w 7 -p'.split()),
1805 (NS(foo
=False, bar
=0.5, w
=7, x
='b'), ['-p']),
1808 self
.parser
.parse_known_args('0.5 1 b -q -rs -w 7'.split()),
1809 (NS(foo
=False, bar
=0.5, w
=7, x
='b'), ['-q', '-rs']),
1812 self
.parser
.parse_known_args('0.5 -W 1 b -X Y -w 7 Z'.split()),
1813 (NS(foo
=False, bar
=0.5, w
=7, x
='b'), ['-W', '-X', 'Y', 'Z']),
1816 def test_dest(self
):
1817 parser
= ErrorRaisingArgumentParser()
1818 parser
.add_argument('--foo', action
='store_true')
1819 subparsers
= parser
.add_subparsers(dest
='bar')
1820 parser1
= subparsers
.add_parser('1')
1821 parser1
.add_argument('baz')
1822 self
.assertEqual(NS(foo
=False, bar
='1', baz
='2'),
1823 parser
.parse_args('1 2'.split()))
1825 def test_help(self
):
1826 self
.assertEqual(self
.parser
.format_usage(),
1827 'usage: PROG [-h] [--foo] bar {1,2} ...\n')
1828 self
.assertEqual(self
.parser
.format_help(), textwrap
.dedent('''\
1829 usage: PROG [-h] [--foo] bar {1,2} ...
1833 positional arguments:
1838 -h, --help show this help message and exit
1842 def test_help_extra_prefix_chars(self
):
1843 # Make sure - is still used for help if it is a non-first prefix char
1844 parser
= self
._get
_parser
(prefix_chars
='+:-')
1845 self
.assertEqual(parser
.format_usage(),
1846 'usage: PROG [-h] [++foo] bar {1,2} ...\n')
1847 self
.assertEqual(parser
.format_help(), textwrap
.dedent('''\
1848 usage: PROG [-h] [++foo] bar {1,2} ...
1852 positional arguments:
1857 -h, --help show this help message and exit
1862 def test_help_alternate_prefix_chars(self
):
1863 parser
= self
._get
_parser
(prefix_chars
='+:/')
1864 self
.assertEqual(parser
.format_usage(),
1865 'usage: PROG [+h] [++foo] bar {1,2} ...\n')
1866 self
.assertEqual(parser
.format_help(), textwrap
.dedent('''\
1867 usage: PROG [+h] [++foo] bar {1,2} ...
1871 positional arguments:
1876 +h, ++help show this help message and exit
1880 def test_parser_command_help(self
):
1881 self
.assertEqual(self
.command_help_parser
.format_usage(),
1882 'usage: PROG [-h] [--foo] bar {1,2} ...\n')
1883 self
.assertEqual(self
.command_help_parser
.format_help(),
1884 textwrap
.dedent('''\
1885 usage: PROG [-h] [--foo] bar {1,2} ...
1889 positional arguments:
1896 -h, --help show this help message and exit
1900 def test_subparser_title_help(self
):
1901 parser
= ErrorRaisingArgumentParser(prog
='PROG',
1902 description
='main description')
1903 parser
.add_argument('--foo', action
='store_true', help='foo help')
1904 parser
.add_argument('bar', help='bar help')
1905 subparsers
= parser
.add_subparsers(title
='subcommands',
1906 description
='command help',
1907 help='additional text')
1908 parser1
= subparsers
.add_parser('1')
1909 parser2
= subparsers
.add_parser('2')
1910 self
.assertEqual(parser
.format_usage(),
1911 'usage: PROG [-h] [--foo] bar {1,2} ...\n')
1912 self
.assertEqual(parser
.format_help(), textwrap
.dedent('''\
1913 usage: PROG [-h] [--foo] bar {1,2} ...
1917 positional arguments:
1921 -h, --help show this help message and exit
1927 {1,2} additional text
1930 def _test_subparser_help(self
, args_str
, expected_help
):
1932 self
.parser
.parse_args(args_str
.split())
1933 except ArgumentParserError
:
1934 err
= sys
.exc_info()[1]
1935 if err
.stdout
!= expected_help
:
1936 print(repr(expected_help
))
1937 print(repr(err
.stdout
))
1938 self
.assertEqual(err
.stdout
, expected_help
)
1940 def test_subparser1_help(self
):
1941 self
._test
_subparser
_help
('5.0 1 -h', textwrap
.dedent('''\
1942 usage: PROG bar 1 [-h] [-w W] {a,b,c}
1946 positional arguments:
1950 -h, --help show this help message and exit
1954 def test_subparser2_help(self
):
1955 self
._test
_subparser
_help
('5.0 2 -h', textwrap
.dedent('''\
1956 usage: PROG bar 2 [-h] [-y {1,2,3}] [z [z ...]]
1960 positional arguments:
1964 -h, --help show this help message and exit
1972 class TestPositionalsGroups(TestCase
):
1973 """Tests that order of group positionals matches construction order"""
1975 def test_nongroup_first(self
):
1976 parser
= ErrorRaisingArgumentParser()
1977 parser
.add_argument('foo')
1978 group
= parser
.add_argument_group('g')
1979 group
.add_argument('bar')
1980 parser
.add_argument('baz')
1981 expected
= NS(foo
='1', bar
='2', baz
='3')
1982 result
= parser
.parse_args('1 2 3'.split())
1983 self
.assertEqual(expected
, result
)
1985 def test_group_first(self
):
1986 parser
= ErrorRaisingArgumentParser()
1987 group
= parser
.add_argument_group('xxx')
1988 group
.add_argument('foo')
1989 parser
.add_argument('bar')
1990 parser
.add_argument('baz')
1991 expected
= NS(foo
='1', bar
='2', baz
='3')
1992 result
= parser
.parse_args('1 2 3'.split())
1993 self
.assertEqual(expected
, result
)
1995 def test_interleaved_groups(self
):
1996 parser
= ErrorRaisingArgumentParser()
1997 group
= parser
.add_argument_group('xxx')
1998 parser
.add_argument('foo')
1999 group
.add_argument('bar')
2000 parser
.add_argument('baz')
2001 group
= parser
.add_argument_group('yyy')
2002 group
.add_argument('frell')
2003 expected
= NS(foo
='1', bar
='2', baz
='3', frell
='4')
2004 result
= parser
.parse_args('1 2 3 4'.split())
2005 self
.assertEqual(expected
, result
)
2007 # ===================
2008 # Parent parser tests
2009 # ===================
2011 class TestParentParsers(TestCase
):
2012 """Tests that parsers can be created with parent parsers"""
2014 def assertArgumentParserError(self
, *args
, **kwargs
):
2015 self
.assertRaises(ArgumentParserError
, *args
, **kwargs
)
2018 super(TestParentParsers
, self
).setUp()
2019 self
.wxyz_parent
= ErrorRaisingArgumentParser(add_help
=False)
2020 self
.wxyz_parent
.add_argument('--w')
2021 x_group
= self
.wxyz_parent
.add_argument_group('x')
2022 x_group
.add_argument('-y')
2023 self
.wxyz_parent
.add_argument('z')
2025 self
.abcd_parent
= ErrorRaisingArgumentParser(add_help
=False)
2026 self
.abcd_parent
.add_argument('a')
2027 self
.abcd_parent
.add_argument('-b')
2028 c_group
= self
.abcd_parent
.add_argument_group('c')
2029 c_group
.add_argument('--d')
2031 self
.w_parent
= ErrorRaisingArgumentParser(add_help
=False)
2032 self
.w_parent
.add_argument('--w')
2034 self
.z_parent
= ErrorRaisingArgumentParser(add_help
=False)
2035 self
.z_parent
.add_argument('z')
2037 # parents with mutually exclusive groups
2038 self
.ab_mutex_parent
= ErrorRaisingArgumentParser(add_help
=False)
2039 group
= self
.ab_mutex_parent
.add_mutually_exclusive_group()
2040 group
.add_argument('-a', action
='store_true')
2041 group
.add_argument('-b', action
='store_true')
2043 self
.main_program
= os
.path
.basename(sys
.argv
[0])
2045 def test_single_parent(self
):
2046 parser
= ErrorRaisingArgumentParser(parents
=[self
.wxyz_parent
])
2047 self
.assertEqual(parser
.parse_args('-y 1 2 --w 3'.split()),
2048 NS(w
='3', y
='1', z
='2'))
2050 def test_single_parent_mutex(self
):
2051 self
._test
_mutex
_ab
(self
.ab_mutex_parent
.parse_args
)
2052 parser
= ErrorRaisingArgumentParser(parents
=[self
.ab_mutex_parent
])
2053 self
._test
_mutex
_ab
(parser
.parse_args
)
2055 def test_single_granparent_mutex(self
):
2056 parents
= [self
.ab_mutex_parent
]
2057 parser
= ErrorRaisingArgumentParser(add_help
=False, parents
=parents
)
2058 parser
= ErrorRaisingArgumentParser(parents
=[parser
])
2059 self
._test
_mutex
_ab
(parser
.parse_args
)
2061 def _test_mutex_ab(self
, parse_args
):
2062 self
.assertEqual(parse_args([]), NS(a
=False, b
=False))
2063 self
.assertEqual(parse_args(['-a']), NS(a
=True, b
=False))
2064 self
.assertEqual(parse_args(['-b']), NS(a
=False, b
=True))
2065 self
.assertArgumentParserError(parse_args
, ['-a', '-b'])
2066 self
.assertArgumentParserError(parse_args
, ['-b', '-a'])
2067 self
.assertArgumentParserError(parse_args
, ['-c'])
2068 self
.assertArgumentParserError(parse_args
, ['-a', '-c'])
2069 self
.assertArgumentParserError(parse_args
, ['-b', '-c'])
2071 def test_multiple_parents(self
):
2072 parents
= [self
.abcd_parent
, self
.wxyz_parent
]
2073 parser
= ErrorRaisingArgumentParser(parents
=parents
)
2074 self
.assertEqual(parser
.parse_args('--d 1 --w 2 3 4'.split()),
2075 NS(a
='3', b
=None, d
='1', w
='2', y
=None, z
='4'))
2077 def test_multiple_parents_mutex(self
):
2078 parents
= [self
.ab_mutex_parent
, self
.wxyz_parent
]
2079 parser
= ErrorRaisingArgumentParser(parents
=parents
)
2080 self
.assertEqual(parser
.parse_args('-a --w 2 3'.split()),
2081 NS(a
=True, b
=False, w
='2', y
=None, z
='3'))
2082 self
.assertArgumentParserError(
2083 parser
.parse_args
, '-a --w 2 3 -b'.split())
2084 self
.assertArgumentParserError(
2085 parser
.parse_args
, '-a -b --w 2 3'.split())
2087 def test_conflicting_parents(self
):
2089 argparse
.ArgumentError
,
2090 argparse
.ArgumentParser
,
2091 parents
=[self
.w_parent
, self
.wxyz_parent
])
2093 def test_conflicting_parents_mutex(self
):
2095 argparse
.ArgumentError
,
2096 argparse
.ArgumentParser
,
2097 parents
=[self
.abcd_parent
, self
.ab_mutex_parent
])
2099 def test_same_argument_name_parents(self
):
2100 parents
= [self
.wxyz_parent
, self
.z_parent
]
2101 parser
= ErrorRaisingArgumentParser(parents
=parents
)
2102 self
.assertEqual(parser
.parse_args('1 2'.split()),
2103 NS(w
=None, y
=None, z
='2'))
2105 def test_subparser_parents(self
):
2106 parser
= ErrorRaisingArgumentParser()
2107 subparsers
= parser
.add_subparsers()
2108 abcde_parser
= subparsers
.add_parser('bar', parents
=[self
.abcd_parent
])
2109 abcde_parser
.add_argument('e')
2110 self
.assertEqual(parser
.parse_args('bar -b 1 --d 2 3 4'.split()),
2111 NS(a
='3', b
='1', d
='2', e
='4'))
2113 def test_subparser_parents_mutex(self
):
2114 parser
= ErrorRaisingArgumentParser()
2115 subparsers
= parser
.add_subparsers()
2116 parents
= [self
.ab_mutex_parent
]
2117 abc_parser
= subparsers
.add_parser('foo', parents
=parents
)
2118 c_group
= abc_parser
.add_argument_group('c_group')
2119 c_group
.add_argument('c')
2120 parents
= [self
.wxyz_parent
, self
.ab_mutex_parent
]
2121 wxyzabe_parser
= subparsers
.add_parser('bar', parents
=parents
)
2122 wxyzabe_parser
.add_argument('e')
2123 self
.assertEqual(parser
.parse_args('foo -a 4'.split()),
2124 NS(a
=True, b
=False, c
='4'))
2125 self
.assertEqual(parser
.parse_args('bar -b --w 2 3 4'.split()),
2126 NS(a
=False, b
=True, w
='2', y
=None, z
='3', e
='4'))
2127 self
.assertArgumentParserError(
2128 parser
.parse_args
, 'foo -a -b 4'.split())
2129 self
.assertArgumentParserError(
2130 parser
.parse_args
, 'bar -b -a 4'.split())
2132 def test_parent_help(self
):
2133 parents
= [self
.abcd_parent
, self
.wxyz_parent
]
2134 parser
= ErrorRaisingArgumentParser(parents
=parents
)
2135 parser_help
= parser
.format_help()
2136 self
.assertEqual(parser_help
, textwrap
.dedent('''\
2137 usage: {} [-h] [-b B] [--d D] [--w W] [-y Y] a z
2139 positional arguments:
2144 -h, --help show this help message and exit
2153 '''.format(self
.main_program
)))
2155 def test_groups_parents(self
):
2156 parent
= ErrorRaisingArgumentParser(add_help
=False)
2157 g
= parent
.add_argument_group(title
='g', description
='gd')
2158 g
.add_argument('-w')
2159 g
.add_argument('-x')
2160 m
= parent
.add_mutually_exclusive_group()
2161 m
.add_argument('-y')
2162 m
.add_argument('-z')
2163 parser
= ErrorRaisingArgumentParser(parents
=[parent
])
2165 self
.assertRaises(ArgumentParserError
, parser
.parse_args
,
2166 ['-y', 'Y', '-z', 'Z'])
2168 parser_help
= parser
.format_help()
2169 self
.assertEqual(parser_help
, textwrap
.dedent('''\
2170 usage: {} [-h] [-w W] [-x X] [-y Y | -z Z]
2173 -h, --help show this help message and exit
2182 '''.format(self
.main_program
)))
2184 # ==============================
2185 # Mutually exclusive group tests
2186 # ==============================
2188 class TestMutuallyExclusiveGroupErrors(TestCase
):
2190 def test_invalid_add_argument_group(self
):
2191 parser
= ErrorRaisingArgumentParser()
2192 raises
= self
.assertRaises
2193 raises(TypeError, parser
.add_mutually_exclusive_group
, title
='foo')
2195 def test_invalid_add_argument(self
):
2196 parser
= ErrorRaisingArgumentParser()
2197 group
= parser
.add_mutually_exclusive_group()
2198 add_argument
= group
.add_argument
2199 raises
= self
.assertRaises
2200 raises(ValueError, add_argument
, '--foo', required
=True)
2201 raises(ValueError, add_argument
, 'bar')
2202 raises(ValueError, add_argument
, 'bar', nargs
='+')
2203 raises(ValueError, add_argument
, 'bar', nargs
=1)
2204 raises(ValueError, add_argument
, 'bar', nargs
=argparse
.PARSER
)
2206 def test_help(self
):
2207 parser
= ErrorRaisingArgumentParser(prog
='PROG')
2208 group1
= parser
.add_mutually_exclusive_group()
2209 group1
.add_argument('--foo', action
='store_true')
2210 group1
.add_argument('--bar', action
='store_false')
2211 group2
= parser
.add_mutually_exclusive_group()
2212 group2
.add_argument('--soup', action
='store_true')
2213 group2
.add_argument('--nuts', action
='store_false')
2215 usage: PROG [-h] [--foo | --bar] [--soup | --nuts]
2218 -h, --help show this help message and exit
2224 self
.assertEqual(parser
.format_help(), textwrap
.dedent(expected
))
2226 class MEMixin(object):
2228 def test_failures_when_not_required(self
):
2229 parse_args
= self
.get_parser(required
=False).parse_args
2230 error
= ArgumentParserError
2231 for args_string
in self
.failures
:
2232 self
.assertRaises(error
, parse_args
, args_string
.split())
2234 def test_failures_when_required(self
):
2235 parse_args
= self
.get_parser(required
=True).parse_args
2236 error
= ArgumentParserError
2237 for args_string
in self
.failures
+ ['']:
2238 self
.assertRaises(error
, parse_args
, args_string
.split())
2240 def test_successes_when_not_required(self
):
2241 parse_args
= self
.get_parser(required
=False).parse_args
2242 successes
= self
.successes
+ self
.successes_when_not_required
2243 for args_string
, expected_ns
in successes
:
2244 actual_ns
= parse_args(args_string
.split())
2245 self
.assertEqual(actual_ns
, expected_ns
)
2247 def test_successes_when_required(self
):
2248 parse_args
= self
.get_parser(required
=True).parse_args
2249 for args_string
, expected_ns
in self
.successes
:
2250 actual_ns
= parse_args(args_string
.split())
2251 self
.assertEqual(actual_ns
, expected_ns
)
2253 def test_usage_when_not_required(self
):
2254 format_usage
= self
.get_parser(required
=False).format_usage
2255 expected_usage
= self
.usage_when_not_required
2256 self
.assertEqual(format_usage(), textwrap
.dedent(expected_usage
))
2258 def test_usage_when_required(self
):
2259 format_usage
= self
.get_parser(required
=True).format_usage
2260 expected_usage
= self
.usage_when_required
2261 self
.assertEqual(format_usage(), textwrap
.dedent(expected_usage
))
2263 def test_help_when_not_required(self
):
2264 format_help
= self
.get_parser(required
=False).format_help
2265 help = self
.usage_when_not_required
+ self
.help
2266 self
.assertEqual(format_help(), textwrap
.dedent(help))
2268 def test_help_when_required(self
):
2269 format_help
= self
.get_parser(required
=True).format_help
2270 help = self
.usage_when_required
+ self
.help
2271 self
.assertEqual(format_help(), textwrap
.dedent(help))
2274 class TestMutuallyExclusiveSimple(MEMixin
, TestCase
):
2276 def get_parser(self
, required
=None):
2277 parser
= ErrorRaisingArgumentParser(prog
='PROG')
2278 group
= parser
.add_mutually_exclusive_group(required
=required
)
2279 group
.add_argument('--bar', help='bar help')
2280 group
.add_argument('--baz', nargs
='?', const
='Z', help='baz help')
2283 failures
= ['--bar X --baz Y', '--bar X --baz']
2285 ('--bar X', NS(bar
='X', baz
=None)),
2286 ('--bar X --bar Z', NS(bar
='Z', baz
=None)),
2287 ('--baz Y', NS(bar
=None, baz
='Y')),
2288 ('--baz', NS(bar
=None, baz
='Z')),
2290 successes_when_not_required
= [
2291 ('', NS(bar
=None, baz
=None)),
2294 usage_when_not_required
= '''\
2295 usage: PROG [-h] [--bar BAR | --baz [BAZ]]
2297 usage_when_required
= '''\
2298 usage: PROG [-h] (--bar BAR | --baz [BAZ])
2303 -h, --help show this help message and exit
2305 --baz [BAZ] baz help
2309 class TestMutuallyExclusiveLong(MEMixin
, TestCase
):
2311 def get_parser(self
, required
=None):
2312 parser
= ErrorRaisingArgumentParser(prog
='PROG')
2313 parser
.add_argument('--abcde', help='abcde help')
2314 parser
.add_argument('--fghij', help='fghij help')
2315 group
= parser
.add_mutually_exclusive_group(required
=required
)
2316 group
.add_argument('--klmno', help='klmno help')
2317 group
.add_argument('--pqrst', help='pqrst help')
2320 failures
= ['--klmno X --pqrst Y']
2322 ('--klmno X', NS(abcde
=None, fghij
=None, klmno
='X', pqrst
=None)),
2323 ('--abcde Y --klmno X',
2324 NS(abcde
='Y', fghij
=None, klmno
='X', pqrst
=None)),
2325 ('--pqrst X', NS(abcde
=None, fghij
=None, klmno
=None, pqrst
='X')),
2326 ('--pqrst X --fghij Y',
2327 NS(abcde
=None, fghij
='Y', klmno
=None, pqrst
='X')),
2329 successes_when_not_required
= [
2330 ('', NS(abcde
=None, fghij
=None, klmno
=None, pqrst
=None)),
2333 usage_when_not_required
= '''\
2334 usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
2335 [--klmno KLMNO | --pqrst PQRST]
2337 usage_when_required
= '''\
2338 usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
2339 (--klmno KLMNO | --pqrst PQRST)
2344 -h, --help show this help message and exit
2345 --abcde ABCDE abcde help
2346 --fghij FGHIJ fghij help
2347 --klmno KLMNO klmno help
2348 --pqrst PQRST pqrst help
2352 class TestMutuallyExclusiveFirstSuppressed(MEMixin
, TestCase
):
2354 def get_parser(self
, required
):
2355 parser
= ErrorRaisingArgumentParser(prog
='PROG')
2356 group
= parser
.add_mutually_exclusive_group(required
=required
)
2357 group
.add_argument('-x', help=argparse
.SUPPRESS
)
2358 group
.add_argument('-y', action
='store_false', help='y help')
2361 failures
= ['-x X -y']
2363 ('-x X', NS(x
='X', y
=True)),
2364 ('-x X -x Y', NS(x
='Y', y
=True)),
2365 ('-y', NS(x
=None, y
=False)),
2367 successes_when_not_required
= [
2368 ('', NS(x
=None, y
=True)),
2371 usage_when_not_required
= '''\
2372 usage: PROG [-h] [-y]
2374 usage_when_required
= '''\
2380 -h, --help show this help message and exit
2385 class TestMutuallyExclusiveManySuppressed(MEMixin
, TestCase
):
2387 def get_parser(self
, required
):
2388 parser
= ErrorRaisingArgumentParser(prog
='PROG')
2389 group
= parser
.add_mutually_exclusive_group(required
=required
)
2390 add
= group
.add_argument
2391 add('--spam', action
='store_true', help=argparse
.SUPPRESS
)
2392 add('--badger', action
='store_false', help=argparse
.SUPPRESS
)
2393 add('--bladder', help=argparse
.SUPPRESS
)
2398 '--badger --bladder B',
2399 '--bladder B --spam',
2402 ('--spam', NS(spam
=True, badger
=True, bladder
=None)),
2403 ('--badger', NS(spam
=False, badger
=False, bladder
=None)),
2404 ('--bladder B', NS(spam
=False, badger
=True, bladder
='B')),
2405 ('--spam --spam', NS(spam
=True, badger
=True, bladder
=None)),
2407 successes_when_not_required
= [
2408 ('', NS(spam
=False, badger
=True, bladder
=None)),
2411 usage_when_required
= usage_when_not_required
= '''\
2417 -h, --help show this help message and exit
2421 class TestMutuallyExclusiveOptionalAndPositional(MEMixin
, TestCase
):
2423 def get_parser(self
, required
):
2424 parser
= ErrorRaisingArgumentParser(prog
='PROG')
2425 group
= parser
.add_mutually_exclusive_group(required
=required
)
2426 group
.add_argument('--foo', action
='store_true', help='FOO')
2427 group
.add_argument('--spam', help='SPAM')
2428 group
.add_argument('badger', nargs
='*', default
='X', help='BADGER')
2439 ('--foo', NS(foo
=True, spam
=None, badger
='X')),
2440 ('--spam S', NS(foo
=False, spam
='S', badger
='X')),
2441 ('X', NS(foo
=False, spam
=None, badger
=['X'])),
2442 ('X Y Z', NS(foo
=False, spam
=None, badger
=['X', 'Y', 'Z'])),
2444 successes_when_not_required
= [
2445 ('', NS(foo
=False, spam
=None, badger
='X')),
2448 usage_when_not_required
= '''\
2449 usage: PROG [-h] [--foo | --spam SPAM | badger [badger ...]]
2451 usage_when_required
= '''\
2452 usage: PROG [-h] (--foo | --spam SPAM | badger [badger ...])
2456 positional arguments:
2460 -h, --help show this help message and exit
2466 class TestMutuallyExclusiveOptionalsMixed(MEMixin
, TestCase
):
2468 def get_parser(self
, required
):
2469 parser
= ErrorRaisingArgumentParser(prog
='PROG')
2470 parser
.add_argument('-x', action
='store_true', help='x help')
2471 group
= parser
.add_mutually_exclusive_group(required
=required
)
2472 group
.add_argument('-a', action
='store_true', help='a help')
2473 group
.add_argument('-b', action
='store_true', help='b help')
2474 parser
.add_argument('-y', action
='store_true', help='y help')
2475 group
.add_argument('-c', action
='store_true', help='c help')
2478 failures
= ['-a -b', '-b -c', '-a -c', '-a -b -c']
2480 ('-a', NS(a
=True, b
=False, c
=False, x
=False, y
=False)),
2481 ('-b', NS(a
=False, b
=True, c
=False, x
=False, y
=False)),
2482 ('-c', NS(a
=False, b
=False, c
=True, x
=False, y
=False)),
2483 ('-a -x', NS(a
=True, b
=False, c
=False, x
=True, y
=False)),
2484 ('-y -b', NS(a
=False, b
=True, c
=False, x
=False, y
=True)),
2485 ('-x -y -c', NS(a
=False, b
=False, c
=True, x
=True, y
=True)),
2487 successes_when_not_required
= [
2488 ('', NS(a
=False, b
=False, c
=False, x
=False, y
=False)),
2489 ('-x', NS(a
=False, b
=False, c
=False, x
=True, y
=False)),
2490 ('-y', NS(a
=False, b
=False, c
=False, x
=False, y
=True)),
2493 usage_when_required
= usage_when_not_required
= '''\
2494 usage: PROG [-h] [-x] [-a] [-b] [-y] [-c]
2499 -h, --help show this help message and exit
2508 class TestMutuallyExclusiveInGroup(MEMixin
, TestCase
):
2510 def get_parser(self
, required
=None):
2511 parser
= ErrorRaisingArgumentParser(prog
='PROG')
2512 titled_group
= parser
.add_argument_group(
2513 title
='Titled group', description
='Group description')
2515 titled_group
.add_mutually_exclusive_group(required
=required
)
2516 mutex_group
.add_argument('--bar', help='bar help')
2517 mutex_group
.add_argument('--baz', help='baz help')
2520 failures
= ['--bar X --baz Y', '--baz X --bar Y']
2522 ('--bar X', NS(bar
='X', baz
=None)),
2523 ('--baz Y', NS(bar
=None, baz
='Y')),
2525 successes_when_not_required
= [
2526 ('', NS(bar
=None, baz
=None)),
2529 usage_when_not_required
= '''\
2530 usage: PROG [-h] [--bar BAR | --baz BAZ]
2532 usage_when_required
= '''\
2533 usage: PROG [-h] (--bar BAR | --baz BAZ)
2538 -h, --help show this help message and exit
2548 class TestMutuallyExclusiveOptionalsAndPositionalsMixed(MEMixin
, TestCase
):
2550 def get_parser(self
, required
):
2551 parser
= ErrorRaisingArgumentParser(prog
='PROG')
2552 parser
.add_argument('x', help='x help')
2553 parser
.add_argument('-y', action
='store_true', help='y help')
2554 group
= parser
.add_mutually_exclusive_group(required
=required
)
2555 group
.add_argument('a', nargs
='?', help='a help')
2556 group
.add_argument('-b', action
='store_true', help='b help')
2557 group
.add_argument('-c', action
='store_true', help='c help')
2560 failures
= ['X A -b', '-b -c', '-c X A']
2562 ('X A', NS(a
='A', b
=False, c
=False, x
='X', y
=False)),
2563 ('X -b', NS(a
=None, b
=True, c
=False, x
='X', y
=False)),
2564 ('X -c', NS(a
=None, b
=False, c
=True, x
='X', y
=False)),
2565 ('X A -y', NS(a
='A', b
=False, c
=False, x
='X', y
=True)),
2566 ('X -y -b', NS(a
=None, b
=True, c
=False, x
='X', y
=True)),
2568 successes_when_not_required
= [
2569 ('X', NS(a
=None, b
=False, c
=False, x
='X', y
=False)),
2570 ('X -y', NS(a
=None, b
=False, c
=False, x
='X', y
=True)),
2573 usage_when_required
= usage_when_not_required
= '''\
2574 usage: PROG [-h] [-y] [-b] [-c] x [a]
2578 positional arguments:
2583 -h, --help show this help message and exit
2589 # =================================================
2590 # Mutually exclusive group in parent parser tests
2591 # =================================================
2593 class MEPBase(object):
2595 def get_parser(self
, required
=None):
2596 parent
= super(MEPBase
, self
).get_parser(required
=required
)
2597 parser
= ErrorRaisingArgumentParser(
2598 prog
=parent
.prog
, add_help
=False, parents
=[parent
])
2602 class TestMutuallyExclusiveGroupErrorsParent(
2603 MEPBase
, TestMutuallyExclusiveGroupErrors
):
2607 class TestMutuallyExclusiveSimpleParent(
2608 MEPBase
, TestMutuallyExclusiveSimple
):
2612 class TestMutuallyExclusiveLongParent(
2613 MEPBase
, TestMutuallyExclusiveLong
):
2617 class TestMutuallyExclusiveFirstSuppressedParent(
2618 MEPBase
, TestMutuallyExclusiveFirstSuppressed
):
2622 class TestMutuallyExclusiveManySuppressedParent(
2623 MEPBase
, TestMutuallyExclusiveManySuppressed
):
2627 class TestMutuallyExclusiveOptionalAndPositionalParent(
2628 MEPBase
, TestMutuallyExclusiveOptionalAndPositional
):
2632 class TestMutuallyExclusiveOptionalsMixedParent(
2633 MEPBase
, TestMutuallyExclusiveOptionalsMixed
):
2637 class TestMutuallyExclusiveOptionalsAndPositionalsMixedParent(
2638 MEPBase
, TestMutuallyExclusiveOptionalsAndPositionalsMixed
):
2645 class TestSetDefaults(TestCase
):
2647 def test_set_defaults_no_args(self
):
2648 parser
= ErrorRaisingArgumentParser()
2649 parser
.set_defaults(x
='foo')
2650 parser
.set_defaults(y
='bar', z
=1)
2651 self
.assertEqual(NS(x
='foo', y
='bar', z
=1),
2652 parser
.parse_args([]))
2653 self
.assertEqual(NS(x
='foo', y
='bar', z
=1),
2654 parser
.parse_args([], NS()))
2655 self
.assertEqual(NS(x
='baz', y
='bar', z
=1),
2656 parser
.parse_args([], NS(x
='baz')))
2657 self
.assertEqual(NS(x
='baz', y
='bar', z
=2),
2658 parser
.parse_args([], NS(x
='baz', z
=2)))
2660 def test_set_defaults_with_args(self
):
2661 parser
= ErrorRaisingArgumentParser()
2662 parser
.set_defaults(x
='foo', y
='bar')
2663 parser
.add_argument('-x', default
='xfoox')
2664 self
.assertEqual(NS(x
='xfoox', y
='bar'),
2665 parser
.parse_args([]))
2666 self
.assertEqual(NS(x
='xfoox', y
='bar'),
2667 parser
.parse_args([], NS()))
2668 self
.assertEqual(NS(x
='baz', y
='bar'),
2669 parser
.parse_args([], NS(x
='baz')))
2670 self
.assertEqual(NS(x
='1', y
='bar'),
2671 parser
.parse_args('-x 1'.split()))
2672 self
.assertEqual(NS(x
='1', y
='bar'),
2673 parser
.parse_args('-x 1'.split(), NS()))
2674 self
.assertEqual(NS(x
='1', y
='bar'),
2675 parser
.parse_args('-x 1'.split(), NS(x
='baz')))
2677 def test_set_defaults_subparsers(self
):
2678 parser
= ErrorRaisingArgumentParser()
2679 parser
.set_defaults(x
='foo')
2680 subparsers
= parser
.add_subparsers()
2681 parser_a
= subparsers
.add_parser('a')
2682 parser_a
.set_defaults(y
='bar')
2683 self
.assertEqual(NS(x
='foo', y
='bar'),
2684 parser
.parse_args('a'.split()))
2686 def test_set_defaults_parents(self
):
2687 parent
= ErrorRaisingArgumentParser(add_help
=False)
2688 parent
.set_defaults(x
='foo')
2689 parser
= ErrorRaisingArgumentParser(parents
=[parent
])
2690 self
.assertEqual(NS(x
='foo'), parser
.parse_args([]))
2692 def test_set_defaults_same_as_add_argument(self
):
2693 parser
= ErrorRaisingArgumentParser()
2694 parser
.set_defaults(w
='W', x
='X', y
='Y', z
='Z')
2695 parser
.add_argument('-w')
2696 parser
.add_argument('-x', default
='XX')
2697 parser
.add_argument('y', nargs
='?')
2698 parser
.add_argument('z', nargs
='?', default
='ZZ')
2700 # defaults set previously
2701 self
.assertEqual(NS(w
='W', x
='XX', y
='Y', z
='ZZ'),
2702 parser
.parse_args([]))
2705 parser
.set_defaults(w
='WW', x
='X', y
='YY', z
='Z')
2706 self
.assertEqual(NS(w
='WW', x
='X', y
='YY', z
='Z'),
2707 parser
.parse_args([]))
2709 def test_set_defaults_same_as_add_argument_group(self
):
2710 parser
= ErrorRaisingArgumentParser()
2711 parser
.set_defaults(w
='W', x
='X', y
='Y', z
='Z')
2712 group
= parser
.add_argument_group('foo')
2713 group
.add_argument('-w')
2714 group
.add_argument('-x', default
='XX')
2715 group
.add_argument('y', nargs
='?')
2716 group
.add_argument('z', nargs
='?', default
='ZZ')
2719 # defaults set previously
2720 self
.assertEqual(NS(w
='W', x
='XX', y
='Y', z
='ZZ'),
2721 parser
.parse_args([]))
2724 parser
.set_defaults(w
='WW', x
='X', y
='YY', z
='Z')
2725 self
.assertEqual(NS(w
='WW', x
='X', y
='YY', z
='Z'),
2726 parser
.parse_args([]))
2732 class TestGetDefault(TestCase
):
2734 def test_get_default(self
):
2735 parser
= ErrorRaisingArgumentParser()
2736 self
.assertEqual(None, parser
.get_default("foo"))
2737 self
.assertEqual(None, parser
.get_default("bar"))
2739 parser
.add_argument("--foo")
2740 self
.assertEqual(None, parser
.get_default("foo"))
2741 self
.assertEqual(None, parser
.get_default("bar"))
2743 parser
.add_argument("--bar", type=int, default
=42)
2744 self
.assertEqual(None, parser
.get_default("foo"))
2745 self
.assertEqual(42, parser
.get_default("bar"))
2747 parser
.set_defaults(foo
="badger")
2748 self
.assertEqual("badger", parser
.get_default("foo"))
2749 self
.assertEqual(42, parser
.get_default("bar"))
2751 # ==========================
2752 # Namespace 'contains' tests
2753 # ==========================
2755 class TestNamespaceContainsSimple(TestCase
):
2757 def test_empty(self
):
2758 ns
= argparse
.Namespace()
2759 self
.assertEqual('' in ns
, False)
2760 self
.assertEqual('' not in ns
, True)
2761 self
.assertEqual('x' in ns
, False)
2763 def test_non_empty(self
):
2764 ns
= argparse
.Namespace(x
=1, y
=2)
2765 self
.assertEqual('x' in ns
, True)
2766 self
.assertEqual('x' not in ns
, False)
2767 self
.assertEqual('y' in ns
, True)
2768 self
.assertEqual('' in ns
, False)
2769 self
.assertEqual('xx' in ns
, False)
2770 self
.assertEqual('z' in ns
, False)
2772 # =====================
2773 # Help formatting tests
2774 # =====================
2776 class TestHelpFormattingMetaclass(type):
2778 def __init__(cls
, name
, bases
, bodydict
):
2779 if name
== 'HelpTestCase':
2782 class AddTests(object):
2784 def __init__(self
, test_class
, func_suffix
, std_name
):
2785 self
.func_suffix
= func_suffix
2786 self
.std_name
= std_name
2788 for test_func
in [self
.test_format
,
2790 self
.test_print_file
]:
2791 test_name
= '%s_%s' % (test_func
.__name
__, func_suffix
)
2793 def test_wrapper(self
, test_func
=test_func
):
2796 test_wrapper
.__name
__ = test_name
2799 setattr(test_class
, test_name
, test_wrapper
)
2801 def _get_parser(self
, tester
):
2802 parser
= argparse
.ArgumentParser(
2803 *tester
.parser_signature
.args
,
2804 **tester
.parser_signature
.kwargs
)
2805 for argument_sig
in getattr(tester
, 'argument_signatures', []):
2806 parser
.add_argument(*argument_sig
.args
,
2807 **argument_sig
.kwargs
)
2808 group_sigs
= getattr(tester
, 'argument_group_signatures', [])
2809 for group_sig
, argument_sigs
in group_sigs
:
2810 group
= parser
.add_argument_group(*group_sig
.args
,
2812 for argument_sig
in argument_sigs
:
2813 group
.add_argument(*argument_sig
.args
,
2814 **argument_sig
.kwargs
)
2815 subparsers_sigs
= getattr(tester
, 'subparsers_signatures', [])
2817 subparsers
= parser
.add_subparsers()
2818 for subparser_sig
in subparsers_sigs
:
2819 subparsers
.add_parser(*subparser_sig
.args
,
2820 **subparser_sig
.kwargs
)
2823 def _test(self
, tester
, parser_text
):
2824 expected_text
= getattr(tester
, self
.func_suffix
)
2825 expected_text
= textwrap
.dedent(expected_text
)
2826 if expected_text
!= parser_text
:
2827 print(repr(expected_text
))
2828 print(repr(parser_text
))
2829 for char1
, char2
in zip(expected_text
, parser_text
):
2831 print('first diff: %r %r' % (char1
, char2
))
2833 tester
.assertEqual(expected_text
, parser_text
)
2835 def test_format(self
, tester
):
2836 parser
= self
._get
_parser
(tester
)
2837 format
= getattr(parser
, 'format_%s' % self
.func_suffix
)
2838 self
._test
(tester
, format())
2840 def test_print(self
, tester
):
2841 parser
= self
._get
_parser
(tester
)
2842 print_
= getattr(parser
, 'print_%s' % self
.func_suffix
)
2843 old_stream
= getattr(sys
, self
.std_name
)
2844 setattr(sys
, self
.std_name
, StdIOBuffer())
2847 parser_text
= getattr(sys
, self
.std_name
).getvalue()
2849 setattr(sys
, self
.std_name
, old_stream
)
2850 self
._test
(tester
, parser_text
)
2852 def test_print_file(self
, tester
):
2853 parser
= self
._get
_parser
(tester
)
2854 print_
= getattr(parser
, 'print_%s' % self
.func_suffix
)
2855 sfile
= StdIOBuffer()
2857 parser_text
= sfile
.getvalue()
2858 self
._test
(tester
, parser_text
)
2860 # add tests for {format,print}_{usage,help,version}
2861 for func_suffix
, std_name
in [('usage', 'stdout'),
2863 ('version', 'stderr')]:
2864 AddTests(cls
, func_suffix
, std_name
)
2867 HelpTestCase
= TestHelpFormattingMetaclass('HelpTestCase', bases
, {})
2870 class TestHelpBiggerOptionals(HelpTestCase
):
2871 """Make sure that argument help aligns when options are longer"""
2873 parser_signature
= Sig(prog
='PROG', description
='DESCRIPTION',
2874 epilog
='EPILOG', version
='0.1')
2875 argument_signatures
= [
2876 Sig('-x', action
='store_true', help='X HELP'),
2877 Sig('--y', help='Y HELP'),
2878 Sig('foo', help='FOO HELP'),
2879 Sig('bar', help='BAR HELP'),
2881 argument_group_signatures
= []
2883 usage: PROG [-h] [-v] [-x] [--y Y] foo bar
2889 positional arguments:
2894 -h, --help show this help message and exit
2895 -v, --version show program's version number and exit
2906 class TestHelpBiggerOptionalGroups(HelpTestCase
):
2907 """Make sure that argument help aligns when options are longer"""
2909 parser_signature
= Sig(prog
='PROG', description
='DESCRIPTION',
2910 epilog
='EPILOG', version
='0.1')
2911 argument_signatures
= [
2912 Sig('-x', action
='store_true', help='X HELP'),
2913 Sig('--y', help='Y HELP'),
2914 Sig('foo', help='FOO HELP'),
2915 Sig('bar', help='BAR HELP'),
2917 argument_group_signatures
= [
2918 (Sig('GROUP TITLE', description
='GROUP DESCRIPTION'), [
2919 Sig('baz', help='BAZ HELP'),
2920 Sig('-z', nargs
='+', help='Z HELP')]),
2923 usage: PROG [-h] [-v] [-x] [--y Y] [-z Z [Z ...]] foo bar baz
2929 positional arguments:
2934 -h, --help show this help message and exit
2935 -v, --version show program's version number and exit
2952 class TestHelpBiggerPositionals(HelpTestCase
):
2953 """Make sure that help aligns when arguments are longer"""
2955 parser_signature
= Sig(usage
='USAGE', description
='DESCRIPTION')
2956 argument_signatures
= [
2957 Sig('-x', action
='store_true', help='X HELP'),
2958 Sig('--y', help='Y HELP'),
2959 Sig('ekiekiekifekang', help='EKI HELP'),
2960 Sig('bar', help='BAR HELP'),
2962 argument_group_signatures
= []
2970 positional arguments:
2971 ekiekiekifekang EKI HELP
2975 -h, --help show this help message and exit
2983 class TestHelpReformatting(HelpTestCase
):
2984 """Make sure that text after short names starts on the first line"""
2986 parser_signature
= Sig(
2988 description
=' oddly formatted\n'
2991 'that is so long that it should go onto multiple '
2992 'lines when wrapped')
2993 argument_signatures
= [
2994 Sig('-x', metavar
='XX', help='oddly\n'
2995 ' formatted -x help'),
2996 Sig('y', metavar
='yyy', help='normal y help'),
2998 argument_group_signatures
= [
2999 (Sig('title', description
='\n'
3000 ' oddly formatted group\n'
3003 [Sig('-a', action
='store_true',
3005 'formatted -a help \n'
3006 ' again, so long that it should be wrapped over '
3007 'multiple lines')]),
3010 usage: PROG [-h] [-x XX] [-a] yyy
3014 oddly formatted description that is so long that it should go onto \
3018 positional arguments:
3022 -h, --help show this help message and exit
3023 -x XX oddly formatted -x help
3026 oddly formatted group description
3028 -a oddly formatted -a help again, so long that it should \
3035 class TestHelpWrappingShortNames(HelpTestCase
):
3036 """Make sure that text after short names starts on the first line"""
3038 parser_signature
= Sig(prog
='PROG', description
= 'D\nD' * 30)
3039 argument_signatures
= [
3040 Sig('-x', metavar
='XX', help='XHH HX' * 20),
3041 Sig('y', metavar
='yyy', help='YH YH' * 20),
3043 argument_group_signatures
= [
3045 Sig('-a', action
='store_true', help='AHHH HHA' * 10)]),
3048 usage: PROG [-h] [-x XX] [-a] yyy
3052 D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
3056 positional arguments:
3057 yyy YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
3059 YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
3062 -h, --help show this help message and exit
3063 -x XX XHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH \
3065 HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HX
3068 -a AHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH \
3075 class TestHelpWrappingLongNames(HelpTestCase
):
3076 """Make sure that text after long names starts on the next line"""
3078 parser_signature
= Sig(usage
='USAGE', description
= 'D D' * 30,
3080 argument_signatures
= [
3081 Sig('-x', metavar
='X' * 25, help='XH XH' * 20),
3082 Sig('y', metavar
='y' * 25, help='YH YH' * 20),
3084 argument_group_signatures
= [
3086 Sig('-a', metavar
='A' * 25, help='AH AH' * 20),
3087 Sig('z', metavar
='z' * 25, help='ZH ZH' * 20)]),
3094 D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
3098 positional arguments:
3099 yyyyyyyyyyyyyyyyyyyyyyyyy
3100 YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
3102 YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
3105 -h, --help show this help message and exit
3106 -v, --version show program's version number and exit
3107 -x XXXXXXXXXXXXXXXXXXXXXXXXX
3108 XH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH \
3110 XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XH
3113 -a AAAAAAAAAAAAAAAAAAAAAAAAA
3114 AH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH \
3116 AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AH
3117 zzzzzzzzzzzzzzzzzzzzzzzzz
3118 ZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH \
3120 ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZH
3123 V VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV \
3129 class TestHelpUsage(HelpTestCase
):
3130 """Test basic usage messages"""
3132 parser_signature
= Sig(prog
='PROG')
3133 argument_signatures
= [
3134 Sig('-w', nargs
='+', help='w'),
3135 Sig('-x', nargs
='*', help='x'),
3137 Sig('b', help='b', nargs
=2),
3138 Sig('c', help='c', nargs
='?'),
3140 argument_group_signatures
= [
3142 Sig('-y', nargs
='?', help='y'),
3143 Sig('-z', nargs
=3, help='z'),
3144 Sig('d', help='d', nargs
='*'),
3145 Sig('e', help='e', nargs
='+'),
3149 usage: PROG [-h] [-w W [W ...]] [-x [X [X ...]]] [-y [Y]] [-z Z Z Z]
3150 a b b [c] [d [d ...]] e [e ...]
3154 positional arguments:
3160 -h, --help show this help message and exit
3173 class TestHelpOnlyUserGroups(HelpTestCase
):
3174 """Test basic usage messages"""
3176 parser_signature
= Sig(prog
='PROG', add_help
=False)
3177 argument_signatures
= []
3178 argument_group_signatures
= [
3180 Sig('-x', help='x'),
3185 Sig('-y', help='y'),
3189 usage: PROG [-x X] [-y Y] a b
3204 class TestHelpUsageLongProg(HelpTestCase
):
3205 """Test usage messages where the prog is long"""
3207 parser_signature
= Sig(prog
='P' * 60)
3208 argument_signatures
= [
3209 Sig('-w', metavar
='W'),
3210 Sig('-x', metavar
='X'),
3214 argument_group_signatures
= []
3216 usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
3217 [-h] [-w W] [-x X] a b
3221 positional arguments:
3226 -h, --help show this help message and exit
3233 class TestHelpUsageLongProgOptionsWrap(HelpTestCase
):
3234 """Test usage messages where the prog is long and the optionals wrap"""
3236 parser_signature
= Sig(prog
='P' * 60)
3237 argument_signatures
= [
3238 Sig('-w', metavar
='W' * 25),
3239 Sig('-x', metavar
='X' * 25),
3240 Sig('-y', metavar
='Y' * 25),
3241 Sig('-z', metavar
='Z' * 25),
3245 argument_group_signatures
= []
3247 usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
3248 [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
3249 [-x XXXXXXXXXXXXXXXXXXXXXXXXX]
3250 [-y YYYYYYYYYYYYYYYYYYYYYYYYY] [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
3255 positional arguments:
3260 -h, --help show this help message and exit
3261 -w WWWWWWWWWWWWWWWWWWWWWWWWW
3262 -x XXXXXXXXXXXXXXXXXXXXXXXXX
3263 -y YYYYYYYYYYYYYYYYYYYYYYYYY
3264 -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
3269 class TestHelpUsageLongProgPositionalsWrap(HelpTestCase
):
3270 """Test usage messages where the prog is long and the positionals wrap"""
3272 parser_signature
= Sig(prog
='P' * 60, add_help
=False)
3273 argument_signatures
= [
3278 argument_group_signatures
= []
3280 usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
3281 aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
3282 ccccccccccccccccccccccccc
3286 positional arguments:
3287 aaaaaaaaaaaaaaaaaaaaaaaaa
3288 bbbbbbbbbbbbbbbbbbbbbbbbb
3289 ccccccccccccccccccccccccc
3294 class TestHelpUsageOptionalsWrap(HelpTestCase
):
3295 """Test usage messages where the optionals wrap"""
3297 parser_signature
= Sig(prog
='PROG')
3298 argument_signatures
= [
3299 Sig('-w', metavar
='W' * 25),
3300 Sig('-x', metavar
='X' * 25),
3301 Sig('-y', metavar
='Y' * 25),
3302 Sig('-z', metavar
='Z' * 25),
3307 argument_group_signatures
= []
3309 usage: PROG [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
3310 [-x XXXXXXXXXXXXXXXXXXXXXXXXX]
3311 [-y YYYYYYYYYYYYYYYYYYYYYYYYY] \
3312 [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
3317 positional arguments:
3323 -h, --help show this help message and exit
3324 -w WWWWWWWWWWWWWWWWWWWWWWWWW
3325 -x XXXXXXXXXXXXXXXXXXXXXXXXX
3326 -y YYYYYYYYYYYYYYYYYYYYYYYYY
3327 -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
3332 class TestHelpUsagePositionalsWrap(HelpTestCase
):
3333 """Test usage messages where the positionals wrap"""
3335 parser_signature
= Sig(prog
='PROG')
3336 argument_signatures
= [
3344 argument_group_signatures
= []
3346 usage: PROG [-h] [-x X] [-y Y] [-z Z]
3347 aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
3348 ccccccccccccccccccccccccc
3352 positional arguments:
3353 aaaaaaaaaaaaaaaaaaaaaaaaa
3354 bbbbbbbbbbbbbbbbbbbbbbbbb
3355 ccccccccccccccccccccccccc
3358 -h, --help show this help message and exit
3366 class TestHelpUsageOptionalsPositionalsWrap(HelpTestCase
):
3367 """Test usage messages where the optionals and positionals wrap"""
3369 parser_signature
= Sig(prog
='PROG')
3370 argument_signatures
= [
3371 Sig('-x', metavar
='X' * 25),
3372 Sig('-y', metavar
='Y' * 25),
3373 Sig('-z', metavar
='Z' * 25),
3378 argument_group_signatures
= []
3380 usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
3381 [-y YYYYYYYYYYYYYYYYYYYYYYYYY]
3382 [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
3383 aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
3384 ccccccccccccccccccccccccc
3388 positional arguments:
3389 aaaaaaaaaaaaaaaaaaaaaaaaa
3390 bbbbbbbbbbbbbbbbbbbbbbbbb
3391 ccccccccccccccccccccccccc
3394 -h, --help show this help message and exit
3395 -x XXXXXXXXXXXXXXXXXXXXXXXXX
3396 -y YYYYYYYYYYYYYYYYYYYYYYYYY
3397 -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
3402 class TestHelpUsageOptionalsOnlyWrap(HelpTestCase
):
3403 """Test usage messages where there are only optionals and they wrap"""
3405 parser_signature
= Sig(prog
='PROG')
3406 argument_signatures
= [
3407 Sig('-x', metavar
='X' * 25),
3408 Sig('-y', metavar
='Y' * 25),
3409 Sig('-z', metavar
='Z' * 25),
3411 argument_group_signatures
= []
3413 usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
3414 [-y YYYYYYYYYYYYYYYYYYYYYYYYY]
3415 [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
3420 -h, --help show this help message and exit
3421 -x XXXXXXXXXXXXXXXXXXXXXXXXX
3422 -y YYYYYYYYYYYYYYYYYYYYYYYYY
3423 -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
3428 class TestHelpUsagePositionalsOnlyWrap(HelpTestCase
):
3429 """Test usage messages where there are only positionals and they wrap"""
3431 parser_signature
= Sig(prog
='PROG', add_help
=False)
3432 argument_signatures
= [
3437 argument_group_signatures
= []
3439 usage: PROG aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
3440 ccccccccccccccccccccccccc
3444 positional arguments:
3445 aaaaaaaaaaaaaaaaaaaaaaaaa
3446 bbbbbbbbbbbbbbbbbbbbbbbbb
3447 ccccccccccccccccccccccccc
3452 class TestHelpVariableExpansion(HelpTestCase
):
3453 """Test that variables are expanded properly in help messages"""
3455 parser_signature
= Sig(prog
='PROG')
3456 argument_signatures
= [
3458 help='x %(prog)s %(default)s %(type)s %%'),
3459 Sig('-y', action
='store_const', default
=42, const
='XXX',
3460 help='y %(prog)s %(default)s %(const)s'),
3461 Sig('--foo', choices
='abc',
3462 help='foo %(prog)s %(default)s %(choices)s'),
3463 Sig('--bar', default
='baz', choices
=[1, 2], metavar
='BBB',
3464 help='bar %(prog)s %(default)s %(dest)s'),
3465 Sig('spam', help='spam %(prog)s %(default)s'),
3466 Sig('badger', default
=0.5, help='badger %(prog)s %(default)s'),
3468 argument_group_signatures
= [
3470 Sig('-a', help='a %(prog)s %(default)s'),
3471 Sig('-b', default
=-1, help='b %(prog)s %(default)s'),
3475 usage: PROG [-h] [-x X] [-y] [--foo {a,b,c}] [--bar BBB] [-a A] [-b B]
3480 positional arguments:
3482 badger badger PROG 0.5
3485 -h, --help show this help message and exit
3486 -x X x PROG None int %
3488 --foo {a,b,c} foo PROG None a, b, c
3489 --bar BBB bar PROG baz bar
3498 class TestHelpVariableExpansionUsageSupplied(HelpTestCase
):
3499 """Test that variables are expanded properly when usage= is present"""
3501 parser_signature
= Sig(prog
='PROG', usage
='%(prog)s FOO')
3502 argument_signatures
= []
3503 argument_group_signatures
= []
3510 -h, --help show this help message and exit
3515 class TestHelpVariableExpansionNoArguments(HelpTestCase
):
3516 """Test that variables are expanded properly with no arguments"""
3518 parser_signature
= Sig(prog
='PROG', add_help
=False)
3519 argument_signatures
= []
3520 argument_group_signatures
= []
3528 class TestHelpSuppressUsage(HelpTestCase
):
3529 """Test that items can be suppressed in usage messages"""
3531 parser_signature
= Sig(prog
='PROG', usage
=argparse
.SUPPRESS
)
3532 argument_signatures
= [
3533 Sig('--foo', help='foo help'),
3534 Sig('spam', help='spam help'),
3536 argument_group_signatures
= []
3538 positional arguments:
3542 -h, --help show this help message and exit
3549 class TestHelpSuppressOptional(HelpTestCase
):
3550 """Test that optional arguments can be suppressed in help messages"""
3552 parser_signature
= Sig(prog
='PROG', add_help
=False)
3553 argument_signatures
= [
3554 Sig('--foo', help=argparse
.SUPPRESS
),
3555 Sig('spam', help='spam help'),
3557 argument_group_signatures
= []
3563 positional arguments:
3569 class TestHelpSuppressOptionalGroup(HelpTestCase
):
3570 """Test that optional groups can be suppressed in help messages"""
3572 parser_signature
= Sig(prog
='PROG')
3573 argument_signatures
= [
3574 Sig('--foo', help='foo help'),
3575 Sig('spam', help='spam help'),
3577 argument_group_signatures
= [
3578 (Sig('group'), [Sig('--bar', help=argparse
.SUPPRESS
)]),
3581 usage: PROG [-h] [--foo FOO] spam
3585 positional arguments:
3589 -h, --help show this help message and exit
3595 class TestHelpSuppressPositional(HelpTestCase
):
3596 """Test that positional arguments can be suppressed in help messages"""
3598 parser_signature
= Sig(prog
='PROG')
3599 argument_signatures
= [
3600 Sig('--foo', help='foo help'),
3601 Sig('spam', help=argparse
.SUPPRESS
),
3603 argument_group_signatures
= []
3605 usage: PROG [-h] [--foo FOO]
3610 -h, --help show this help message and exit
3616 class TestHelpRequiredOptional(HelpTestCase
):
3617 """Test that required options don't look optional"""
3619 parser_signature
= Sig(prog
='PROG')
3620 argument_signatures
= [
3621 Sig('--foo', required
=True, help='foo help'),
3623 argument_group_signatures
= []
3625 usage: PROG [-h] --foo FOO
3630 -h, --help show this help message and exit
3636 class TestHelpAlternatePrefixChars(HelpTestCase
):
3637 """Test that options display with different prefix characters"""
3639 parser_signature
= Sig(prog
='PROG', prefix_chars
='^;', add_help
=False)
3640 argument_signatures
= [
3641 Sig('^^foo', action
='store_true', help='foo help'),
3642 Sig(';b', ';;bar', help='bar help'),
3644 argument_group_signatures
= []
3646 usage: PROG [^^foo] [;b BAR]
3652 ;b BAR, ;;bar BAR bar help
3657 class TestHelpNoHelpOptional(HelpTestCase
):
3658 """Test that the --help argument can be suppressed help messages"""
3660 parser_signature
= Sig(prog
='PROG', add_help
=False)
3661 argument_signatures
= [
3662 Sig('--foo', help='foo help'),
3663 Sig('spam', help='spam help'),
3665 argument_group_signatures
= []
3667 usage: PROG [--foo FOO] spam
3671 positional arguments:
3680 class TestHelpVersionOptional(HelpTestCase
):
3681 """Test that the --version argument can be suppressed help messages"""
3683 parser_signature
= Sig(prog
='PROG', version
='1.0')
3684 argument_signatures
= [
3685 Sig('--foo', help='foo help'),
3686 Sig('spam', help='spam help'),
3688 argument_group_signatures
= []
3690 usage: PROG [-h] [-v] [--foo FOO] spam
3694 positional arguments:
3698 -h, --help show this help message and exit
3699 -v, --version show program's version number and exit
3707 class TestHelpNone(HelpTestCase
):
3708 """Test that no errors occur if no help is specified"""
3710 parser_signature
= Sig(prog
='PROG')
3711 argument_signatures
= [
3715 argument_group_signatures
= []
3717 usage: PROG [-h] [--foo FOO] spam
3721 positional arguments:
3725 -h, --help show this help message and exit
3731 class TestHelpTupleMetavar(HelpTestCase
):
3732 """Test specifying metavar as a tuple"""
3734 parser_signature
= Sig(prog
='PROG')
3735 argument_signatures
= [
3736 Sig('-w', help='w', nargs
='+', metavar
=('W1', 'W2')),
3737 Sig('-x', help='x', nargs
='*', metavar
=('X1', 'X2')),
3738 Sig('-y', help='y', nargs
=3, metavar
=('Y1', 'Y2', 'Y3')),
3739 Sig('-z', help='z', nargs
='?', metavar
=('Z1', )),
3741 argument_group_signatures
= []
3743 usage: PROG [-h] [-w W1 [W2 ...]] [-x [X1 [X2 ...]]] [-y Y1 Y2 Y3] \
3749 -h, --help show this help message and exit
3758 class TestHelpRawText(HelpTestCase
):
3759 """Test the RawTextHelpFormatter"""
3761 parser_signature
= Sig(
3762 prog
='PROG', formatter_class
=argparse
.RawTextHelpFormatter
,
3763 description
='Keep the formatting\n'
3764 ' exactly as it is written\n'
3768 argument_signatures
= [
3769 Sig('--foo', help=' foo help should also\n'
3770 'appear as given here'),
3771 Sig('spam', help='spam help'),
3773 argument_group_signatures
= [
3774 (Sig('title', description
=' This text\n'
3775 ' should be indented\n'
3776 ' exactly like it is here\n'),
3777 [Sig('--bar', help='bar help')]),
3780 usage: PROG [-h] [--foo FOO] [--bar BAR] spam
3785 exactly as it is written
3789 positional arguments:
3793 -h, --help show this help message and exit
3794 --foo FOO foo help should also
3795 appear as given here
3800 exactly like it is here
3807 class TestHelpRawDescription(HelpTestCase
):
3808 """Test the RawTextHelpFormatter"""
3810 parser_signature
= Sig(
3811 prog
='PROG', formatter_class
=argparse
.RawDescriptionHelpFormatter
,
3812 description
='Keep the formatting\n'
3813 ' exactly as it is written\n'
3817 argument_signatures
= [
3818 Sig('--foo', help=' foo help should not\n'
3819 ' retain this odd formatting'),
3820 Sig('spam', help='spam help'),
3822 argument_group_signatures
= [
3823 (Sig('title', description
=' This text\n'
3824 ' should be indented\n'
3825 ' exactly like it is here\n'),
3826 [Sig('--bar', help='bar help')]),
3829 usage: PROG [-h] [--foo FOO] [--bar BAR] spam
3834 exactly as it is written
3838 positional arguments:
3842 -h, --help show this help message and exit
3843 --foo FOO foo help should not retain this odd formatting
3848 exactly like it is here
3855 class TestHelpArgumentDefaults(HelpTestCase
):
3856 """Test the ArgumentDefaultsHelpFormatter"""
3858 parser_signature
= Sig(
3859 prog
='PROG', formatter_class
=argparse
.ArgumentDefaultsHelpFormatter
,
3860 description
='description')
3862 argument_signatures
= [
3863 Sig('--foo', help='foo help - oh and by the way, %(default)s'),
3864 Sig('--bar', action
='store_true', help='bar help'),
3865 Sig('spam', help='spam help'),
3866 Sig('badger', nargs
='?', default
='wooden', help='badger help'),
3868 argument_group_signatures
= [
3869 (Sig('title', description
='description'),
3870 [Sig('--baz', type=int, default
=42, help='baz help')]),
3873 usage: PROG [-h] [--foo FOO] [--bar] [--baz BAZ] spam [badger]
3879 positional arguments:
3881 badger badger help (default: wooden)
3884 -h, --help show this help message and exit
3885 --foo FOO foo help - oh and by the way, None
3886 --bar bar help (default: False)
3891 --baz BAZ baz help (default: 42)
3895 class TestHelpVersionAction(HelpTestCase
):
3896 """Test the default help for the version action"""
3898 parser_signature
= Sig(prog
='PROG', description
='description')
3899 argument_signatures
= [Sig('-V', '--version', action
='version', version
='3.6')]
3900 argument_group_signatures
= []
3902 usage: PROG [-h] [-V]
3909 -h, --help show this help message and exit
3910 -V, --version show program's version number and exit
3914 class TestHelpSubparsersOrdering(HelpTestCase
):
3915 """Test ordering of subcommands in help matches the code"""
3916 parser_signature
= Sig(prog
='PROG',
3917 description
='display some subcommands',
3920 subparsers_signatures
= [Sig(name
=name
)
3921 for name
in ('a', 'b', 'c', 'd', 'e')]
3924 usage: PROG [-h] [-v] {a,b,c,d,e} ...
3929 display some subcommands
3931 positional arguments:
3935 -h, --help show this help message and exit
3936 -v, --version show program's version number and exit
3943 class TestHelpSubparsersWithHelpOrdering(HelpTestCase
):
3944 """Test ordering of subcommands in help matches the code"""
3945 parser_signature
= Sig(prog
='PROG',
3946 description
='display some subcommands',
3949 subcommand_data
= (('a', 'a subcommand help'),
3950 ('b', 'b subcommand help'),
3951 ('c', 'c subcommand help'),
3952 ('d', 'd subcommand help'),
3953 ('e', 'e subcommand help'),
3956 subparsers_signatures
= [Sig(name
=name
, help=help)
3957 for name
, help in subcommand_data
]
3960 usage: PROG [-h] [-v] {a,b,c,d,e} ...
3965 display some subcommands
3967 positional arguments:
3976 -h, --help show this help message and exit
3977 -v, --version show program's version number and exit
3985 # =====================================
3986 # Optional/Positional constructor tests
3987 # =====================================
3989 class TestInvalidArgumentConstructors(TestCase
):
3990 """Test a bunch of invalid Argument constructors"""
3992 def assertTypeError(self
, *args
, **kwargs
):
3993 parser
= argparse
.ArgumentParser()
3994 self
.assertRaises(TypeError, parser
.add_argument
,
3997 def assertValueError(self
, *args
, **kwargs
):
3998 parser
= argparse
.ArgumentParser()
3999 self
.assertRaises(ValueError, parser
.add_argument
,
4002 def test_invalid_keyword_arguments(self
):
4003 self
.assertTypeError('-x', bar
=None)
4004 self
.assertTypeError('-y', callback
='foo')
4005 self
.assertTypeError('-y', callback_args
=())
4006 self
.assertTypeError('-y', callback_kwargs
={})
4008 def test_missing_destination(self
):
4009 self
.assertTypeError()
4010 for action
in ['append', 'store']:
4011 self
.assertTypeError(action
=action
)
4013 def test_invalid_option_strings(self
):
4014 self
.assertValueError('--')
4015 self
.assertValueError('---')
4017 def test_invalid_type(self
):
4018 self
.assertValueError('--foo', type='int')
4019 self
.assertValueError('--foo', type=(int, float))
4021 def test_invalid_action(self
):
4022 self
.assertValueError('-x', action
='foo')
4023 self
.assertValueError('foo', action
='baz')
4024 self
.assertValueError('--foo', action
=('store', 'append'))
4025 parser
= argparse
.ArgumentParser()
4027 parser
.add_argument("--foo", action
="store-true")
4029 e
= sys
.exc_info()[1]
4030 expected
= 'unknown action'
4031 msg
= 'expected %r, found %r' % (expected
, e
)
4032 self
.assertTrue(expected
in str(e
), msg
)
4034 def test_multiple_dest(self
):
4035 parser
= argparse
.ArgumentParser()
4036 parser
.add_argument(dest
='foo')
4038 parser
.add_argument('bar', dest
='baz')
4040 e
= sys
.exc_info()[1]
4041 expected
= 'dest supplied twice for positional argument'
4042 msg
= 'expected %r, found %r' % (expected
, e
)
4043 self
.assertTrue(expected
in str(e
), msg
)
4045 def test_no_argument_actions(self
):
4046 for action
in ['store_const', 'store_true', 'store_false',
4047 'append_const', 'count']:
4048 for attrs
in [dict(type=int), dict(nargs
='+'),
4049 dict(choices
='ab')]:
4050 self
.assertTypeError('-x', action
=action
, **attrs
)
4052 def test_no_argument_no_const_actions(self
):
4053 # options with zero arguments
4054 for action
in ['store_true', 'store_false', 'count']:
4056 # const is always disallowed
4057 self
.assertTypeError('-x', const
='foo', action
=action
)
4059 # nargs is always disallowed
4060 self
.assertTypeError('-x', nargs
='*', action
=action
)
4062 def test_more_than_one_argument_actions(self
):
4063 for action
in ['store', 'append']:
4065 # nargs=0 is disallowed
4066 self
.assertValueError('-x', nargs
=0, action
=action
)
4067 self
.assertValueError('spam', nargs
=0, action
=action
)
4069 # const is disallowed with non-optional arguments
4070 for nargs
in [1, '*', '+']:
4071 self
.assertValueError('-x', const
='foo',
4072 nargs
=nargs
, action
=action
)
4073 self
.assertValueError('spam', const
='foo',
4074 nargs
=nargs
, action
=action
)
4076 def test_required_const_actions(self
):
4077 for action
in ['store_const', 'append_const']:
4079 # nargs is always disallowed
4080 self
.assertTypeError('-x', nargs
='+', action
=action
)
4082 def test_parsers_action_missing_params(self
):
4083 self
.assertTypeError('command', action
='parsers')
4084 self
.assertTypeError('command', action
='parsers', prog
='PROG')
4085 self
.assertTypeError('command', action
='parsers',
4086 parser_class
=argparse
.ArgumentParser
)
4088 def test_required_positional(self
):
4089 self
.assertTypeError('foo', required
=True)
4091 def test_user_defined_action(self
):
4093 class Success(Exception):
4096 class Action(object):
4105 if const
is Success
:
4106 if default
is Success
:
4109 def __call__(self
, *args
, **kwargs
):
4112 parser
= argparse
.ArgumentParser()
4113 self
.assertRaises(Success
, parser
.add_argument
, '--spam',
4114 action
=Action
, default
=Success
, const
=Success
)
4115 self
.assertRaises(Success
, parser
.add_argument
, 'spam',
4116 action
=Action
, default
=Success
, const
=Success
)
4118 # ================================
4119 # Actions returned by add_argument
4120 # ================================
4122 class TestActionsReturned(TestCase
):
4124 def test_dest(self
):
4125 parser
= argparse
.ArgumentParser()
4126 action
= parser
.add_argument('--foo')
4127 self
.assertEqual(action
.dest
, 'foo')
4128 action
= parser
.add_argument('-b', '--bar')
4129 self
.assertEqual(action
.dest
, 'bar')
4130 action
= parser
.add_argument('-x', '-y')
4131 self
.assertEqual(action
.dest
, 'x')
4133 def test_misc(self
):
4134 parser
= argparse
.ArgumentParser()
4135 action
= parser
.add_argument('--foo', nargs
='?', const
=42,
4136 default
=84, type=int, choices
=[1, 2],
4137 help='FOO', metavar
='BAR', dest
='baz')
4138 self
.assertEqual(action
.nargs
, '?')
4139 self
.assertEqual(action
.const
, 42)
4140 self
.assertEqual(action
.default
, 84)
4141 self
.assertEqual(action
.type, int)
4142 self
.assertEqual(action
.choices
, [1, 2])
4143 self
.assertEqual(action
.help, 'FOO')
4144 self
.assertEqual(action
.metavar
, 'BAR')
4145 self
.assertEqual(action
.dest
, 'baz')
4148 # ================================
4149 # Argument conflict handling tests
4150 # ================================
4152 class TestConflictHandling(TestCase
):
4154 def test_bad_type(self
):
4155 self
.assertRaises(ValueError, argparse
.ArgumentParser
,
4156 conflict_handler
='foo')
4158 def test_conflict_error(self
):
4159 parser
= argparse
.ArgumentParser()
4160 parser
.add_argument('-x')
4161 self
.assertRaises(argparse
.ArgumentError
,
4162 parser
.add_argument
, '-x')
4163 parser
.add_argument('--spam')
4164 self
.assertRaises(argparse
.ArgumentError
,
4165 parser
.add_argument
, '--spam')
4167 def test_resolve_error(self
):
4168 get_parser
= argparse
.ArgumentParser
4169 parser
= get_parser(prog
='PROG', conflict_handler
='resolve')
4171 parser
.add_argument('-x', help='OLD X')
4172 parser
.add_argument('-x', help='NEW X')
4173 self
.assertEqual(parser
.format_help(), textwrap
.dedent('''\
4174 usage: PROG [-h] [-x X]
4177 -h, --help show this help message and exit
4181 parser
.add_argument('--spam', metavar
='OLD_SPAM')
4182 parser
.add_argument('--spam', metavar
='NEW_SPAM')
4183 self
.assertEqual(parser
.format_help(), textwrap
.dedent('''\
4184 usage: PROG [-h] [-x X] [--spam NEW_SPAM]
4187 -h, --help show this help message and exit
4193 # =============================
4194 # Help and Version option tests
4195 # =============================
4197 class TestOptionalsHelpVersionActions(TestCase
):
4198 """Test the help and version actions"""
4200 def _get_error(self
, func
, *args
, **kwargs
):
4202 func(*args
, **kwargs
)
4203 except ArgumentParserError
:
4204 return sys
.exc_info()[1]
4206 self
.assertRaises(ArgumentParserError
, func
, *args
, **kwargs
)
4208 def assertPrintHelpExit(self
, parser
, args_str
):
4210 parser
.format_help(),
4211 self
._get
_error
(parser
.parse_args
, args_str
.split()).stdout
)
4213 def assertPrintVersionExit(self
, parser
, args_str
):
4215 parser
.format_version(),
4216 self
._get
_error
(parser
.parse_args
, args_str
.split()).stderr
)
4218 def assertArgumentParserError(self
, parser
, *args
):
4219 self
.assertRaises(ArgumentParserError
, parser
.parse_args
, args
)
4221 def test_version(self
):
4222 parser
= ErrorRaisingArgumentParser(version
='1.0')
4223 self
.assertPrintHelpExit(parser
, '-h')
4224 self
.assertPrintHelpExit(parser
, '--help')
4225 self
.assertPrintVersionExit(parser
, '-v')
4226 self
.assertPrintVersionExit(parser
, '--version')
4228 def test_version_format(self
):
4229 parser
= ErrorRaisingArgumentParser(prog
='PPP', version
='%(prog)s 3.5')
4230 msg
= self
._get
_error
(parser
.parse_args
, ['-v']).stderr
4231 self
.assertEqual('PPP 3.5\n', msg
)
4233 def test_version_no_help(self
):
4234 parser
= ErrorRaisingArgumentParser(add_help
=False, version
='1.0')
4235 self
.assertArgumentParserError(parser
, '-h')
4236 self
.assertArgumentParserError(parser
, '--help')
4237 self
.assertPrintVersionExit(parser
, '-v')
4238 self
.assertPrintVersionExit(parser
, '--version')
4240 def test_version_action(self
):
4241 parser
= ErrorRaisingArgumentParser(prog
='XXX')
4242 parser
.add_argument('-V', action
='version', version
='%(prog)s 3.7')
4243 msg
= self
._get
_error
(parser
.parse_args
, ['-V']).stderr
4244 self
.assertEqual('XXX 3.7\n', msg
)
4246 def test_no_help(self
):
4247 parser
= ErrorRaisingArgumentParser(add_help
=False)
4248 self
.assertArgumentParserError(parser
, '-h')
4249 self
.assertArgumentParserError(parser
, '--help')
4250 self
.assertArgumentParserError(parser
, '-v')
4251 self
.assertArgumentParserError(parser
, '--version')
4253 def test_alternate_help_version(self
):
4254 parser
= ErrorRaisingArgumentParser()
4255 parser
.add_argument('-x', action
='help')
4256 parser
.add_argument('-y', action
='version')
4257 self
.assertPrintHelpExit(parser
, '-x')
4258 self
.assertPrintVersionExit(parser
, '-y')
4259 self
.assertArgumentParserError(parser
, '-v')
4260 self
.assertArgumentParserError(parser
, '--version')
4262 def test_help_version_extra_arguments(self
):
4263 parser
= ErrorRaisingArgumentParser(version
='1.0')
4264 parser
.add_argument('-x', action
='store_true')
4265 parser
.add_argument('y')
4267 # try all combinations of valid prefixes and suffixes
4268 valid_prefixes
= ['', '-x', 'foo', '-x bar', 'baz -x']
4269 valid_suffixes
= valid_prefixes
+ ['--bad-option', 'foo bar baz']
4270 for prefix
in valid_prefixes
:
4271 for suffix
in valid_suffixes
:
4272 format
= '%s %%s %s' % (prefix
, suffix
)
4273 self
.assertPrintHelpExit(parser
, format
% '-h')
4274 self
.assertPrintHelpExit(parser
, format
% '--help')
4275 self
.assertPrintVersionExit(parser
, format
% '-v')
4276 self
.assertPrintVersionExit(parser
, format
% '--version')
4279 # ======================
4280 # str() and repr() tests
4281 # ======================
4283 class TestStrings(TestCase
):
4284 """Test str() and repr() on Optionals and Positionals"""
4286 def assertStringEqual(self
, obj
, result_string
):
4287 for func
in [str, repr]:
4288 self
.assertEqual(func(obj
), result_string
)
4290 def test_optional(self
):
4291 option
= argparse
.Action(
4292 option_strings
=['--foo', '-a', '-b'],
4301 "Action(option_strings=['--foo', '-a', '-b'], dest='b', "
4302 "nargs='+', const=None, default=42, type='int', "
4303 "choices=[1, 2, 3], help='HELP', metavar='METAVAR')")
4304 self
.assertStringEqual(option
, string
)
4306 def test_argument(self
):
4307 argument
= argparse
.Action(
4313 choices
=[0.5, 1.5, 2.5],
4317 "Action(option_strings=[], dest='x', nargs='?', "
4318 "const=None, default=2.5, type=%r, choices=[0.5, 1.5, 2.5], "
4319 "help='H HH H', metavar='MV MV MV')" % float)
4320 self
.assertStringEqual(argument
, string
)
4322 def test_namespace(self
):
4323 ns
= argparse
.Namespace(foo
=42, bar
='spam')
4324 string
= "Namespace(bar='spam', foo=42)"
4325 self
.assertStringEqual(ns
, string
)
4327 def test_parser(self
):
4328 parser
= argparse
.ArgumentParser(prog
='PROG')
4330 "ArgumentParser(prog='PROG', usage=None, description=None, "
4331 "version=None, formatter_class=%r, conflict_handler='error', "
4332 "add_help=True)" % argparse
.HelpFormatter
)
4333 self
.assertStringEqual(parser
, string
)
4339 class TestNamespace(TestCase
):
4341 def test_constructor(self
):
4342 ns
= argparse
.Namespace()
4343 self
.assertRaises(AttributeError, getattr, ns
, 'x')
4345 ns
= argparse
.Namespace(a
=42, b
='spam')
4346 self
.assertEqual(ns
.a
, 42)
4347 self
.assertEqual(ns
.b
, 'spam')
4349 def test_equality(self
):
4350 ns1
= argparse
.Namespace(a
=1, b
=2)
4351 ns2
= argparse
.Namespace(b
=2, a
=1)
4352 ns3
= argparse
.Namespace(a
=1)
4353 ns4
= argparse
.Namespace(b
=2)
4355 self
.assertEqual(ns1
, ns2
)
4356 self
.assertNotEqual(ns1
, ns3
)
4357 self
.assertNotEqual(ns1
, ns4
)
4358 self
.assertNotEqual(ns2
, ns3
)
4359 self
.assertNotEqual(ns2
, ns4
)
4360 self
.assertTrue(ns1
!= ns3
)
4361 self
.assertTrue(ns1
!= ns4
)
4362 self
.assertTrue(ns2
!= ns3
)
4363 self
.assertTrue(ns2
!= ns4
)
4366 # ===================
4367 # File encoding tests
4368 # ===================
4370 class TestEncoding(TestCase
):
4372 def _test_module_encoding(self
, path
):
4373 path
, _
= os
.path
.splitext(path
)
4375 with codecs
.open(path
, 'r', 'utf8') as f
:
4378 def test_argparse_module_encoding(self
):
4379 self
._test
_module
_encoding
(argparse
.__file
__)
4381 def test_test_argparse_module_encoding(self
):
4382 self
._test
_module
_encoding
(__file__
)
4384 # ===================
4385 # ArgumentError tests
4386 # ===================
4388 class TestArgumentError(TestCase
):
4390 def test_argument_error(self
):
4391 msg
= "my error here"
4392 error
= argparse
.ArgumentError(None, msg
)
4393 self
.assertEqual(str(error
), msg
)
4395 # =======================
4396 # ArgumentTypeError tests
4397 # =======================
4399 class TestArgumentTypeError(TestCase
):
4401 def test_argument_type_error(self
):
4404 raise argparse
.ArgumentTypeError('spam!')
4406 parser
= ErrorRaisingArgumentParser(prog
='PROG', add_help
=False)
4407 parser
.add_argument('x', type=spam
)
4409 parser
.parse_args(['XXX'])
4410 except ArgumentParserError
:
4411 expected
= 'usage: PROG x\nPROG: error: argument x: spam!\n'
4412 msg
= sys
.exc_info()[1].stderr
4413 self
.assertEqual(expected
, msg
)
4417 # ======================
4418 # parse_known_args tests
4419 # ======================
4421 class TestParseKnownArgs(TestCase
):
4423 def test_optionals(self
):
4424 parser
= argparse
.ArgumentParser()
4425 parser
.add_argument('--foo')
4426 args
, extras
= parser
.parse_known_args('--foo F --bar --baz'.split())
4427 self
.assertEqual(NS(foo
='F'), args
)
4428 self
.assertEqual(['--bar', '--baz'], extras
)
4430 def test_mixed(self
):
4431 parser
= argparse
.ArgumentParser()
4432 parser
.add_argument('-v', nargs
='?', const
=1, type=int)
4433 parser
.add_argument('--spam', action
='store_false')
4434 parser
.add_argument('badger')
4436 argv
= ["B", "C", "--foo", "-v", "3", "4"]
4437 args
, extras
= parser
.parse_known_args(argv
)
4438 self
.assertEqual(NS(v
=3, spam
=True, badger
="B"), args
)
4439 self
.assertEqual(["C", "--foo", "4"], extras
)
4441 # ==========================
4442 # add_argument metavar tests
4443 # ==========================
4445 class TestAddArgumentMetavar(TestCase
):
4447 EXPECTED_MESSAGE
= "length of metavar tuple does not match nargs"
4449 def do_test_no_exception(self
, nargs
, metavar
):
4450 parser
= argparse
.ArgumentParser()
4451 parser
.add_argument("--foo", nargs
=nargs
, metavar
=metavar
)
4453 def do_test_exception(self
, nargs
, metavar
):
4454 parser
= argparse
.ArgumentParser()
4455 with self
.assertRaises(ValueError) as cm
:
4456 parser
.add_argument("--foo", nargs
=nargs
, metavar
=metavar
)
4457 self
.assertEqual(cm
.exception
.args
[0], self
.EXPECTED_MESSAGE
)
4459 # Unit tests for different values of metavar when nargs=None
4461 def test_nargs_None_metavar_string(self
):
4462 self
.do_test_no_exception(nargs
=None, metavar
="1")
4464 def test_nargs_None_metavar_length0(self
):
4465 self
.do_test_exception(nargs
=None, metavar
=tuple())
4467 def test_nargs_None_metavar_length1(self
):
4468 self
.do_test_no_exception(nargs
=None, metavar
=("1"))
4470 def test_nargs_None_metavar_length2(self
):
4471 self
.do_test_exception(nargs
=None, metavar
=("1", "2"))
4473 def test_nargs_None_metavar_length3(self
):
4474 self
.do_test_exception(nargs
=None, metavar
=("1", "2", "3"))
4476 # Unit tests for different values of metavar when nargs=?
4478 def test_nargs_optional_metavar_string(self
):
4479 self
.do_test_no_exception(nargs
="?", metavar
="1")
4481 def test_nargs_optional_metavar_length0(self
):
4482 self
.do_test_exception(nargs
="?", metavar
=tuple())
4484 def test_nargs_optional_metavar_length1(self
):
4485 self
.do_test_no_exception(nargs
="?", metavar
=("1"))
4487 def test_nargs_optional_metavar_length2(self
):
4488 self
.do_test_exception(nargs
="?", metavar
=("1", "2"))
4490 def test_nargs_optional_metavar_length3(self
):
4491 self
.do_test_exception(nargs
="?", metavar
=("1", "2", "3"))
4493 # Unit tests for different values of metavar when nargs=*
4495 def test_nargs_zeroormore_metavar_string(self
):
4496 self
.do_test_no_exception(nargs
="*", metavar
="1")
4498 def test_nargs_zeroormore_metavar_length0(self
):
4499 self
.do_test_exception(nargs
="*", metavar
=tuple())
4501 def test_nargs_zeroormore_metavar_length1(self
):
4502 self
.do_test_no_exception(nargs
="*", metavar
=("1"))
4504 def test_nargs_zeroormore_metavar_length2(self
):
4505 self
.do_test_no_exception(nargs
="*", metavar
=("1", "2"))
4507 def test_nargs_zeroormore_metavar_length3(self
):
4508 self
.do_test_exception(nargs
="*", metavar
=("1", "2", "3"))
4510 # Unit tests for different values of metavar when nargs=+
4512 def test_nargs_oneormore_metavar_string(self
):
4513 self
.do_test_no_exception(nargs
="+", metavar
="1")
4515 def test_nargs_oneormore_metavar_length0(self
):
4516 self
.do_test_exception(nargs
="+", metavar
=tuple())
4518 def test_nargs_oneormore_metavar_length1(self
):
4519 self
.do_test_no_exception(nargs
="+", metavar
=("1"))
4521 def test_nargs_oneormore_metavar_length2(self
):
4522 self
.do_test_no_exception(nargs
="+", metavar
=("1", "2"))
4524 def test_nargs_oneormore_metavar_length3(self
):
4525 self
.do_test_exception(nargs
="+", metavar
=("1", "2", "3"))
4527 # Unit tests for different values of metavar when nargs=...
4529 def test_nargs_remainder_metavar_string(self
):
4530 self
.do_test_no_exception(nargs
="...", metavar
="1")
4532 def test_nargs_remainder_metavar_length0(self
):
4533 self
.do_test_no_exception(nargs
="...", metavar
=tuple())
4535 def test_nargs_remainder_metavar_length1(self
):
4536 self
.do_test_no_exception(nargs
="...", metavar
=("1"))
4538 def test_nargs_remainder_metavar_length2(self
):
4539 self
.do_test_no_exception(nargs
="...", metavar
=("1", "2"))
4541 def test_nargs_remainder_metavar_length3(self
):
4542 self
.do_test_no_exception(nargs
="...", metavar
=("1", "2", "3"))
4544 # Unit tests for different values of metavar when nargs=A...
4546 def test_nargs_parser_metavar_string(self
):
4547 self
.do_test_no_exception(nargs
="A...", metavar
="1")
4549 def test_nargs_parser_metavar_length0(self
):
4550 self
.do_test_exception(nargs
="A...", metavar
=tuple())
4552 def test_nargs_parser_metavar_length1(self
):
4553 self
.do_test_no_exception(nargs
="A...", metavar
=("1"))
4555 def test_nargs_parser_metavar_length2(self
):
4556 self
.do_test_exception(nargs
="A...", metavar
=("1", "2"))
4558 def test_nargs_parser_metavar_length3(self
):
4559 self
.do_test_exception(nargs
="A...", metavar
=("1", "2", "3"))
4561 # Unit tests for different values of metavar when nargs=1
4563 def test_nargs_1_metavar_string(self
):
4564 self
.do_test_no_exception(nargs
=1, metavar
="1")
4566 def test_nargs_1_metavar_length0(self
):
4567 self
.do_test_exception(nargs
=1, metavar
=tuple())
4569 def test_nargs_1_metavar_length1(self
):
4570 self
.do_test_no_exception(nargs
=1, metavar
=("1"))
4572 def test_nargs_1_metavar_length2(self
):
4573 self
.do_test_exception(nargs
=1, metavar
=("1", "2"))
4575 def test_nargs_1_metavar_length3(self
):
4576 self
.do_test_exception(nargs
=1, metavar
=("1", "2", "3"))
4578 # Unit tests for different values of metavar when nargs=2
4580 def test_nargs_2_metavar_string(self
):
4581 self
.do_test_no_exception(nargs
=2, metavar
="1")
4583 def test_nargs_2_metavar_length0(self
):
4584 self
.do_test_exception(nargs
=2, metavar
=tuple())
4586 def test_nargs_2_metavar_length1(self
):
4587 self
.do_test_no_exception(nargs
=2, metavar
=("1"))
4589 def test_nargs_2_metavar_length2(self
):
4590 self
.do_test_no_exception(nargs
=2, metavar
=("1", "2"))
4592 def test_nargs_2_metavar_length3(self
):
4593 self
.do_test_exception(nargs
=2, metavar
=("1", "2", "3"))
4595 # Unit tests for different values of metavar when nargs=3
4597 def test_nargs_3_metavar_string(self
):
4598 self
.do_test_no_exception(nargs
=3, metavar
="1")
4600 def test_nargs_3_metavar_length0(self
):
4601 self
.do_test_exception(nargs
=3, metavar
=tuple())
4603 def test_nargs_3_metavar_length1(self
):
4604 self
.do_test_no_exception(nargs
=3, metavar
=("1"))
4606 def test_nargs_3_metavar_length2(self
):
4607 self
.do_test_exception(nargs
=3, metavar
=("1", "2"))
4609 def test_nargs_3_metavar_length3(self
):
4610 self
.do_test_no_exception(nargs
=3, metavar
=("1", "2", "3"))
4612 # ============================
4613 # from argparse import * tests
4614 # ============================
4616 class TestImportStar(TestCase
):
4619 for name
in argparse
.__all
__:
4620 self
.assertTrue(hasattr(argparse
, name
))
4622 def test_all_exports_everything_but_modules(self
):
4625 for name
, value
in vars(argparse
).items()
4626 if not name
.startswith("_")
4627 if not inspect
.ismodule(value
)
4629 self
.assertEqual(sorted(items
), sorted(argparse
.__all
__))
4632 # silence warnings about version argument - these are expected
4633 with test_support
.check_warnings(
4634 ('The "version" argument to ArgumentParser is deprecated.',
4635 DeprecationWarning),
4636 ('The (format|print)_version method is deprecated',
4637 DeprecationWarning)):
4638 test_support
.run_unittest(__name__
)
4639 # Remove global references to avoid looking like we have refleaks.
4645 if __name__
== '__main__':