1 | # Author: Steven J. Bethard <steven.bethard@gmail.com>.
|
---|
2 |
|
---|
3 | import codecs
|
---|
4 | import inspect
|
---|
5 | import os
|
---|
6 | import shutil
|
---|
7 | import stat
|
---|
8 | import sys
|
---|
9 | import textwrap
|
---|
10 | import tempfile
|
---|
11 | import unittest
|
---|
12 | import argparse
|
---|
13 |
|
---|
14 | from StringIO import StringIO
|
---|
15 |
|
---|
16 | class StdIOBuffer(StringIO):
|
---|
17 | pass
|
---|
18 |
|
---|
19 | from test import test_support
|
---|
20 |
|
---|
21 | class TestCase(unittest.TestCase):
|
---|
22 |
|
---|
23 | def assertEqual(self, obj1, obj2):
|
---|
24 | if obj1 != obj2:
|
---|
25 | print('')
|
---|
26 | print(repr(obj1))
|
---|
27 | print(repr(obj2))
|
---|
28 | print(obj1)
|
---|
29 | print(obj2)
|
---|
30 | super(TestCase, self).assertEqual(obj1, obj2)
|
---|
31 |
|
---|
32 | def setUp(self):
|
---|
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()
|
---|
37 | env.unset("COLUMNS")
|
---|
38 | self.addCleanup(env.__exit__)
|
---|
39 |
|
---|
40 |
|
---|
41 | class TempDirMixin(object):
|
---|
42 |
|
---|
43 | def setUp(self):
|
---|
44 | self.temp_dir = tempfile.mkdtemp()
|
---|
45 | self.old_dir = os.getcwd()
|
---|
46 | os.chdir(self.temp_dir)
|
---|
47 |
|
---|
48 | def tearDown(self):
|
---|
49 | os.chdir(self.old_dir)
|
---|
50 | shutil.rmtree(self.temp_dir, True)
|
---|
51 |
|
---|
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:
|
---|
55 | file.write(filename)
|
---|
56 | os.chmod(file_path, stat.S_IREAD)
|
---|
57 |
|
---|
58 | class Sig(object):
|
---|
59 |
|
---|
60 | def __init__(self, *args, **kwargs):
|
---|
61 | self.args = args
|
---|
62 | self.kwargs = kwargs
|
---|
63 |
|
---|
64 |
|
---|
65 | class NS(object):
|
---|
66 |
|
---|
67 | def __init__(self, **kwargs):
|
---|
68 | self.__dict__.update(kwargs)
|
---|
69 |
|
---|
70 | def __repr__(self):
|
---|
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)
|
---|
74 |
|
---|
75 | __hash__ = None
|
---|
76 |
|
---|
77 | def __eq__(self, other):
|
---|
78 | return vars(self) == vars(other)
|
---|
79 |
|
---|
80 | def __ne__(self, other):
|
---|
81 | return not (self == other)
|
---|
82 |
|
---|
83 |
|
---|
84 | class ArgumentParserError(Exception):
|
---|
85 |
|
---|
86 | def __init__(self, message, stdout=None, stderr=None, error_code=None):
|
---|
87 | Exception.__init__(self, message, stdout, stderr)
|
---|
88 | self.message = message
|
---|
89 | self.stdout = stdout
|
---|
90 | self.stderr = stderr
|
---|
91 | self.error_code = error_code
|
---|
92 |
|
---|
93 |
|
---|
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
|
---|
97 | # catch the exception
|
---|
98 | if isinstance(sys.stderr, StdIOBuffer) or isinstance(sys.stdout, StdIOBuffer):
|
---|
99 | return parse_args(*args, **kwargs)
|
---|
100 |
|
---|
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()
|
---|
107 | try:
|
---|
108 | try:
|
---|
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)
|
---|
115 | return result
|
---|
116 | except SystemExit:
|
---|
117 | code = sys.exc_info()[1].code
|
---|
118 | stdout = sys.stdout.getvalue()
|
---|
119 | stderr = sys.stderr.getvalue()
|
---|
120 | raise ArgumentParserError("SystemExit", stdout, stderr, code)
|
---|
121 | finally:
|
---|
122 | sys.stdout = old_stdout
|
---|
123 | sys.stderr = old_stderr
|
---|
124 |
|
---|
125 |
|
---|
126 | class ErrorRaisingArgumentParser(argparse.ArgumentParser):
|
---|
127 |
|
---|
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)
|
---|
131 |
|
---|
132 | def exit(self, *args, **kwargs):
|
---|
133 | exit = super(ErrorRaisingArgumentParser, self).exit
|
---|
134 | return stderr_to_parser_error(exit, *args, **kwargs)
|
---|
135 |
|
---|
136 | def error(self, *args, **kwargs):
|
---|
137 | error = super(ErrorRaisingArgumentParser, self).error
|
---|
138 | return stderr_to_parser_error(error, *args, **kwargs)
|
---|
139 |
|
---|
140 |
|
---|
141 | class ParserTesterMetaclass(type):
|
---|
142 | """Adds parser tests using the class attributes.
|
---|
143 |
|
---|
144 | Classes of this type should specify the following attributes:
|
---|
145 |
|
---|
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
|
---|
149 | to fail
|
---|
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
|
---|
155 | """
|
---|
156 |
|
---|
157 | def __init__(cls, name, bases, bodydict):
|
---|
158 | if name == 'ParserTestCase':
|
---|
159 | return
|
---|
160 |
|
---|
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
|
---|
166 |
|
---|
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)
|
---|
174 |
|
---|
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)
|
---|
180 |
|
---|
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)
|
---|
186 |
|
---|
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)
|
---|
193 |
|
---|
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
|
---|
198 | try:
|
---|
199 | return parser.parse_args()
|
---|
200 | finally:
|
---|
201 | sys.argv = old_sys_argv
|
---|
202 |
|
---|
203 | # class that holds the combination of one optional argument
|
---|
204 | # addition method and one arg parsing method
|
---|
205 | class AddTests(object):
|
---|
206 |
|
---|
207 | def __init__(self, tester_cls, add_arguments, parse_args):
|
---|
208 | self._add_arguments = add_arguments
|
---|
209 | self._parse_args = parse_args
|
---|
210 |
|
---|
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)
|
---|
217 |
|
---|
218 | def wrapper(self, test_func=test_func):
|
---|
219 | test_func(self)
|
---|
220 | try:
|
---|
221 | wrapper.__name__ = test_name
|
---|
222 | except TypeError:
|
---|
223 | pass
|
---|
224 | setattr(tester_cls, test_name, wrapper)
|
---|
225 |
|
---|
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)
|
---|
231 | return parser
|
---|
232 |
|
---|
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)
|
---|
239 |
|
---|
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):
|
---|
244 | args = args.split()
|
---|
245 | result_ns = self._parse_args(parser, args)
|
---|
246 | tester.assertEqual(expected_ns, result_ns)
|
---|
247 |
|
---|
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)
|
---|
253 |
|
---|
254 | bases = TestCase,
|
---|
255 | ParserTestCase = ParserTesterMetaclass('ParserTestCase', bases, {})
|
---|
256 |
|
---|
257 | # ===============
|
---|
258 | # Optionals tests
|
---|
259 | # ===============
|
---|
260 |
|
---|
261 | class TestOptionalsSingleDash(ParserTestCase):
|
---|
262 | """Test an Optional with a single-dash option string"""
|
---|
263 |
|
---|
264 | argument_signatures = [Sig('-x')]
|
---|
265 | failures = ['-x', 'a', '--foo', '-x --foo', '-x -y']
|
---|
266 | successes = [
|
---|
267 | ('', NS(x=None)),
|
---|
268 | ('-x a', NS(x='a')),
|
---|
269 | ('-xa', NS(x='a')),
|
---|
270 | ('-x -1', NS(x='-1')),
|
---|
271 | ('-x-1', NS(x='-1')),
|
---|
272 | ]
|
---|
273 |
|
---|
274 |
|
---|
275 | class TestOptionalsSingleDashCombined(ParserTestCase):
|
---|
276 | """Test an Optional with a single-dash option string"""
|
---|
277 |
|
---|
278 | argument_signatures = [
|
---|
279 | Sig('-x', action='store_true'),
|
---|
280 | Sig('-yyy', action='store_const', const=42),
|
---|
281 | Sig('-z'),
|
---|
282 | ]
|
---|
283 | failures = ['a', '--foo', '-xa', '-x --foo', '-x -z', '-z -x',
|
---|
284 | '-yx', '-yz a', '-yyyx', '-yyyza', '-xyza']
|
---|
285 | successes = [
|
---|
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')),
|
---|
298 | ]
|
---|
299 |
|
---|
300 |
|
---|
301 | class TestOptionalsSingleDashLong(ParserTestCase):
|
---|
302 | """Test an Optional with a multi-character single-dash option string"""
|
---|
303 |
|
---|
304 | argument_signatures = [Sig('-foo')]
|
---|
305 | failures = ['-foo', 'a', '--foo', '-foo --foo', '-foo -y', '-fooa']
|
---|
306 | successes = [
|
---|
307 | ('', NS(foo=None)),
|
---|
308 | ('-foo a', NS(foo='a')),
|
---|
309 | ('-foo -1', NS(foo='-1')),
|
---|
310 | ('-fo a', NS(foo='a')),
|
---|
311 | ('-f a', NS(foo='a')),
|
---|
312 | ]
|
---|
313 |
|
---|
314 |
|
---|
315 | class TestOptionalsSingleDashSubsetAmbiguous(ParserTestCase):
|
---|
316 | """Test Optionals where option strings are subsets of each other"""
|
---|
317 |
|
---|
318 | argument_signatures = [Sig('-f'), Sig('-foobar'), Sig('-foorab')]
|
---|
319 | failures = ['-f', '-foo', '-fo', '-foo b', '-foob', '-fooba', '-foora']
|
---|
320 | successes = [
|
---|
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')),
|
---|
328 | ]
|
---|
329 |
|
---|
330 |
|
---|
331 | class TestOptionalsSingleDashAmbiguous(ParserTestCase):
|
---|
332 | """Test Optionals that partially match but are not subsets"""
|
---|
333 |
|
---|
334 | argument_signatures = [Sig('-foobar'), Sig('-foorab')]
|
---|
335 | failures = ['-f', '-f a', '-fa', '-foa', '-foo', '-fo', '-foo b']
|
---|
336 | successes = [
|
---|
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')),
|
---|
344 | ]
|
---|
345 |
|
---|
346 |
|
---|
347 | class TestOptionalsNumeric(ParserTestCase):
|
---|
348 | """Test an Optional with a short opt string"""
|
---|
349 |
|
---|
350 | argument_signatures = [Sig('-1', dest='one')]
|
---|
351 | failures = ['-1', 'a', '-1 --foo', '-1 -y', '-1 -1', '-1 -2']
|
---|
352 | successes = [
|
---|
353 | ('', NS(one=None)),
|
---|
354 | ('-1 a', NS(one='a')),
|
---|
355 | ('-1a', NS(one='a')),
|
---|
356 | ('-1-2', NS(one='-2')),
|
---|
357 | ]
|
---|
358 |
|
---|
359 |
|
---|
360 | class TestOptionalsDoubleDash(ParserTestCase):
|
---|
361 | """Test an Optional with a double-dash option string"""
|
---|
362 |
|
---|
363 | argument_signatures = [Sig('--foo')]
|
---|
364 | failures = ['--foo', '-f', '-f a', 'a', '--foo -x', '--foo --bar']
|
---|
365 | successes = [
|
---|
366 | ('', NS(foo=None)),
|
---|
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')),
|
---|
371 | ]
|
---|
372 |
|
---|
373 |
|
---|
374 | class TestOptionalsDoubleDashPartialMatch(ParserTestCase):
|
---|
375 | """Tests partial matching with a double-dash option string"""
|
---|
376 |
|
---|
377 | argument_signatures = [
|
---|
378 | Sig('--badger', action='store_true'),
|
---|
379 | Sig('--bat'),
|
---|
380 | ]
|
---|
381 | failures = ['--bar', '--b', '--ba', '--b=2', '--ba=4', '--badge 5']
|
---|
382 | successes = [
|
---|
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)),
|
---|
389 | ]
|
---|
390 |
|
---|
391 |
|
---|
392 | class TestOptionalsDoubleDashPrefixMatch(ParserTestCase):
|
---|
393 | """Tests when one double-dash option string is a prefix of another"""
|
---|
394 |
|
---|
395 | argument_signatures = [
|
---|
396 | Sig('--badger', action='store_true'),
|
---|
397 | Sig('--ba'),
|
---|
398 | ]
|
---|
399 | failures = ['--bar', '--b', '--ba', '--b=2', '--badge 5']
|
---|
400 | successes = [
|
---|
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)),
|
---|
408 | ]
|
---|
409 |
|
---|
410 |
|
---|
411 | class TestOptionalsSingleDoubleDash(ParserTestCase):
|
---|
412 | """Test an Optional with single- and double-dash option strings"""
|
---|
413 |
|
---|
414 | argument_signatures = [
|
---|
415 | Sig('-f', action='store_true'),
|
---|
416 | Sig('--bar'),
|
---|
417 | Sig('-baz', action='store_const', const=42),
|
---|
418 | ]
|
---|
419 | failures = ['--bar', '-fbar', '-fbaz', '-bazf', '-b B', 'B']
|
---|
420 | successes = [
|
---|
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)),
|
---|
427 | ]
|
---|
428 |
|
---|
429 |
|
---|
430 | class TestOptionalsAlternatePrefixChars(ParserTestCase):
|
---|
431 | """Test an Optional with option strings with custom prefixes"""
|
---|
432 |
|
---|
433 | parser_signature = Sig(prefix_chars='+:/', add_help=False)
|
---|
434 | argument_signatures = [
|
---|
435 | Sig('+f', action='store_true'),
|
---|
436 | Sig('::bar'),
|
---|
437 | Sig('/baz', action='store_const', const=42),
|
---|
438 | ]
|
---|
439 | failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz', '-h', '--help', '+h', '::help', '/help']
|
---|
440 | successes = [
|
---|
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)),
|
---|
447 | ]
|
---|
448 |
|
---|
449 |
|
---|
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"""
|
---|
454 |
|
---|
455 | parser_signature = Sig(prefix_chars='+:/', add_help=True)
|
---|
456 | argument_signatures = [
|
---|
457 | Sig('+f', action='store_true'),
|
---|
458 | Sig('::bar'),
|
---|
459 | Sig('/baz', action='store_const', const=42),
|
---|
460 | ]
|
---|
461 | failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz']
|
---|
462 | successes = [
|
---|
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))
|
---|
469 | ]
|
---|
470 |
|
---|
471 |
|
---|
472 | class TestOptionalsAlternatePrefixCharsMultipleShortArgs(ParserTestCase):
|
---|
473 | """Verify that Optionals must be called with their defined prefixes"""
|
---|
474 |
|
---|
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'),
|
---|
480 | ]
|
---|
481 | failures = ['-w',
|
---|
482 | '-xyz',
|
---|
483 | '+x',
|
---|
484 | '-y',
|
---|
485 | '+xyz',
|
---|
486 | ]
|
---|
487 | successes = [
|
---|
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)),
|
---|
492 | ]
|
---|
493 |
|
---|
494 |
|
---|
495 | class TestOptionalsShortLong(ParserTestCase):
|
---|
496 | """Test a combination of single- and double-dash option strings"""
|
---|
497 |
|
---|
498 | argument_signatures = [
|
---|
499 | Sig('-v', '--verbose', '-n', '--noisy', action='store_true'),
|
---|
500 | ]
|
---|
501 | failures = ['--x --verbose', '-N', 'a', '-v x']
|
---|
502 | successes = [
|
---|
503 | ('', NS(verbose=False)),
|
---|
504 | ('-v', NS(verbose=True)),
|
---|
505 | ('--verbose', NS(verbose=True)),
|
---|
506 | ('-n', NS(verbose=True)),
|
---|
507 | ('--noisy', NS(verbose=True)),
|
---|
508 | ]
|
---|
509 |
|
---|
510 |
|
---|
511 | class TestOptionalsDest(ParserTestCase):
|
---|
512 | """Tests various means of setting destination"""
|
---|
513 |
|
---|
514 | argument_signatures = [Sig('--foo-bar'), Sig('--baz', dest='zabbaz')]
|
---|
515 | failures = ['a']
|
---|
516 | successes = [
|
---|
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')),
|
---|
521 | ]
|
---|
522 |
|
---|
523 |
|
---|
524 | class TestOptionalsDefault(ParserTestCase):
|
---|
525 | """Tests specifying a default for an Optional"""
|
---|
526 |
|
---|
527 | argument_signatures = [Sig('-x'), Sig('-y', default=42)]
|
---|
528 | failures = ['a']
|
---|
529 | successes = [
|
---|
530 | ('', NS(x=None, y=42)),
|
---|
531 | ('-xx', NS(x='x', y=42)),
|
---|
532 | ('-yy', NS(x=None, y='y')),
|
---|
533 | ]
|
---|
534 |
|
---|
535 |
|
---|
536 | class TestOptionalsNargsDefault(ParserTestCase):
|
---|
537 | """Tests not specifying the number of args for an Optional"""
|
---|
538 |
|
---|
539 | argument_signatures = [Sig('-x')]
|
---|
540 | failures = ['a', '-x']
|
---|
541 | successes = [
|
---|
542 | ('', NS(x=None)),
|
---|
543 | ('-x a', NS(x='a')),
|
---|
544 | ]
|
---|
545 |
|
---|
546 |
|
---|
547 | class TestOptionalsNargs1(ParserTestCase):
|
---|
548 | """Tests specifying the 1 arg for an Optional"""
|
---|
549 |
|
---|
550 | argument_signatures = [Sig('-x', nargs=1)]
|
---|
551 | failures = ['a', '-x']
|
---|
552 | successes = [
|
---|
553 | ('', NS(x=None)),
|
---|
554 | ('-x a', NS(x=['a'])),
|
---|
555 | ]
|
---|
556 |
|
---|
557 |
|
---|
558 | class TestOptionalsNargs3(ParserTestCase):
|
---|
559 | """Tests specifying the 3 args for an Optional"""
|
---|
560 |
|
---|
561 | argument_signatures = [Sig('-x', nargs=3)]
|
---|
562 | failures = ['a', '-x', '-x a', '-x a b', 'a -x', 'a -x b']
|
---|
563 | successes = [
|
---|
564 | ('', NS(x=None)),
|
---|
565 | ('-x a b c', NS(x=['a', 'b', 'c'])),
|
---|
566 | ]
|
---|
567 |
|
---|
568 |
|
---|
569 | class TestOptionalsNargsOptional(ParserTestCase):
|
---|
570 | """Tests specifying an Optional arg for an Optional"""
|
---|
571 |
|
---|
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'),
|
---|
577 | ]
|
---|
578 | failures = ['2']
|
---|
579 | successes = [
|
---|
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)),
|
---|
589 | ]
|
---|
590 |
|
---|
591 |
|
---|
592 | class TestOptionalsNargsZeroOrMore(ParserTestCase):
|
---|
593 | """Tests specifying an args for an Optional that accepts zero or more"""
|
---|
594 |
|
---|
595 | argument_signatures = [
|
---|
596 | Sig('-x', nargs='*'),
|
---|
597 | Sig('-y', nargs='*', default='spam'),
|
---|
598 | ]
|
---|
599 | failures = ['a']
|
---|
600 | successes = [
|
---|
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'])),
|
---|
608 | ]
|
---|
609 |
|
---|
610 |
|
---|
611 | class TestOptionalsNargsOneOrMore(ParserTestCase):
|
---|
612 | """Tests specifying an args for an Optional that accepts one or more"""
|
---|
613 |
|
---|
614 | argument_signatures = [
|
---|
615 | Sig('-x', nargs='+'),
|
---|
616 | Sig('-y', nargs='+', default='spam'),
|
---|
617 | ]
|
---|
618 | failures = ['a', '-x', '-y', 'a -x', 'a -y b']
|
---|
619 | successes = [
|
---|
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'])),
|
---|
625 | ]
|
---|
626 |
|
---|
627 |
|
---|
628 | class TestOptionalsChoices(ParserTestCase):
|
---|
629 | """Tests specifying the choices for an Optional"""
|
---|
630 |
|
---|
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']
|
---|
635 | successes = [
|
---|
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)),
|
---|
642 | ]
|
---|
643 |
|
---|
644 |
|
---|
645 | class TestOptionalsRequired(ParserTestCase):
|
---|
646 | """Tests the an optional action that is required"""
|
---|
647 |
|
---|
648 | argument_signatures = [
|
---|
649 | Sig('-x', type=int, required=True),
|
---|
650 | ]
|
---|
651 | failures = ['a', '']
|
---|
652 | successes = [
|
---|
653 | ('-x 1', NS(x=1)),
|
---|
654 | ('-x42', NS(x=42)),
|
---|
655 | ]
|
---|
656 |
|
---|
657 |
|
---|
658 | class TestOptionalsActionStore(ParserTestCase):
|
---|
659 | """Tests the store action for an Optional"""
|
---|
660 |
|
---|
661 | argument_signatures = [Sig('-x', action='store')]
|
---|
662 | failures = ['a', 'a -x']
|
---|
663 | successes = [
|
---|
664 | ('', NS(x=None)),
|
---|
665 | ('-xfoo', NS(x='foo')),
|
---|
666 | ]
|
---|
667 |
|
---|
668 |
|
---|
669 | class TestOptionalsActionStoreConst(ParserTestCase):
|
---|
670 | """Tests the store_const action for an Optional"""
|
---|
671 |
|
---|
672 | argument_signatures = [Sig('-y', action='store_const', const=object)]
|
---|
673 | failures = ['a']
|
---|
674 | successes = [
|
---|
675 | ('', NS(y=None)),
|
---|
676 | ('-y', NS(y=object)),
|
---|
677 | ]
|
---|
678 |
|
---|
679 |
|
---|
680 | class TestOptionalsActionStoreFalse(ParserTestCase):
|
---|
681 | """Tests the store_false action for an Optional"""
|
---|
682 |
|
---|
683 | argument_signatures = [Sig('-z', action='store_false')]
|
---|
684 | failures = ['a', '-za', '-z a']
|
---|
685 | successes = [
|
---|
686 | ('', NS(z=True)),
|
---|
687 | ('-z', NS(z=False)),
|
---|
688 | ]
|
---|
689 |
|
---|
690 |
|
---|
691 | class TestOptionalsActionStoreTrue(ParserTestCase):
|
---|
692 | """Tests the store_true action for an Optional"""
|
---|
693 |
|
---|
694 | argument_signatures = [Sig('--apple', action='store_true')]
|
---|
695 | failures = ['a', '--apple=b', '--apple b']
|
---|
696 | successes = [
|
---|
697 | ('', NS(apple=False)),
|
---|
698 | ('--apple', NS(apple=True)),
|
---|
699 | ]
|
---|
700 |
|
---|
701 |
|
---|
702 | class TestOptionalsActionAppend(ParserTestCase):
|
---|
703 | """Tests the append action for an Optional"""
|
---|
704 |
|
---|
705 | argument_signatures = [Sig('--baz', action='append')]
|
---|
706 | failures = ['a', '--baz', 'a --baz', '--baz a b']
|
---|
707 | successes = [
|
---|
708 | ('', NS(baz=None)),
|
---|
709 | ('--baz a', NS(baz=['a'])),
|
---|
710 | ('--baz a --baz b', NS(baz=['a', 'b'])),
|
---|
711 | ]
|
---|
712 |
|
---|
713 |
|
---|
714 | class TestOptionalsActionAppendWithDefault(ParserTestCase):
|
---|
715 | """Tests the append action for an Optional"""
|
---|
716 |
|
---|
717 | argument_signatures = [Sig('--baz', action='append', default=['X'])]
|
---|
718 | failures = ['a', '--baz', 'a --baz', '--baz a b']
|
---|
719 | successes = [
|
---|
720 | ('', NS(baz=['X'])),
|
---|
721 | ('--baz a', NS(baz=['X', 'a'])),
|
---|
722 | ('--baz a --baz b', NS(baz=['X', 'a', 'b'])),
|
---|
723 | ]
|
---|
724 |
|
---|
725 |
|
---|
726 | class TestOptionalsActionAppendConst(ParserTestCase):
|
---|
727 | """Tests the append_const action for an Optional"""
|
---|
728 |
|
---|
729 | argument_signatures = [
|
---|
730 | Sig('-b', action='append_const', const=Exception),
|
---|
731 | Sig('-c', action='append', dest='b'),
|
---|
732 | ]
|
---|
733 | failures = ['a', '-c', 'a -c', '-bx', '-b x']
|
---|
734 | successes = [
|
---|
735 | ('', NS(b=None)),
|
---|
736 | ('-b', NS(b=[Exception])),
|
---|
737 | ('-b -cx -b -cyz', NS(b=[Exception, 'x', Exception, 'yz'])),
|
---|
738 | ]
|
---|
739 |
|
---|
740 |
|
---|
741 | class TestOptionalsActionAppendConstWithDefault(ParserTestCase):
|
---|
742 | """Tests the append_const action for an Optional"""
|
---|
743 |
|
---|
744 | argument_signatures = [
|
---|
745 | Sig('-b', action='append_const', const=Exception, default=['X']),
|
---|
746 | Sig('-c', action='append', dest='b'),
|
---|
747 | ]
|
---|
748 | failures = ['a', '-c', 'a -c', '-bx', '-b x']
|
---|
749 | successes = [
|
---|
750 | ('', NS(b=['X'])),
|
---|
751 | ('-b', NS(b=['X', Exception])),
|
---|
752 | ('-b -cx -b -cyz', NS(b=['X', Exception, 'x', Exception, 'yz'])),
|
---|
753 | ]
|
---|
754 |
|
---|
755 |
|
---|
756 | class TestOptionalsActionCount(ParserTestCase):
|
---|
757 | """Tests the count action for an Optional"""
|
---|
758 |
|
---|
759 | argument_signatures = [Sig('-x', action='count')]
|
---|
760 | failures = ['a', '-x a', '-x b', '-x a -x b']
|
---|
761 | successes = [
|
---|
762 | ('', NS(x=None)),
|
---|
763 | ('-x', NS(x=1)),
|
---|
764 | ]
|
---|
765 |
|
---|
766 |
|
---|
767 | # ================
|
---|
768 | # Positional tests
|
---|
769 | # ================
|
---|
770 |
|
---|
771 | class TestPositionalsNargsNone(ParserTestCase):
|
---|
772 | """Test a Positional that doesn't specify nargs"""
|
---|
773 |
|
---|
774 | argument_signatures = [Sig('foo')]
|
---|
775 | failures = ['', '-x', 'a b']
|
---|
776 | successes = [
|
---|
777 | ('a', NS(foo='a')),
|
---|
778 | ]
|
---|
779 |
|
---|
780 |
|
---|
781 | class TestPositionalsNargs1(ParserTestCase):
|
---|
782 | """Test a Positional that specifies an nargs of 1"""
|
---|
783 |
|
---|
784 | argument_signatures = [Sig('foo', nargs=1)]
|
---|
785 | failures = ['', '-x', 'a b']
|
---|
786 | successes = [
|
---|
787 | ('a', NS(foo=['a'])),
|
---|
788 | ]
|
---|
789 |
|
---|
790 |
|
---|
791 | class TestPositionalsNargs2(ParserTestCase):
|
---|
792 | """Test a Positional that specifies an nargs of 2"""
|
---|
793 |
|
---|
794 | argument_signatures = [Sig('foo', nargs=2)]
|
---|
795 | failures = ['', 'a', '-x', 'a b c']
|
---|
796 | successes = [
|
---|
797 | ('a b', NS(foo=['a', 'b'])),
|
---|
798 | ]
|
---|
799 |
|
---|
800 |
|
---|
801 | class TestPositionalsNargsZeroOrMore(ParserTestCase):
|
---|
802 | """Test a Positional that specifies unlimited nargs"""
|
---|
803 |
|
---|
804 | argument_signatures = [Sig('foo', nargs='*')]
|
---|
805 | failures = ['-x']
|
---|
806 | successes = [
|
---|
807 | ('', NS(foo=[])),
|
---|
808 | ('a', NS(foo=['a'])),
|
---|
809 | ('a b', NS(foo=['a', 'b'])),
|
---|
810 | ]
|
---|
811 |
|
---|
812 |
|
---|
813 | class TestPositionalsNargsZeroOrMoreDefault(ParserTestCase):
|
---|
814 | """Test a Positional that specifies unlimited nargs and a default"""
|
---|
815 |
|
---|
816 | argument_signatures = [Sig('foo', nargs='*', default='bar')]
|
---|
817 | failures = ['-x']
|
---|
818 | successes = [
|
---|
819 | ('', NS(foo='bar')),
|
---|
820 | ('a', NS(foo=['a'])),
|
---|
821 | ('a b', NS(foo=['a', 'b'])),
|
---|
822 | ]
|
---|
823 |
|
---|
824 |
|
---|
825 | class TestPositionalsNargsOneOrMore(ParserTestCase):
|
---|
826 | """Test a Positional that specifies one or more nargs"""
|
---|
827 |
|
---|
828 | argument_signatures = [Sig('foo', nargs='+')]
|
---|
829 | failures = ['', '-x']
|
---|
830 | successes = [
|
---|
831 | ('a', NS(foo=['a'])),
|
---|
832 | ('a b', NS(foo=['a', 'b'])),
|
---|
833 | ]
|
---|
834 |
|
---|
835 |
|
---|
836 | class TestPositionalsNargsOptional(ParserTestCase):
|
---|
837 | """Tests an Optional Positional"""
|
---|
838 |
|
---|
839 | argument_signatures = [Sig('foo', nargs='?')]
|
---|
840 | failures = ['-x', 'a b']
|
---|
841 | successes = [
|
---|
842 | ('', NS(foo=None)),
|
---|
843 | ('a', NS(foo='a')),
|
---|
844 | ]
|
---|
845 |
|
---|
846 |
|
---|
847 | class TestPositionalsNargsOptionalDefault(ParserTestCase):
|
---|
848 | """Tests an Optional Positional with a default value"""
|
---|
849 |
|
---|
850 | argument_signatures = [Sig('foo', nargs='?', default=42)]
|
---|
851 | failures = ['-x', 'a b']
|
---|
852 | successes = [
|
---|
853 | ('', NS(foo=42)),
|
---|
854 | ('a', NS(foo='a')),
|
---|
855 | ]
|
---|
856 |
|
---|
857 |
|
---|
858 | class TestPositionalsNargsOptionalConvertedDefault(ParserTestCase):
|
---|
859 | """Tests an Optional Positional with a default value
|
---|
860 | that needs to be converted to the appropriate type.
|
---|
861 | """
|
---|
862 |
|
---|
863 | argument_signatures = [
|
---|
864 | Sig('foo', nargs='?', type=int, default='42'),
|
---|
865 | ]
|
---|
866 | failures = ['-x', 'a b', '1 2']
|
---|
867 | successes = [
|
---|
868 | ('', NS(foo=42)),
|
---|
869 | ('1', NS(foo=1)),
|
---|
870 | ]
|
---|
871 |
|
---|
872 |
|
---|
873 | class TestPositionalsNargsNoneNone(ParserTestCase):
|
---|
874 | """Test two Positionals that don't specify nargs"""
|
---|
875 |
|
---|
876 | argument_signatures = [Sig('foo'), Sig('bar')]
|
---|
877 | failures = ['', '-x', 'a', 'a b c']
|
---|
878 | successes = [
|
---|
879 | ('a b', NS(foo='a', bar='b')),
|
---|
880 | ]
|
---|
881 |
|
---|
882 |
|
---|
883 | class TestPositionalsNargsNone1(ParserTestCase):
|
---|
884 | """Test a Positional with no nargs followed by one with 1"""
|
---|
885 |
|
---|
886 | argument_signatures = [Sig('foo'), Sig('bar', nargs=1)]
|
---|
887 | failures = ['', '--foo', 'a', 'a b c']
|
---|
888 | successes = [
|
---|
889 | ('a b', NS(foo='a', bar=['b'])),
|
---|
890 | ]
|
---|
891 |
|
---|
892 |
|
---|
893 | class TestPositionalsNargs2None(ParserTestCase):
|
---|
894 | """Test a Positional with 2 nargs followed by one with none"""
|
---|
895 |
|
---|
896 | argument_signatures = [Sig('foo', nargs=2), Sig('bar')]
|
---|
897 | failures = ['', '--foo', 'a', 'a b', 'a b c d']
|
---|
898 | successes = [
|
---|
899 | ('a b c', NS(foo=['a', 'b'], bar='c')),
|
---|
900 | ]
|
---|
901 |
|
---|
902 |
|
---|
903 | class TestPositionalsNargsNoneZeroOrMore(ParserTestCase):
|
---|
904 | """Test a Positional with no nargs followed by one with unlimited"""
|
---|
905 |
|
---|
906 | argument_signatures = [Sig('foo'), Sig('bar', nargs='*')]
|
---|
907 | failures = ['', '--foo']
|
---|
908 | successes = [
|
---|
909 | ('a', NS(foo='a', bar=[])),
|
---|
910 | ('a b', NS(foo='a', bar=['b'])),
|
---|
911 | ('a b c', NS(foo='a', bar=['b', 'c'])),
|
---|
912 | ]
|
---|
913 |
|
---|
914 |
|
---|
915 | class TestPositionalsNargsNoneOneOrMore(ParserTestCase):
|
---|
916 | """Test a Positional with no nargs followed by one with one or more"""
|
---|
917 |
|
---|
918 | argument_signatures = [Sig('foo'), Sig('bar', nargs='+')]
|
---|
919 | failures = ['', '--foo', 'a']
|
---|
920 | successes = [
|
---|
921 | ('a b', NS(foo='a', bar=['b'])),
|
---|
922 | ('a b c', NS(foo='a', bar=['b', 'c'])),
|
---|
923 | ]
|
---|
924 |
|
---|
925 |
|
---|
926 | class TestPositionalsNargsNoneOptional(ParserTestCase):
|
---|
927 | """Test a Positional with no nargs followed by one with an Optional"""
|
---|
928 |
|
---|
929 | argument_signatures = [Sig('foo'), Sig('bar', nargs='?')]
|
---|
930 | failures = ['', '--foo', 'a b c']
|
---|
931 | successes = [
|
---|
932 | ('a', NS(foo='a', bar=None)),
|
---|
933 | ('a b', NS(foo='a', bar='b')),
|
---|
934 | ]
|
---|
935 |
|
---|
936 |
|
---|
937 | class TestPositionalsNargsZeroOrMoreNone(ParserTestCase):
|
---|
938 | """Test a Positional with unlimited nargs followed by one with none"""
|
---|
939 |
|
---|
940 | argument_signatures = [Sig('foo', nargs='*'), Sig('bar')]
|
---|
941 | failures = ['', '--foo']
|
---|
942 | successes = [
|
---|
943 | ('a', NS(foo=[], bar='a')),
|
---|
944 | ('a b', NS(foo=['a'], bar='b')),
|
---|
945 | ('a b c', NS(foo=['a', 'b'], bar='c')),
|
---|
946 | ]
|
---|
947 |
|
---|
948 |
|
---|
949 | class TestPositionalsNargsOneOrMoreNone(ParserTestCase):
|
---|
950 | """Test a Positional with one or more nargs followed by one with none"""
|
---|
951 |
|
---|
952 | argument_signatures = [Sig('foo', nargs='+'), Sig('bar')]
|
---|
953 | failures = ['', '--foo', 'a']
|
---|
954 | successes = [
|
---|
955 | ('a b', NS(foo=['a'], bar='b')),
|
---|
956 | ('a b c', NS(foo=['a', 'b'], bar='c')),
|
---|
957 | ]
|
---|
958 |
|
---|
959 |
|
---|
960 | class TestPositionalsNargsOptionalNone(ParserTestCase):
|
---|
961 | """Test a Positional with an Optional nargs followed by one with none"""
|
---|
962 |
|
---|
963 | argument_signatures = [Sig('foo', nargs='?', default=42), Sig('bar')]
|
---|
964 | failures = ['', '--foo', 'a b c']
|
---|
965 | successes = [
|
---|
966 | ('a', NS(foo=42, bar='a')),
|
---|
967 | ('a b', NS(foo='a', bar='b')),
|
---|
968 | ]
|
---|
969 |
|
---|
970 |
|
---|
971 | class TestPositionalsNargs2ZeroOrMore(ParserTestCase):
|
---|
972 | """Test a Positional with 2 nargs followed by one with unlimited"""
|
---|
973 |
|
---|
974 | argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='*')]
|
---|
975 | failures = ['', '--foo', 'a']
|
---|
976 | successes = [
|
---|
977 | ('a b', NS(foo=['a', 'b'], bar=[])),
|
---|
978 | ('a b c', NS(foo=['a', 'b'], bar=['c'])),
|
---|
979 | ]
|
---|
980 |
|
---|
981 |
|
---|
982 | class TestPositionalsNargs2OneOrMore(ParserTestCase):
|
---|
983 | """Test a Positional with 2 nargs followed by one with one or more"""
|
---|
984 |
|
---|
985 | argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='+')]
|
---|
986 | failures = ['', '--foo', 'a', 'a b']
|
---|
987 | successes = [
|
---|
988 | ('a b c', NS(foo=['a', 'b'], bar=['c'])),
|
---|
989 | ]
|
---|
990 |
|
---|
991 |
|
---|
992 | class TestPositionalsNargs2Optional(ParserTestCase):
|
---|
993 | """Test a Positional with 2 nargs followed by one optional"""
|
---|
994 |
|
---|
995 | argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='?')]
|
---|
996 | failures = ['', '--foo', 'a', 'a b c d']
|
---|
997 | successes = [
|
---|
998 | ('a b', NS(foo=['a', 'b'], bar=None)),
|
---|
999 | ('a b c', NS(foo=['a', 'b'], bar='c')),
|
---|
1000 | ]
|
---|
1001 |
|
---|
1002 |
|
---|
1003 | class TestPositionalsNargsZeroOrMore1(ParserTestCase):
|
---|
1004 | """Test a Positional with unlimited nargs followed by one with 1"""
|
---|
1005 |
|
---|
1006 | argument_signatures = [Sig('foo', nargs='*'), Sig('bar', nargs=1)]
|
---|
1007 | failures = ['', '--foo', ]
|
---|
1008 | successes = [
|
---|
1009 | ('a', NS(foo=[], bar=['a'])),
|
---|
1010 | ('a b', NS(foo=['a'], bar=['b'])),
|
---|
1011 | ('a b c', NS(foo=['a', 'b'], bar=['c'])),
|
---|
1012 | ]
|
---|
1013 |
|
---|
1014 |
|
---|
1015 | class TestPositionalsNargsOneOrMore1(ParserTestCase):
|
---|
1016 | """Test a Positional with one or more nargs followed by one with 1"""
|
---|
1017 |
|
---|
1018 | argument_signatures = [Sig('foo', nargs='+'), Sig('bar', nargs=1)]
|
---|
1019 | failures = ['', '--foo', 'a']
|
---|
1020 | successes = [
|
---|
1021 | ('a b', NS(foo=['a'], bar=['b'])),
|
---|
1022 | ('a b c', NS(foo=['a', 'b'], bar=['c'])),
|
---|
1023 | ]
|
---|
1024 |
|
---|
1025 |
|
---|
1026 | class TestPositionalsNargsOptional1(ParserTestCase):
|
---|
1027 | """Test a Positional with an Optional nargs followed by one with 1"""
|
---|
1028 |
|
---|
1029 | argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs=1)]
|
---|
1030 | failures = ['', '--foo', 'a b c']
|
---|
1031 | successes = [
|
---|
1032 | ('a', NS(foo=None, bar=['a'])),
|
---|
1033 | ('a b', NS(foo='a', bar=['b'])),
|
---|
1034 | ]
|
---|
1035 |
|
---|
1036 |
|
---|
1037 | class TestPositionalsNargsNoneZeroOrMore1(ParserTestCase):
|
---|
1038 | """Test three Positionals: no nargs, unlimited nargs and 1 nargs"""
|
---|
1039 |
|
---|
1040 | argument_signatures = [
|
---|
1041 | Sig('foo'),
|
---|
1042 | Sig('bar', nargs='*'),
|
---|
1043 | Sig('baz', nargs=1),
|
---|
1044 | ]
|
---|
1045 | failures = ['', '--foo', 'a']
|
---|
1046 | successes = [
|
---|
1047 | ('a b', NS(foo='a', bar=[], baz=['b'])),
|
---|
1048 | ('a b c', NS(foo='a', bar=['b'], baz=['c'])),
|
---|
1049 | ]
|
---|
1050 |
|
---|
1051 |
|
---|
1052 | class TestPositionalsNargsNoneOneOrMore1(ParserTestCase):
|
---|
1053 | """Test three Positionals: no nargs, one or more nargs and 1 nargs"""
|
---|
1054 |
|
---|
1055 | argument_signatures = [
|
---|
1056 | Sig('foo'),
|
---|
1057 | Sig('bar', nargs='+'),
|
---|
1058 | Sig('baz', nargs=1),
|
---|
1059 | ]
|
---|
1060 | failures = ['', '--foo', 'a', 'b']
|
---|
1061 | successes = [
|
---|
1062 | ('a b c', NS(foo='a', bar=['b'], baz=['c'])),
|
---|
1063 | ('a b c d', NS(foo='a', bar=['b', 'c'], baz=['d'])),
|
---|
1064 | ]
|
---|
1065 |
|
---|
1066 |
|
---|
1067 | class TestPositionalsNargsNoneOptional1(ParserTestCase):
|
---|
1068 | """Test three Positionals: no nargs, optional narg and 1 nargs"""
|
---|
1069 |
|
---|
1070 | argument_signatures = [
|
---|
1071 | Sig('foo'),
|
---|
1072 | Sig('bar', nargs='?', default=0.625),
|
---|
1073 | Sig('baz', nargs=1),
|
---|
1074 | ]
|
---|
1075 | failures = ['', '--foo', 'a']
|
---|
1076 | successes = [
|
---|
1077 | ('a b', NS(foo='a', bar=0.625, baz=['b'])),
|
---|
1078 | ('a b c', NS(foo='a', bar='b', baz=['c'])),
|
---|
1079 | ]
|
---|
1080 |
|
---|
1081 |
|
---|
1082 | class TestPositionalsNargsOptionalOptional(ParserTestCase):
|
---|
1083 | """Test two optional nargs"""
|
---|
1084 |
|
---|
1085 | argument_signatures = [
|
---|
1086 | Sig('foo', nargs='?'),
|
---|
1087 | Sig('bar', nargs='?', default=42),
|
---|
1088 | ]
|
---|
1089 | failures = ['--foo', 'a b c']
|
---|
1090 | successes = [
|
---|
1091 | ('', NS(foo=None, bar=42)),
|
---|
1092 | ('a', NS(foo='a', bar=42)),
|
---|
1093 | ('a b', NS(foo='a', bar='b')),
|
---|
1094 | ]
|
---|
1095 |
|
---|
1096 |
|
---|
1097 | class TestPositionalsNargsOptionalZeroOrMore(ParserTestCase):
|
---|
1098 | """Test an Optional narg followed by unlimited nargs"""
|
---|
1099 |
|
---|
1100 | argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='*')]
|
---|
1101 | failures = ['--foo']
|
---|
1102 | successes = [
|
---|
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'])),
|
---|
1107 | ]
|
---|
1108 |
|
---|
1109 |
|
---|
1110 | class TestPositionalsNargsOptionalOneOrMore(ParserTestCase):
|
---|
1111 | """Test an Optional narg followed by one or more nargs"""
|
---|
1112 |
|
---|
1113 | argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='+')]
|
---|
1114 | failures = ['', '--foo']
|
---|
1115 | successes = [
|
---|
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'])),
|
---|
1119 | ]
|
---|
1120 |
|
---|
1121 |
|
---|
1122 | class TestPositionalsChoicesString(ParserTestCase):
|
---|
1123 | """Test a set of single-character choices"""
|
---|
1124 |
|
---|
1125 | argument_signatures = [Sig('spam', choices=set('abcdefg'))]
|
---|
1126 | failures = ['', '--foo', 'h', '42', 'ef']
|
---|
1127 | successes = [
|
---|
1128 | ('a', NS(spam='a')),
|
---|
1129 | ('g', NS(spam='g')),
|
---|
1130 | ]
|
---|
1131 |
|
---|
1132 |
|
---|
1133 | class TestPositionalsChoicesInt(ParserTestCase):
|
---|
1134 | """Test a set of integer choices"""
|
---|
1135 |
|
---|
1136 | argument_signatures = [Sig('spam', type=int, choices=range(20))]
|
---|
1137 | failures = ['', '--foo', 'h', '42', 'ef']
|
---|
1138 | successes = [
|
---|
1139 | ('4', NS(spam=4)),
|
---|
1140 | ('15', NS(spam=15)),
|
---|
1141 | ]
|
---|
1142 |
|
---|
1143 |
|
---|
1144 | class TestPositionalsActionAppend(ParserTestCase):
|
---|
1145 | """Test the 'append' action"""
|
---|
1146 |
|
---|
1147 | argument_signatures = [
|
---|
1148 | Sig('spam', action='append'),
|
---|
1149 | Sig('spam', action='append', nargs=2),
|
---|
1150 | ]
|
---|
1151 | failures = ['', '--foo', 'a', 'a b', 'a b c d']
|
---|
1152 | successes = [
|
---|
1153 | ('a b c', NS(spam=['a', ['b', 'c']])),
|
---|
1154 | ]
|
---|
1155 |
|
---|
1156 | # ========================================
|
---|
1157 | # Combined optionals and positionals tests
|
---|
1158 | # ========================================
|
---|
1159 |
|
---|
1160 | class TestOptionalsNumericAndPositionals(ParserTestCase):
|
---|
1161 | """Tests negative number args when numeric options are present"""
|
---|
1162 |
|
---|
1163 | argument_signatures = [
|
---|
1164 | Sig('x', nargs='?'),
|
---|
1165 | Sig('-4', dest='y', action='store_true'),
|
---|
1166 | ]
|
---|
1167 | failures = ['-2', '-315']
|
---|
1168 | successes = [
|
---|
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)),
|
---|
1173 | ]
|
---|
1174 |
|
---|
1175 |
|
---|
1176 | class TestOptionalsAlmostNumericAndPositionals(ParserTestCase):
|
---|
1177 | """Tests negative number args when almost numeric options are present"""
|
---|
1178 |
|
---|
1179 | argument_signatures = [
|
---|
1180 | Sig('x', nargs='?'),
|
---|
1181 | Sig('-k4', dest='y', action='store_true'),
|
---|
1182 | ]
|
---|
1183 | failures = ['-k3']
|
---|
1184 | successes = [
|
---|
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)),
|
---|
1190 | ]
|
---|
1191 |
|
---|
1192 |
|
---|
1193 | class TestEmptyAndSpaceContainingArguments(ParserTestCase):
|
---|
1194 |
|
---|
1195 | argument_signatures = [
|
---|
1196 | Sig('x', nargs='?'),
|
---|
1197 | Sig('-y', '--yyy', dest='y'),
|
---|
1198 | ]
|
---|
1199 | failures = ['-y']
|
---|
1200 | successes = [
|
---|
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')),
|
---|
1209 | ]
|
---|
1210 |
|
---|
1211 |
|
---|
1212 | class TestPrefixCharacterOnlyArguments(ParserTestCase):
|
---|
1213 |
|
---|
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'),
|
---|
1219 | ]
|
---|
1220 | failures = ['-y', '+ -']
|
---|
1221 | successes = [
|
---|
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)),
|
---|
1228 | ]
|
---|
1229 |
|
---|
1230 |
|
---|
1231 | class TestNargsZeroOrMore(ParserTestCase):
|
---|
1232 | """Tests specifying an args for an Optional that accepts zero or more"""
|
---|
1233 |
|
---|
1234 | argument_signatures = [Sig('-x', nargs='*'), Sig('y', nargs='*')]
|
---|
1235 | failures = []
|
---|
1236 | successes = [
|
---|
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'])),
|
---|
1244 | ]
|
---|
1245 |
|
---|
1246 |
|
---|
1247 | class TestNargsRemainder(ParserTestCase):
|
---|
1248 | """Tests specifying a positional with nargs=REMAINDER"""
|
---|
1249 |
|
---|
1250 | argument_signatures = [Sig('x'), Sig('y', nargs='...'), Sig('-z')]
|
---|
1251 | failures = ['', '-z', '-z Z']
|
---|
1252 | successes = [
|
---|
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)),
|
---|
1257 | ]
|
---|
1258 |
|
---|
1259 |
|
---|
1260 | class TestOptionLike(ParserTestCase):
|
---|
1261 | """Tests options that may or may not be arguments"""
|
---|
1262 |
|
---|
1263 | argument_signatures = [
|
---|
1264 | Sig('-x', type=float),
|
---|
1265 | Sig('-3', type=float, dest='y'),
|
---|
1266 | Sig('z', nargs='*'),
|
---|
1267 | ]
|
---|
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']
|
---|
1272 | successes = [
|
---|
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'])),
|
---|
1284 | ]
|
---|
1285 |
|
---|
1286 |
|
---|
1287 | class TestDefaultSuppress(ParserTestCase):
|
---|
1288 | """Test actions with suppressed defaults"""
|
---|
1289 |
|
---|
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),
|
---|
1294 | ]
|
---|
1295 | failures = ['-x']
|
---|
1296 | successes = [
|
---|
1297 | ('', NS()),
|
---|
1298 | ('a', NS(foo='a')),
|
---|
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)),
|
---|
1303 | ]
|
---|
1304 |
|
---|
1305 |
|
---|
1306 | class TestParserDefaultSuppress(ParserTestCase):
|
---|
1307 | """Test actions with a parser-level default of SUPPRESS"""
|
---|
1308 |
|
---|
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'),
|
---|
1314 | ]
|
---|
1315 | failures = ['-x']
|
---|
1316 | successes = [
|
---|
1317 | ('', NS()),
|
---|
1318 | ('a', NS(foo='a')),
|
---|
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)),
|
---|
1323 | ]
|
---|
1324 |
|
---|
1325 |
|
---|
1326 | class TestParserDefault42(ParserTestCase):
|
---|
1327 | """Test actions with a parser-level default of 42"""
|
---|
1328 |
|
---|
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'),
|
---|
1334 | ]
|
---|
1335 | failures = ['-x']
|
---|
1336 | successes = [
|
---|
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)),
|
---|
1343 | ]
|
---|
1344 |
|
---|
1345 |
|
---|
1346 | class TestArgumentsFromFile(TempDirMixin, ParserTestCase):
|
---|
1347 | """Test reading arguments from a file"""
|
---|
1348 |
|
---|
1349 | def setUp(self):
|
---|
1350 | super(TestArgumentsFromFile, self).setUp()
|
---|
1351 | file_texts = [
|
---|
1352 | ('hello', 'hello world!\n'),
|
---|
1353 | ('recursive', '-a\n'
|
---|
1354 | 'A\n'
|
---|
1355 | '@hello'),
|
---|
1356 | ('invalid', '@no-such-path\n'),
|
---|
1357 | ]
|
---|
1358 | for path, text in file_texts:
|
---|
1359 | file = open(path, 'w')
|
---|
1360 | file.write(text)
|
---|
1361 | file.close()
|
---|
1362 |
|
---|
1363 | parser_signature = Sig(fromfile_prefix_chars='@')
|
---|
1364 | argument_signatures = [
|
---|
1365 | Sig('-a'),
|
---|
1366 | Sig('x'),
|
---|
1367 | Sig('y', nargs='+'),
|
---|
1368 | ]
|
---|
1369 | failures = ['', '-b', 'X', '@invalid', '@missing']
|
---|
1370 | successes = [
|
---|
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'])),
|
---|
1377 | (["-a", "", "X", "Y"], NS(a='', x='X', y=['Y'])),
|
---|
1378 | ]
|
---|
1379 |
|
---|
1380 |
|
---|
1381 | class TestArgumentsFromFileConverter(TempDirMixin, ParserTestCase):
|
---|
1382 | """Test reading arguments from a file"""
|
---|
1383 |
|
---|
1384 | def setUp(self):
|
---|
1385 | super(TestArgumentsFromFileConverter, self).setUp()
|
---|
1386 | file_texts = [
|
---|
1387 | ('hello', 'hello world!\n'),
|
---|
1388 | ]
|
---|
1389 | for path, text in file_texts:
|
---|
1390 | file = open(path, 'w')
|
---|
1391 | file.write(text)
|
---|
1392 | file.close()
|
---|
1393 |
|
---|
1394 | class FromFileConverterArgumentParser(ErrorRaisingArgumentParser):
|
---|
1395 |
|
---|
1396 | def convert_arg_line_to_args(self, arg_line):
|
---|
1397 | for arg in arg_line.split():
|
---|
1398 | if not arg.strip():
|
---|
1399 | continue
|
---|
1400 | yield arg
|
---|
1401 | parser_class = FromFileConverterArgumentParser
|
---|
1402 | parser_signature = Sig(fromfile_prefix_chars='@')
|
---|
1403 | argument_signatures = [
|
---|
1404 | Sig('y', nargs='+'),
|
---|
1405 | ]
|
---|
1406 | failures = []
|
---|
1407 | successes = [
|
---|
1408 | ('@hello X', NS(y=['hello', 'world!', 'X'])),
|
---|
1409 | ]
|
---|
1410 |
|
---|
1411 |
|
---|
1412 | # =====================
|
---|
1413 | # Type conversion tests
|
---|
1414 | # =====================
|
---|
1415 |
|
---|
1416 | class TestFileTypeRepr(TestCase):
|
---|
1417 |
|
---|
1418 | def test_r(self):
|
---|
1419 | type = argparse.FileType('r')
|
---|
1420 | self.assertEqual("FileType('r')", repr(type))
|
---|
1421 |
|
---|
1422 | def test_wb_1(self):
|
---|
1423 | type = argparse.FileType('wb', 1)
|
---|
1424 | self.assertEqual("FileType('wb', 1)", repr(type))
|
---|
1425 |
|
---|
1426 |
|
---|
1427 | class RFile(object):
|
---|
1428 | seen = {}
|
---|
1429 |
|
---|
1430 | def __init__(self, name):
|
---|
1431 | self.name = name
|
---|
1432 |
|
---|
1433 | __hash__ = None
|
---|
1434 |
|
---|
1435 | def __eq__(self, other):
|
---|
1436 | if other in self.seen:
|
---|
1437 | text = self.seen[other]
|
---|
1438 | else:
|
---|
1439 | text = self.seen[other] = other.read()
|
---|
1440 | other.close()
|
---|
1441 | if not isinstance(text, str):
|
---|
1442 | text = text.decode('ascii')
|
---|
1443 | return self.name == other.name == text
|
---|
1444 |
|
---|
1445 |
|
---|
1446 | class TestFileTypeR(TempDirMixin, ParserTestCase):
|
---|
1447 | """Test the FileType option/argument type for reading files"""
|
---|
1448 |
|
---|
1449 | def setUp(self):
|
---|
1450 | super(TestFileTypeR, self).setUp()
|
---|
1451 | for file_name in ['foo', 'bar']:
|
---|
1452 | file = open(os.path.join(self.temp_dir, file_name), 'w')
|
---|
1453 | file.write(file_name)
|
---|
1454 | file.close()
|
---|
1455 | self.create_readonly_file('readonly')
|
---|
1456 |
|
---|
1457 | argument_signatures = [
|
---|
1458 | Sig('-x', type=argparse.FileType()),
|
---|
1459 | Sig('spam', type=argparse.FileType('r')),
|
---|
1460 | ]
|
---|
1461 | failures = ['-x', '-x bar', 'non-existent-file.txt']
|
---|
1462 | successes = [
|
---|
1463 | ('foo', NS(x=None, spam=RFile('foo'))),
|
---|
1464 | ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
|
---|
1465 | ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
|
---|
1466 | ('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
|
---|
1467 | ('readonly', NS(x=None, spam=RFile('readonly'))),
|
---|
1468 | ]
|
---|
1469 |
|
---|
1470 | class TestFileTypeDefaults(TempDirMixin, ParserTestCase):
|
---|
1471 | """Test that a file is not created unless the default is needed"""
|
---|
1472 | def setUp(self):
|
---|
1473 | super(TestFileTypeDefaults, self).setUp()
|
---|
1474 | file = open(os.path.join(self.temp_dir, 'good'), 'w')
|
---|
1475 | file.write('good')
|
---|
1476 | file.close()
|
---|
1477 |
|
---|
1478 | argument_signatures = [
|
---|
1479 | Sig('-c', type=argparse.FileType('r'), default='no-file.txt'),
|
---|
1480 | ]
|
---|
1481 | # should provoke no such file error
|
---|
1482 | failures = ['']
|
---|
1483 | # should not provoke error because default file is created
|
---|
1484 | successes = [('-c good', NS(c=RFile('good')))]
|
---|
1485 |
|
---|
1486 |
|
---|
1487 | class TestFileTypeRB(TempDirMixin, ParserTestCase):
|
---|
1488 | """Test the FileType option/argument type for reading files"""
|
---|
1489 |
|
---|
1490 | def setUp(self):
|
---|
1491 | super(TestFileTypeRB, self).setUp()
|
---|
1492 | for file_name in ['foo', 'bar']:
|
---|
1493 | file = open(os.path.join(self.temp_dir, file_name), 'w')
|
---|
1494 | file.write(file_name)
|
---|
1495 | file.close()
|
---|
1496 |
|
---|
1497 | argument_signatures = [
|
---|
1498 | Sig('-x', type=argparse.FileType('rb')),
|
---|
1499 | Sig('spam', type=argparse.FileType('rb')),
|
---|
1500 | ]
|
---|
1501 | failures = ['-x', '-x bar']
|
---|
1502 | successes = [
|
---|
1503 | ('foo', NS(x=None, spam=RFile('foo'))),
|
---|
1504 | ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
|
---|
1505 | ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
|
---|
1506 | ('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
|
---|
1507 | ]
|
---|
1508 |
|
---|
1509 |
|
---|
1510 | class WFile(object):
|
---|
1511 | seen = set()
|
---|
1512 |
|
---|
1513 | def __init__(self, name):
|
---|
1514 | self.name = name
|
---|
1515 |
|
---|
1516 | __hash__ = None
|
---|
1517 |
|
---|
1518 | def __eq__(self, other):
|
---|
1519 | if other not in self.seen:
|
---|
1520 | text = 'Check that file is writable.'
|
---|
1521 | if 'b' in other.mode:
|
---|
1522 | text = text.encode('ascii')
|
---|
1523 | other.write(text)
|
---|
1524 | other.close()
|
---|
1525 | self.seen.add(other)
|
---|
1526 | return self.name == other.name
|
---|
1527 |
|
---|
1528 |
|
---|
1529 | @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
|
---|
1530 | "non-root user required")
|
---|
1531 | class TestFileTypeW(TempDirMixin, ParserTestCase):
|
---|
1532 | """Test the FileType option/argument type for writing files"""
|
---|
1533 |
|
---|
1534 | def setUp(self):
|
---|
1535 | super(TestFileTypeW, self).setUp()
|
---|
1536 | self.create_readonly_file('readonly')
|
---|
1537 |
|
---|
1538 | argument_signatures = [
|
---|
1539 | Sig('-x', type=argparse.FileType('w')),
|
---|
1540 | Sig('spam', type=argparse.FileType('w')),
|
---|
1541 | ]
|
---|
1542 | failures = ['-x', '-x bar']
|
---|
1543 | failures = ['-x', '-x bar', 'readonly']
|
---|
1544 | successes = [
|
---|
1545 | ('foo', NS(x=None, spam=WFile('foo'))),
|
---|
1546 | ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),
|
---|
1547 | ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))),
|
---|
1548 | ('-x - -', NS(x=sys.stdout, spam=sys.stdout)),
|
---|
1549 | ]
|
---|
1550 |
|
---|
1551 |
|
---|
1552 | class TestFileTypeWB(TempDirMixin, ParserTestCase):
|
---|
1553 |
|
---|
1554 | argument_signatures = [
|
---|
1555 | Sig('-x', type=argparse.FileType('wb')),
|
---|
1556 | Sig('spam', type=argparse.FileType('wb')),
|
---|
1557 | ]
|
---|
1558 | failures = ['-x', '-x bar']
|
---|
1559 | successes = [
|
---|
1560 | ('foo', NS(x=None, spam=WFile('foo'))),
|
---|
1561 | ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),
|
---|
1562 | ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))),
|
---|
1563 | ('-x - -', NS(x=sys.stdout, spam=sys.stdout)),
|
---|
1564 | ]
|
---|
1565 |
|
---|
1566 |
|
---|
1567 | class TestTypeCallable(ParserTestCase):
|
---|
1568 | """Test some callables as option/argument types"""
|
---|
1569 |
|
---|
1570 | argument_signatures = [
|
---|
1571 | Sig('--eggs', type=complex),
|
---|
1572 | Sig('spam', type=float),
|
---|
1573 | ]
|
---|
1574 | failures = ['a', '42j', '--eggs a', '--eggs 2i']
|
---|
1575 | successes = [
|
---|
1576 | ('--eggs=42 42', NS(eggs=42, spam=42.0)),
|
---|
1577 | ('--eggs 2j -- -1.5', NS(eggs=2j, spam=-1.5)),
|
---|
1578 | ('1024.675', NS(eggs=None, spam=1024.675)),
|
---|
1579 | ]
|
---|
1580 |
|
---|
1581 |
|
---|
1582 | class TestTypeUserDefined(ParserTestCase):
|
---|
1583 | """Test a user-defined option/argument type"""
|
---|
1584 |
|
---|
1585 | class MyType(TestCase):
|
---|
1586 |
|
---|
1587 | def __init__(self, value):
|
---|
1588 | self.value = value
|
---|
1589 |
|
---|
1590 | __hash__ = None
|
---|
1591 |
|
---|
1592 | def __eq__(self, other):
|
---|
1593 | return (type(self), self.value) == (type(other), other.value)
|
---|
1594 |
|
---|
1595 | argument_signatures = [
|
---|
1596 | Sig('-x', type=MyType),
|
---|
1597 | Sig('spam', type=MyType),
|
---|
1598 | ]
|
---|
1599 | failures = []
|
---|
1600 | successes = [
|
---|
1601 | ('a -x b', NS(x=MyType('b'), spam=MyType('a'))),
|
---|
1602 | ('-xf g', NS(x=MyType('f'), spam=MyType('g'))),
|
---|
1603 | ]
|
---|
1604 |
|
---|
1605 |
|
---|
1606 | class TestTypeClassicClass(ParserTestCase):
|
---|
1607 | """Test a classic class type"""
|
---|
1608 |
|
---|
1609 | class C:
|
---|
1610 |
|
---|
1611 | def __init__(self, value):
|
---|
1612 | self.value = value
|
---|
1613 |
|
---|
1614 | __hash__ = None
|
---|
1615 |
|
---|
1616 | def __eq__(self, other):
|
---|
1617 | return (type(self), self.value) == (type(other), other.value)
|
---|
1618 |
|
---|
1619 | argument_signatures = [
|
---|
1620 | Sig('-x', type=C),
|
---|
1621 | Sig('spam', type=C),
|
---|
1622 | ]
|
---|
1623 | failures = []
|
---|
1624 | successes = [
|
---|
1625 | ('a -x b', NS(x=C('b'), spam=C('a'))),
|
---|
1626 | ('-xf g', NS(x=C('f'), spam=C('g'))),
|
---|
1627 | ]
|
---|
1628 |
|
---|
1629 |
|
---|
1630 | class TestTypeRegistration(TestCase):
|
---|
1631 | """Test a user-defined type by registering it"""
|
---|
1632 |
|
---|
1633 | def test(self):
|
---|
1634 |
|
---|
1635 | def get_my_type(string):
|
---|
1636 | return 'my_type{%s}' % string
|
---|
1637 |
|
---|
1638 | parser = argparse.ArgumentParser()
|
---|
1639 | parser.register('type', 'my_type', get_my_type)
|
---|
1640 | parser.add_argument('-x', type='my_type')
|
---|
1641 | parser.add_argument('y', type='my_type')
|
---|
1642 |
|
---|
1643 | self.assertEqual(parser.parse_args('1'.split()),
|
---|
1644 | NS(x=None, y='my_type{1}'))
|
---|
1645 | self.assertEqual(parser.parse_args('-x 1 42'.split()),
|
---|
1646 | NS(x='my_type{1}', y='my_type{42}'))
|
---|
1647 |
|
---|
1648 |
|
---|
1649 | # ============
|
---|
1650 | # Action tests
|
---|
1651 | # ============
|
---|
1652 |
|
---|
1653 | class TestActionUserDefined(ParserTestCase):
|
---|
1654 | """Test a user-defined option/argument action"""
|
---|
1655 |
|
---|
1656 | class OptionalAction(argparse.Action):
|
---|
1657 |
|
---|
1658 | def __call__(self, parser, namespace, value, option_string=None):
|
---|
1659 | try:
|
---|
1660 | # check destination and option string
|
---|
1661 | assert self.dest == 'spam', 'dest: %s' % self.dest
|
---|
1662 | assert option_string == '-s', 'flag: %s' % option_string
|
---|
1663 | # when option is before argument, badger=2, and when
|
---|
1664 | # option is after argument, badger=<whatever was set>
|
---|
1665 | expected_ns = NS(spam=0.25)
|
---|
1666 | if value in [0.125, 0.625]:
|
---|
1667 | expected_ns.badger = 2
|
---|
1668 | elif value in [2.0]:
|
---|
1669 | expected_ns.badger = 84
|
---|
1670 | else:
|
---|
1671 | raise AssertionError('value: %s' % value)
|
---|
1672 | assert expected_ns == namespace, ('expected %s, got %s' %
|
---|
1673 | (expected_ns, namespace))
|
---|
1674 | except AssertionError:
|
---|
1675 | e = sys.exc_info()[1]
|
---|
1676 | raise ArgumentParserError('opt_action failed: %s' % e)
|
---|
1677 | setattr(namespace, 'spam', value)
|
---|
1678 |
|
---|
1679 | class PositionalAction(argparse.Action):
|
---|
1680 |
|
---|
1681 | def __call__(self, parser, namespace, value, option_string=None):
|
---|
1682 | try:
|
---|
1683 | assert option_string is None, ('option_string: %s' %
|
---|
1684 | option_string)
|
---|
1685 | # check destination
|
---|
1686 | assert self.dest == 'badger', 'dest: %s' % self.dest
|
---|
1687 | # when argument is before option, spam=0.25, and when
|
---|
1688 | # option is after argument, spam=<whatever was set>
|
---|
1689 | expected_ns = NS(badger=2)
|
---|
1690 | if value in [42, 84]:
|
---|
1691 | expected_ns.spam = 0.25
|
---|
1692 | elif value in [1]:
|
---|
1693 | expected_ns.spam = 0.625
|
---|
1694 | elif value in [2]:
|
---|
1695 | expected_ns.spam = 0.125
|
---|
1696 | else:
|
---|
1697 | raise AssertionError('value: %s' % value)
|
---|
1698 | assert expected_ns == namespace, ('expected %s, got %s' %
|
---|
1699 | (expected_ns, namespace))
|
---|
1700 | except AssertionError:
|
---|
1701 | e = sys.exc_info()[1]
|
---|
1702 | raise ArgumentParserError('arg_action failed: %s' % e)
|
---|
1703 | setattr(namespace, 'badger', value)
|
---|
1704 |
|
---|
1705 | argument_signatures = [
|
---|
1706 | Sig('-s', dest='spam', action=OptionalAction,
|
---|
1707 | type=float, default=0.25),
|
---|
1708 | Sig('badger', action=PositionalAction,
|
---|
1709 | type=int, nargs='?', default=2),
|
---|
1710 | ]
|
---|
1711 | failures = []
|
---|
1712 | successes = [
|
---|
1713 | ('-s0.125', NS(spam=0.125, badger=2)),
|
---|
1714 | ('42', NS(spam=0.25, badger=42)),
|
---|
1715 | ('-s 0.625 1', NS(spam=0.625, badger=1)),
|
---|
1716 | ('84 -s2', NS(spam=2.0, badger=84)),
|
---|
1717 | ]
|
---|
1718 |
|
---|
1719 |
|
---|
1720 | class TestActionRegistration(TestCase):
|
---|
1721 | """Test a user-defined action supplied by registering it"""
|
---|
1722 |
|
---|
1723 | class MyAction(argparse.Action):
|
---|
1724 |
|
---|
1725 | def __call__(self, parser, namespace, values, option_string=None):
|
---|
1726 | setattr(namespace, self.dest, 'foo[%s]' % values)
|
---|
1727 |
|
---|
1728 | def test(self):
|
---|
1729 |
|
---|
1730 | parser = argparse.ArgumentParser()
|
---|
1731 | parser.register('action', 'my_action', self.MyAction)
|
---|
1732 | parser.add_argument('badger', action='my_action')
|
---|
1733 |
|
---|
1734 | self.assertEqual(parser.parse_args(['1']), NS(badger='foo[1]'))
|
---|
1735 | self.assertEqual(parser.parse_args(['42']), NS(badger='foo[42]'))
|
---|
1736 |
|
---|
1737 |
|
---|
1738 | # ================
|
---|
1739 | # Subparsers tests
|
---|
1740 | # ================
|
---|
1741 |
|
---|
1742 | class TestAddSubparsers(TestCase):
|
---|
1743 | """Test the add_subparsers method"""
|
---|
1744 |
|
---|
1745 | def assertArgumentParserError(self, *args, **kwargs):
|
---|
1746 | self.assertRaises(ArgumentParserError, *args, **kwargs)
|
---|
1747 |
|
---|
1748 | def _get_parser(self, subparser_help=False, prefix_chars=None):
|
---|
1749 | # create a parser with a subparsers argument
|
---|
1750 | if prefix_chars:
|
---|
1751 | parser = ErrorRaisingArgumentParser(
|
---|
1752 | prog='PROG', description='main description', prefix_chars=prefix_chars)
|
---|
1753 | parser.add_argument(
|
---|
1754 | prefix_chars[0] * 2 + 'foo', action='store_true', help='foo help')
|
---|
1755 | else:
|
---|
1756 | parser = ErrorRaisingArgumentParser(
|
---|
1757 | prog='PROG', description='main description')
|
---|
1758 | parser.add_argument(
|
---|
1759 | '--foo', action='store_true', help='foo help')
|
---|
1760 | parser.add_argument(
|
---|
1761 | 'bar', type=float, help='bar help')
|
---|
1762 |
|
---|
1763 | # check that only one subparsers argument can be added
|
---|
1764 | subparsers = parser.add_subparsers(help='command help')
|
---|
1765 | self.assertArgumentParserError(parser.add_subparsers)
|
---|
1766 |
|
---|
1767 | # add first sub-parser
|
---|
1768 | parser1_kwargs = dict(description='1 description')
|
---|
1769 | if subparser_help:
|
---|
1770 | parser1_kwargs['help'] = '1 help'
|
---|
1771 | parser1 = subparsers.add_parser('1', **parser1_kwargs)
|
---|
1772 | parser1.add_argument('-w', type=int, help='w help')
|
---|
1773 | parser1.add_argument('x', choices='abc', help='x help')
|
---|
1774 |
|
---|
1775 | # add second sub-parser
|
---|
1776 | parser2_kwargs = dict(description='2 description')
|
---|
1777 | if subparser_help:
|
---|
1778 | parser2_kwargs['help'] = '2 help'
|
---|
1779 | parser2 = subparsers.add_parser('2', **parser2_kwargs)
|
---|
1780 | parser2.add_argument('-y', choices='123', help='y help')
|
---|
1781 | parser2.add_argument('z', type=complex, nargs='*', help='z help')
|
---|
1782 |
|
---|
1783 | # add third sub-parser
|
---|
1784 | parser3_kwargs = dict(description='3 description')
|
---|
1785 | if subparser_help:
|
---|
1786 | parser3_kwargs['help'] = '3 help'
|
---|
1787 | parser3 = subparsers.add_parser('3', **parser3_kwargs)
|
---|
1788 | parser3.add_argument('t', type=int, help='t help')
|
---|
1789 | parser3.add_argument('u', nargs='...', help='u help')
|
---|
1790 |
|
---|
1791 | # return the main parser
|
---|
1792 | return parser
|
---|
1793 |
|
---|
1794 | def setUp(self):
|
---|
1795 | super(TestAddSubparsers, self).setUp()
|
---|
1796 | self.parser = self._get_parser()
|
---|
1797 | self.command_help_parser = self._get_parser(subparser_help=True)
|
---|
1798 |
|
---|
1799 | def test_parse_args_failures(self):
|
---|
1800 | # check some failure cases:
|
---|
1801 | for args_str in ['', 'a', 'a a', '0.5 a', '0.5 1',
|
---|
1802 | '0.5 1 -y', '0.5 2 -w']:
|
---|
1803 | args = args_str.split()
|
---|
1804 | self.assertArgumentParserError(self.parser.parse_args, args)
|
---|
1805 |
|
---|
1806 | def test_parse_args(self):
|
---|
1807 | # check some non-failure cases:
|
---|
1808 | self.assertEqual(
|
---|
1809 | self.parser.parse_args('0.5 1 b -w 7'.split()),
|
---|
1810 | NS(foo=False, bar=0.5, w=7, x='b'),
|
---|
1811 | )
|
---|
1812 | self.assertEqual(
|
---|
1813 | self.parser.parse_args('0.25 --foo 2 -y 2 3j -- -1j'.split()),
|
---|
1814 | NS(foo=True, bar=0.25, y='2', z=[3j, -1j]),
|
---|
1815 | )
|
---|
1816 | self.assertEqual(
|
---|
1817 | self.parser.parse_args('--foo 0.125 1 c'.split()),
|
---|
1818 | NS(foo=True, bar=0.125, w=None, x='c'),
|
---|
1819 | )
|
---|
1820 | self.assertEqual(
|
---|
1821 | self.parser.parse_args('-1.5 3 11 -- a --foo 7 -- b'.split()),
|
---|
1822 | NS(foo=False, bar=-1.5, t=11, u=['a', '--foo', '7', '--', 'b']),
|
---|
1823 | )
|
---|
1824 |
|
---|
1825 | def test_parse_known_args(self):
|
---|
1826 | self.assertEqual(
|
---|
1827 | self.parser.parse_known_args('0.5 1 b -w 7'.split()),
|
---|
1828 | (NS(foo=False, bar=0.5, w=7, x='b'), []),
|
---|
1829 | )
|
---|
1830 | self.assertEqual(
|
---|
1831 | self.parser.parse_known_args('0.5 -p 1 b -w 7'.split()),
|
---|
1832 | (NS(foo=False, bar=0.5, w=7, x='b'), ['-p']),
|
---|
1833 | )
|
---|
1834 | self.assertEqual(
|
---|
1835 | self.parser.parse_known_args('0.5 1 b -w 7 -p'.split()),
|
---|
1836 | (NS(foo=False, bar=0.5, w=7, x='b'), ['-p']),
|
---|
1837 | )
|
---|
1838 | self.assertEqual(
|
---|
1839 | self.parser.parse_known_args('0.5 1 b -q -rs -w 7'.split()),
|
---|
1840 | (NS(foo=False, bar=0.5, w=7, x='b'), ['-q', '-rs']),
|
---|
1841 | )
|
---|
1842 | self.assertEqual(
|
---|
1843 | self.parser.parse_known_args('0.5 -W 1 b -X Y -w 7 Z'.split()),
|
---|
1844 | (NS(foo=False, bar=0.5, w=7, x='b'), ['-W', '-X', 'Y', 'Z']),
|
---|
1845 | )
|
---|
1846 |
|
---|
1847 | def test_dest(self):
|
---|
1848 | parser = ErrorRaisingArgumentParser()
|
---|
1849 | parser.add_argument('--foo', action='store_true')
|
---|
1850 | subparsers = parser.add_subparsers(dest='bar')
|
---|
1851 | parser1 = subparsers.add_parser('1')
|
---|
1852 | parser1.add_argument('baz')
|
---|
1853 | self.assertEqual(NS(foo=False, bar='1', baz='2'),
|
---|
1854 | parser.parse_args('1 2'.split()))
|
---|
1855 |
|
---|
1856 | def test_help(self):
|
---|
1857 | self.assertEqual(self.parser.format_usage(),
|
---|
1858 | 'usage: PROG [-h] [--foo] bar {1,2,3} ...\n')
|
---|
1859 | self.assertEqual(self.parser.format_help(), textwrap.dedent('''\
|
---|
1860 | usage: PROG [-h] [--foo] bar {1,2,3} ...
|
---|
1861 |
|
---|
1862 | main description
|
---|
1863 |
|
---|
1864 | positional arguments:
|
---|
1865 | bar bar help
|
---|
1866 | {1,2,3} command help
|
---|
1867 |
|
---|
1868 | optional arguments:
|
---|
1869 | -h, --help show this help message and exit
|
---|
1870 | --foo foo help
|
---|
1871 | '''))
|
---|
1872 |
|
---|
1873 | def test_help_extra_prefix_chars(self):
|
---|
1874 | # Make sure - is still used for help if it is a non-first prefix char
|
---|
1875 | parser = self._get_parser(prefix_chars='+:-')
|
---|
1876 | self.assertEqual(parser.format_usage(),
|
---|
1877 | 'usage: PROG [-h] [++foo] bar {1,2,3} ...\n')
|
---|
1878 | self.assertEqual(parser.format_help(), textwrap.dedent('''\
|
---|
1879 | usage: PROG [-h] [++foo] bar {1,2,3} ...
|
---|
1880 |
|
---|
1881 | main description
|
---|
1882 |
|
---|
1883 | positional arguments:
|
---|
1884 | bar bar help
|
---|
1885 | {1,2,3} command help
|
---|
1886 |
|
---|
1887 | optional arguments:
|
---|
1888 | -h, --help show this help message and exit
|
---|
1889 | ++foo foo help
|
---|
1890 | '''))
|
---|
1891 |
|
---|
1892 |
|
---|
1893 | def test_help_alternate_prefix_chars(self):
|
---|
1894 | parser = self._get_parser(prefix_chars='+:/')
|
---|
1895 | self.assertEqual(parser.format_usage(),
|
---|
1896 | 'usage: PROG [+h] [++foo] bar {1,2,3} ...\n')
|
---|
1897 | self.assertEqual(parser.format_help(), textwrap.dedent('''\
|
---|
1898 | usage: PROG [+h] [++foo] bar {1,2,3} ...
|
---|
1899 |
|
---|
1900 | main description
|
---|
1901 |
|
---|
1902 | positional arguments:
|
---|
1903 | bar bar help
|
---|
1904 | {1,2,3} command help
|
---|
1905 |
|
---|
1906 | optional arguments:
|
---|
1907 | +h, ++help show this help message and exit
|
---|
1908 | ++foo foo help
|
---|
1909 | '''))
|
---|
1910 |
|
---|
1911 | def test_parser_command_help(self):
|
---|
1912 | self.assertEqual(self.command_help_parser.format_usage(),
|
---|
1913 | 'usage: PROG [-h] [--foo] bar {1,2,3} ...\n')
|
---|
1914 | self.assertEqual(self.command_help_parser.format_help(),
|
---|
1915 | textwrap.dedent('''\
|
---|
1916 | usage: PROG [-h] [--foo] bar {1,2,3} ...
|
---|
1917 |
|
---|
1918 | main description
|
---|
1919 |
|
---|
1920 | positional arguments:
|
---|
1921 | bar bar help
|
---|
1922 | {1,2,3} command help
|
---|
1923 | 1 1 help
|
---|
1924 | 2 2 help
|
---|
1925 | 3 3 help
|
---|
1926 |
|
---|
1927 | optional arguments:
|
---|
1928 | -h, --help show this help message and exit
|
---|
1929 | --foo foo help
|
---|
1930 | '''))
|
---|
1931 |
|
---|
1932 | def test_subparser_title_help(self):
|
---|
1933 | parser = ErrorRaisingArgumentParser(prog='PROG',
|
---|
1934 | description='main description')
|
---|
1935 | parser.add_argument('--foo', action='store_true', help='foo help')
|
---|
1936 | parser.add_argument('bar', help='bar help')
|
---|
1937 | subparsers = parser.add_subparsers(title='subcommands',
|
---|
1938 | description='command help',
|
---|
1939 | help='additional text')
|
---|
1940 | parser1 = subparsers.add_parser('1')
|
---|
1941 | parser2 = subparsers.add_parser('2')
|
---|
1942 | self.assertEqual(parser.format_usage(),
|
---|
1943 | 'usage: PROG [-h] [--foo] bar {1,2} ...\n')
|
---|
1944 | self.assertEqual(parser.format_help(), textwrap.dedent('''\
|
---|
1945 | usage: PROG [-h] [--foo] bar {1,2} ...
|
---|
1946 |
|
---|
1947 | main description
|
---|
1948 |
|
---|
1949 | positional arguments:
|
---|
1950 | bar bar help
|
---|
1951 |
|
---|
1952 | optional arguments:
|
---|
1953 | -h, --help show this help message and exit
|
---|
1954 | --foo foo help
|
---|
1955 |
|
---|
1956 | subcommands:
|
---|
1957 | command help
|
---|
1958 |
|
---|
1959 | {1,2} additional text
|
---|
1960 | '''))
|
---|
1961 |
|
---|
1962 | def _test_subparser_help(self, args_str, expected_help):
|
---|
1963 | try:
|
---|
1964 | self.parser.parse_args(args_str.split())
|
---|
1965 | except ArgumentParserError:
|
---|
1966 | err = sys.exc_info()[1]
|
---|
1967 | if err.stdout != expected_help:
|
---|
1968 | print(repr(expected_help))
|
---|
1969 | print(repr(err.stdout))
|
---|
1970 | self.assertEqual(err.stdout, expected_help)
|
---|
1971 |
|
---|
1972 | def test_subparser1_help(self):
|
---|
1973 | self._test_subparser_help('5.0 1 -h', textwrap.dedent('''\
|
---|
1974 | usage: PROG bar 1 [-h] [-w W] {a,b,c}
|
---|
1975 |
|
---|
1976 | 1 description
|
---|
1977 |
|
---|
1978 | positional arguments:
|
---|
1979 | {a,b,c} x help
|
---|
1980 |
|
---|
1981 | optional arguments:
|
---|
1982 | -h, --help show this help message and exit
|
---|
1983 | -w W w help
|
---|
1984 | '''))
|
---|
1985 |
|
---|
1986 | def test_subparser2_help(self):
|
---|
1987 | self._test_subparser_help('5.0 2 -h', textwrap.dedent('''\
|
---|
1988 | usage: PROG bar 2 [-h] [-y {1,2,3}] [z [z ...]]
|
---|
1989 |
|
---|
1990 | 2 description
|
---|
1991 |
|
---|
1992 | positional arguments:
|
---|
1993 | z z help
|
---|
1994 |
|
---|
1995 | optional arguments:
|
---|
1996 | -h, --help show this help message and exit
|
---|
1997 | -y {1,2,3} y help
|
---|
1998 | '''))
|
---|
1999 |
|
---|
2000 | # ============
|
---|
2001 | # Groups tests
|
---|
2002 | # ============
|
---|
2003 |
|
---|
2004 | class TestPositionalsGroups(TestCase):
|
---|
2005 | """Tests that order of group positionals matches construction order"""
|
---|
2006 |
|
---|
2007 | def test_nongroup_first(self):
|
---|
2008 | parser = ErrorRaisingArgumentParser()
|
---|
2009 | parser.add_argument('foo')
|
---|
2010 | group = parser.add_argument_group('g')
|
---|
2011 | group.add_argument('bar')
|
---|
2012 | parser.add_argument('baz')
|
---|
2013 | expected = NS(foo='1', bar='2', baz='3')
|
---|
2014 | result = parser.parse_args('1 2 3'.split())
|
---|
2015 | self.assertEqual(expected, result)
|
---|
2016 |
|
---|
2017 | def test_group_first(self):
|
---|
2018 | parser = ErrorRaisingArgumentParser()
|
---|
2019 | group = parser.add_argument_group('xxx')
|
---|
2020 | group.add_argument('foo')
|
---|
2021 | parser.add_argument('bar')
|
---|
2022 | parser.add_argument('baz')
|
---|
2023 | expected = NS(foo='1', bar='2', baz='3')
|
---|
2024 | result = parser.parse_args('1 2 3'.split())
|
---|
2025 | self.assertEqual(expected, result)
|
---|
2026 |
|
---|
2027 | def test_interleaved_groups(self):
|
---|
2028 | parser = ErrorRaisingArgumentParser()
|
---|
2029 | group = parser.add_argument_group('xxx')
|
---|
2030 | parser.add_argument('foo')
|
---|
2031 | group.add_argument('bar')
|
---|
2032 | parser.add_argument('baz')
|
---|
2033 | group = parser.add_argument_group('yyy')
|
---|
2034 | group.add_argument('frell')
|
---|
2035 | expected = NS(foo='1', bar='2', baz='3', frell='4')
|
---|
2036 | result = parser.parse_args('1 2 3 4'.split())
|
---|
2037 | self.assertEqual(expected, result)
|
---|
2038 |
|
---|
2039 | # ===================
|
---|
2040 | # Parent parser tests
|
---|
2041 | # ===================
|
---|
2042 |
|
---|
2043 | class TestParentParsers(TestCase):
|
---|
2044 | """Tests that parsers can be created with parent parsers"""
|
---|
2045 |
|
---|
2046 | def assertArgumentParserError(self, *args, **kwargs):
|
---|
2047 | self.assertRaises(ArgumentParserError, *args, **kwargs)
|
---|
2048 |
|
---|
2049 | def setUp(self):
|
---|
2050 | super(TestParentParsers, self).setUp()
|
---|
2051 | self.wxyz_parent = ErrorRaisingArgumentParser(add_help=False)
|
---|
2052 | self.wxyz_parent.add_argument('--w')
|
---|
2053 | x_group = self.wxyz_parent.add_argument_group('x')
|
---|
2054 | x_group.add_argument('-y')
|
---|
2055 | self.wxyz_parent.add_argument('z')
|
---|
2056 |
|
---|
2057 | self.abcd_parent = ErrorRaisingArgumentParser(add_help=False)
|
---|
2058 | self.abcd_parent.add_argument('a')
|
---|
2059 | self.abcd_parent.add_argument('-b')
|
---|
2060 | c_group = self.abcd_parent.add_argument_group('c')
|
---|
2061 | c_group.add_argument('--d')
|
---|
2062 |
|
---|
2063 | self.w_parent = ErrorRaisingArgumentParser(add_help=False)
|
---|
2064 | self.w_parent.add_argument('--w')
|
---|
2065 |
|
---|
2066 | self.z_parent = ErrorRaisingArgumentParser(add_help=False)
|
---|
2067 | self.z_parent.add_argument('z')
|
---|
2068 |
|
---|
2069 | # parents with mutually exclusive groups
|
---|
2070 | self.ab_mutex_parent = ErrorRaisingArgumentParser(add_help=False)
|
---|
2071 | group = self.ab_mutex_parent.add_mutually_exclusive_group()
|
---|
2072 | group.add_argument('-a', action='store_true')
|
---|
2073 | group.add_argument('-b', action='store_true')
|
---|
2074 |
|
---|
2075 | self.main_program = os.path.basename(sys.argv[0])
|
---|
2076 |
|
---|
2077 | def test_single_parent(self):
|
---|
2078 | parser = ErrorRaisingArgumentParser(parents=[self.wxyz_parent])
|
---|
2079 | self.assertEqual(parser.parse_args('-y 1 2 --w 3'.split()),
|
---|
2080 | NS(w='3', y='1', z='2'))
|
---|
2081 |
|
---|
2082 | def test_single_parent_mutex(self):
|
---|
2083 | self._test_mutex_ab(self.ab_mutex_parent.parse_args)
|
---|
2084 | parser = ErrorRaisingArgumentParser(parents=[self.ab_mutex_parent])
|
---|
2085 | self._test_mutex_ab(parser.parse_args)
|
---|
2086 |
|
---|
2087 | def test_single_granparent_mutex(self):
|
---|
2088 | parents = [self.ab_mutex_parent]
|
---|
2089 | parser = ErrorRaisingArgumentParser(add_help=False, parents=parents)
|
---|
2090 | parser = ErrorRaisingArgumentParser(parents=[parser])
|
---|
2091 | self._test_mutex_ab(parser.parse_args)
|
---|
2092 |
|
---|
2093 | def _test_mutex_ab(self, parse_args):
|
---|
2094 | self.assertEqual(parse_args([]), NS(a=False, b=False))
|
---|
2095 | self.assertEqual(parse_args(['-a']), NS(a=True, b=False))
|
---|
2096 | self.assertEqual(parse_args(['-b']), NS(a=False, b=True))
|
---|
2097 | self.assertArgumentParserError(parse_args, ['-a', '-b'])
|
---|
2098 | self.assertArgumentParserError(parse_args, ['-b', '-a'])
|
---|
2099 | self.assertArgumentParserError(parse_args, ['-c'])
|
---|
2100 | self.assertArgumentParserError(parse_args, ['-a', '-c'])
|
---|
2101 | self.assertArgumentParserError(parse_args, ['-b', '-c'])
|
---|
2102 |
|
---|
2103 | def test_multiple_parents(self):
|
---|
2104 | parents = [self.abcd_parent, self.wxyz_parent]
|
---|
2105 | parser = ErrorRaisingArgumentParser(parents=parents)
|
---|
2106 | self.assertEqual(parser.parse_args('--d 1 --w 2 3 4'.split()),
|
---|
2107 | NS(a='3', b=None, d='1', w='2', y=None, z='4'))
|
---|
2108 |
|
---|
2109 | def test_multiple_parents_mutex(self):
|
---|
2110 | parents = [self.ab_mutex_parent, self.wxyz_parent]
|
---|
2111 | parser = ErrorRaisingArgumentParser(parents=parents)
|
---|
2112 | self.assertEqual(parser.parse_args('-a --w 2 3'.split()),
|
---|
2113 | NS(a=True, b=False, w='2', y=None, z='3'))
|
---|
2114 | self.assertArgumentParserError(
|
---|
2115 | parser.parse_args, '-a --w 2 3 -b'.split())
|
---|
2116 | self.assertArgumentParserError(
|
---|
2117 | parser.parse_args, '-a -b --w 2 3'.split())
|
---|
2118 |
|
---|
2119 | def test_conflicting_parents(self):
|
---|
2120 | self.assertRaises(
|
---|
2121 | argparse.ArgumentError,
|
---|
2122 | argparse.ArgumentParser,
|
---|
2123 | parents=[self.w_parent, self.wxyz_parent])
|
---|
2124 |
|
---|
2125 | def test_conflicting_parents_mutex(self):
|
---|
2126 | self.assertRaises(
|
---|
2127 | argparse.ArgumentError,
|
---|
2128 | argparse.ArgumentParser,
|
---|
2129 | parents=[self.abcd_parent, self.ab_mutex_parent])
|
---|
2130 |
|
---|
2131 | def test_same_argument_name_parents(self):
|
---|
2132 | parents = [self.wxyz_parent, self.z_parent]
|
---|
2133 | parser = ErrorRaisingArgumentParser(parents=parents)
|
---|
2134 | self.assertEqual(parser.parse_args('1 2'.split()),
|
---|
2135 | NS(w=None, y=None, z='2'))
|
---|
2136 |
|
---|
2137 | def test_subparser_parents(self):
|
---|
2138 | parser = ErrorRaisingArgumentParser()
|
---|
2139 | subparsers = parser.add_subparsers()
|
---|
2140 | abcde_parser = subparsers.add_parser('bar', parents=[self.abcd_parent])
|
---|
2141 | abcde_parser.add_argument('e')
|
---|
2142 | self.assertEqual(parser.parse_args('bar -b 1 --d 2 3 4'.split()),
|
---|
2143 | NS(a='3', b='1', d='2', e='4'))
|
---|
2144 |
|
---|
2145 | def test_subparser_parents_mutex(self):
|
---|
2146 | parser = ErrorRaisingArgumentParser()
|
---|
2147 | subparsers = parser.add_subparsers()
|
---|
2148 | parents = [self.ab_mutex_parent]
|
---|
2149 | abc_parser = subparsers.add_parser('foo', parents=parents)
|
---|
2150 | c_group = abc_parser.add_argument_group('c_group')
|
---|
2151 | c_group.add_argument('c')
|
---|
2152 | parents = [self.wxyz_parent, self.ab_mutex_parent]
|
---|
2153 | wxyzabe_parser = subparsers.add_parser('bar', parents=parents)
|
---|
2154 | wxyzabe_parser.add_argument('e')
|
---|
2155 | self.assertEqual(parser.parse_args('foo -a 4'.split()),
|
---|
2156 | NS(a=True, b=False, c='4'))
|
---|
2157 | self.assertEqual(parser.parse_args('bar -b --w 2 3 4'.split()),
|
---|
2158 | NS(a=False, b=True, w='2', y=None, z='3', e='4'))
|
---|
2159 | self.assertArgumentParserError(
|
---|
2160 | parser.parse_args, 'foo -a -b 4'.split())
|
---|
2161 | self.assertArgumentParserError(
|
---|
2162 | parser.parse_args, 'bar -b -a 4'.split())
|
---|
2163 |
|
---|
2164 | def test_parent_help(self):
|
---|
2165 | parents = [self.abcd_parent, self.wxyz_parent]
|
---|
2166 | parser = ErrorRaisingArgumentParser(parents=parents)
|
---|
2167 | parser_help = parser.format_help()
|
---|
2168 | progname = self.main_program
|
---|
2169 | self.assertEqual(parser_help, textwrap.dedent('''\
|
---|
2170 | usage: {}{}[-h] [-b B] [--d D] [--w W] [-y Y] a z
|
---|
2171 |
|
---|
2172 | positional arguments:
|
---|
2173 | a
|
---|
2174 | z
|
---|
2175 |
|
---|
2176 | optional arguments:
|
---|
2177 | -h, --help show this help message and exit
|
---|
2178 | -b B
|
---|
2179 | --w W
|
---|
2180 |
|
---|
2181 | c:
|
---|
2182 | --d D
|
---|
2183 |
|
---|
2184 | x:
|
---|
2185 | -y Y
|
---|
2186 | '''.format(progname, ' ' if progname else '' )))
|
---|
2187 |
|
---|
2188 | def test_groups_parents(self):
|
---|
2189 | parent = ErrorRaisingArgumentParser(add_help=False)
|
---|
2190 | g = parent.add_argument_group(title='g', description='gd')
|
---|
2191 | g.add_argument('-w')
|
---|
2192 | g.add_argument('-x')
|
---|
2193 | m = parent.add_mutually_exclusive_group()
|
---|
2194 | m.add_argument('-y')
|
---|
2195 | m.add_argument('-z')
|
---|
2196 | parser = ErrorRaisingArgumentParser(parents=[parent])
|
---|
2197 |
|
---|
2198 | self.assertRaises(ArgumentParserError, parser.parse_args,
|
---|
2199 | ['-y', 'Y', '-z', 'Z'])
|
---|
2200 |
|
---|
2201 | parser_help = parser.format_help()
|
---|
2202 | progname = self.main_program
|
---|
2203 | self.assertEqual(parser_help, textwrap.dedent('''\
|
---|
2204 | usage: {}{}[-h] [-w W] [-x X] [-y Y | -z Z]
|
---|
2205 |
|
---|
2206 | optional arguments:
|
---|
2207 | -h, --help show this help message and exit
|
---|
2208 | -y Y
|
---|
2209 | -z Z
|
---|
2210 |
|
---|
2211 | g:
|
---|
2212 | gd
|
---|
2213 |
|
---|
2214 | -w W
|
---|
2215 | -x X
|
---|
2216 | '''.format(progname, ' ' if progname else '' )))
|
---|
2217 |
|
---|
2218 | # ==============================
|
---|
2219 | # Mutually exclusive group tests
|
---|
2220 | # ==============================
|
---|
2221 |
|
---|
2222 | class TestMutuallyExclusiveGroupErrors(TestCase):
|
---|
2223 |
|
---|
2224 | def test_invalid_add_argument_group(self):
|
---|
2225 | parser = ErrorRaisingArgumentParser()
|
---|
2226 | raises = self.assertRaises
|
---|
2227 | raises(TypeError, parser.add_mutually_exclusive_group, title='foo')
|
---|
2228 |
|
---|
2229 | def test_invalid_add_argument(self):
|
---|
2230 | parser = ErrorRaisingArgumentParser()
|
---|
2231 | group = parser.add_mutually_exclusive_group()
|
---|
2232 | add_argument = group.add_argument
|
---|
2233 | raises = self.assertRaises
|
---|
2234 | raises(ValueError, add_argument, '--foo', required=True)
|
---|
2235 | raises(ValueError, add_argument, 'bar')
|
---|
2236 | raises(ValueError, add_argument, 'bar', nargs='+')
|
---|
2237 | raises(ValueError, add_argument, 'bar', nargs=1)
|
---|
2238 | raises(ValueError, add_argument, 'bar', nargs=argparse.PARSER)
|
---|
2239 |
|
---|
2240 | def test_help(self):
|
---|
2241 | parser = ErrorRaisingArgumentParser(prog='PROG')
|
---|
2242 | group1 = parser.add_mutually_exclusive_group()
|
---|
2243 | group1.add_argument('--foo', action='store_true')
|
---|
2244 | group1.add_argument('--bar', action='store_false')
|
---|
2245 | group2 = parser.add_mutually_exclusive_group()
|
---|
2246 | group2.add_argument('--soup', action='store_true')
|
---|
2247 | group2.add_argument('--nuts', action='store_false')
|
---|
2248 | expected = '''\
|
---|
2249 | usage: PROG [-h] [--foo | --bar] [--soup | --nuts]
|
---|
2250 |
|
---|
2251 | optional arguments:
|
---|
2252 | -h, --help show this help message and exit
|
---|
2253 | --foo
|
---|
2254 | --bar
|
---|
2255 | --soup
|
---|
2256 | --nuts
|
---|
2257 | '''
|
---|
2258 | self.assertEqual(parser.format_help(), textwrap.dedent(expected))
|
---|
2259 |
|
---|
2260 | class MEMixin(object):
|
---|
2261 |
|
---|
2262 | def test_failures_when_not_required(self):
|
---|
2263 | parse_args = self.get_parser(required=False).parse_args
|
---|
2264 | error = ArgumentParserError
|
---|
2265 | for args_string in self.failures:
|
---|
2266 | self.assertRaises(error, parse_args, args_string.split())
|
---|
2267 |
|
---|
2268 | def test_failures_when_required(self):
|
---|
2269 | parse_args = self.get_parser(required=True).parse_args
|
---|
2270 | error = ArgumentParserError
|
---|
2271 | for args_string in self.failures + ['']:
|
---|
2272 | self.assertRaises(error, parse_args, args_string.split())
|
---|
2273 |
|
---|
2274 | def test_successes_when_not_required(self):
|
---|
2275 | parse_args = self.get_parser(required=False).parse_args
|
---|
2276 | successes = self.successes + self.successes_when_not_required
|
---|
2277 | for args_string, expected_ns in successes:
|
---|
2278 | actual_ns = parse_args(args_string.split())
|
---|
2279 | self.assertEqual(actual_ns, expected_ns)
|
---|
2280 |
|
---|
2281 | def test_successes_when_required(self):
|
---|
2282 | parse_args = self.get_parser(required=True).parse_args
|
---|
2283 | for args_string, expected_ns in self.successes:
|
---|
2284 | actual_ns = parse_args(args_string.split())
|
---|
2285 | self.assertEqual(actual_ns, expected_ns)
|
---|
2286 |
|
---|
2287 | def test_usage_when_not_required(self):
|
---|
2288 | format_usage = self.get_parser(required=False).format_usage
|
---|
2289 | expected_usage = self.usage_when_not_required
|
---|
2290 | self.assertEqual(format_usage(), textwrap.dedent(expected_usage))
|
---|
2291 |
|
---|
2292 | def test_usage_when_required(self):
|
---|
2293 | format_usage = self.get_parser(required=True).format_usage
|
---|
2294 | expected_usage = self.usage_when_required
|
---|
2295 | self.assertEqual(format_usage(), textwrap.dedent(expected_usage))
|
---|
2296 |
|
---|
2297 | def test_help_when_not_required(self):
|
---|
2298 | format_help = self.get_parser(required=False).format_help
|
---|
2299 | help = self.usage_when_not_required + self.help
|
---|
2300 | self.assertEqual(format_help(), textwrap.dedent(help))
|
---|
2301 |
|
---|
2302 | def test_help_when_required(self):
|
---|
2303 | format_help = self.get_parser(required=True).format_help
|
---|
2304 | help = self.usage_when_required + self.help
|
---|
2305 | self.assertEqual(format_help(), textwrap.dedent(help))
|
---|
2306 |
|
---|
2307 |
|
---|
2308 | class TestMutuallyExclusiveSimple(MEMixin, TestCase):
|
---|
2309 |
|
---|
2310 | def get_parser(self, required=None):
|
---|
2311 | parser = ErrorRaisingArgumentParser(prog='PROG')
|
---|
2312 | group = parser.add_mutually_exclusive_group(required=required)
|
---|
2313 | group.add_argument('--bar', help='bar help')
|
---|
2314 | group.add_argument('--baz', nargs='?', const='Z', help='baz help')
|
---|
2315 | return parser
|
---|
2316 |
|
---|
2317 | failures = ['--bar X --baz Y', '--bar X --baz']
|
---|
2318 | successes = [
|
---|
2319 | ('--bar X', NS(bar='X', baz=None)),
|
---|
2320 | ('--bar X --bar Z', NS(bar='Z', baz=None)),
|
---|
2321 | ('--baz Y', NS(bar=None, baz='Y')),
|
---|
2322 | ('--baz', NS(bar=None, baz='Z')),
|
---|
2323 | ]
|
---|
2324 | successes_when_not_required = [
|
---|
2325 | ('', NS(bar=None, baz=None)),
|
---|
2326 | ]
|
---|
2327 |
|
---|
2328 | usage_when_not_required = '''\
|
---|
2329 | usage: PROG [-h] [--bar BAR | --baz [BAZ]]
|
---|
2330 | '''
|
---|
2331 | usage_when_required = '''\
|
---|
2332 | usage: PROG [-h] (--bar BAR | --baz [BAZ])
|
---|
2333 | '''
|
---|
2334 | help = '''\
|
---|
2335 |
|
---|
2336 | optional arguments:
|
---|
2337 | -h, --help show this help message and exit
|
---|
2338 | --bar BAR bar help
|
---|
2339 | --baz [BAZ] baz help
|
---|
2340 | '''
|
---|
2341 |
|
---|
2342 |
|
---|
2343 | class TestMutuallyExclusiveLong(MEMixin, TestCase):
|
---|
2344 |
|
---|
2345 | def get_parser(self, required=None):
|
---|
2346 | parser = ErrorRaisingArgumentParser(prog='PROG')
|
---|
2347 | parser.add_argument('--abcde', help='abcde help')
|
---|
2348 | parser.add_argument('--fghij', help='fghij help')
|
---|
2349 | group = parser.add_mutually_exclusive_group(required=required)
|
---|
2350 | group.add_argument('--klmno', help='klmno help')
|
---|
2351 | group.add_argument('--pqrst', help='pqrst help')
|
---|
2352 | return parser
|
---|
2353 |
|
---|
2354 | failures = ['--klmno X --pqrst Y']
|
---|
2355 | successes = [
|
---|
2356 | ('--klmno X', NS(abcde=None, fghij=None, klmno='X', pqrst=None)),
|
---|
2357 | ('--abcde Y --klmno X',
|
---|
2358 | NS(abcde='Y', fghij=None, klmno='X', pqrst=None)),
|
---|
2359 | ('--pqrst X', NS(abcde=None, fghij=None, klmno=None, pqrst='X')),
|
---|
2360 | ('--pqrst X --fghij Y',
|
---|
2361 | NS(abcde=None, fghij='Y', klmno=None, pqrst='X')),
|
---|
2362 | ]
|
---|
2363 | successes_when_not_required = [
|
---|
2364 | ('', NS(abcde=None, fghij=None, klmno=None, pqrst=None)),
|
---|
2365 | ]
|
---|
2366 |
|
---|
2367 | usage_when_not_required = '''\
|
---|
2368 | usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
|
---|
2369 | [--klmno KLMNO | --pqrst PQRST]
|
---|
2370 | '''
|
---|
2371 | usage_when_required = '''\
|
---|
2372 | usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
|
---|
2373 | (--klmno KLMNO | --pqrst PQRST)
|
---|
2374 | '''
|
---|
2375 | help = '''\
|
---|
2376 |
|
---|
2377 | optional arguments:
|
---|
2378 | -h, --help show this help message and exit
|
---|
2379 | --abcde ABCDE abcde help
|
---|
2380 | --fghij FGHIJ fghij help
|
---|
2381 | --klmno KLMNO klmno help
|
---|
2382 | --pqrst PQRST pqrst help
|
---|
2383 | '''
|
---|
2384 |
|
---|
2385 |
|
---|
2386 | class TestMutuallyExclusiveFirstSuppressed(MEMixin, TestCase):
|
---|
2387 |
|
---|
2388 | def get_parser(self, required):
|
---|
2389 | parser = ErrorRaisingArgumentParser(prog='PROG')
|
---|
2390 | group = parser.add_mutually_exclusive_group(required=required)
|
---|
2391 | group.add_argument('-x', help=argparse.SUPPRESS)
|
---|
2392 | group.add_argument('-y', action='store_false', help='y help')
|
---|
2393 | return parser
|
---|
2394 |
|
---|
2395 | failures = ['-x X -y']
|
---|
2396 | successes = [
|
---|
2397 | ('-x X', NS(x='X', y=True)),
|
---|
2398 | ('-x X -x Y', NS(x='Y', y=True)),
|
---|
2399 | ('-y', NS(x=None, y=False)),
|
---|
2400 | ]
|
---|
2401 | successes_when_not_required = [
|
---|
2402 | ('', NS(x=None, y=True)),
|
---|
2403 | ]
|
---|
2404 |
|
---|
2405 | usage_when_not_required = '''\
|
---|
2406 | usage: PROG [-h] [-y]
|
---|
2407 | '''
|
---|
2408 | usage_when_required = '''\
|
---|
2409 | usage: PROG [-h] -y
|
---|
2410 | '''
|
---|
2411 | help = '''\
|
---|
2412 |
|
---|
2413 | optional arguments:
|
---|
2414 | -h, --help show this help message and exit
|
---|
2415 | -y y help
|
---|
2416 | '''
|
---|
2417 |
|
---|
2418 |
|
---|
2419 | class TestMutuallyExclusiveManySuppressed(MEMixin, TestCase):
|
---|
2420 |
|
---|
2421 | def get_parser(self, required):
|
---|
2422 | parser = ErrorRaisingArgumentParser(prog='PROG')
|
---|
2423 | group = parser.add_mutually_exclusive_group(required=required)
|
---|
2424 | add = group.add_argument
|
---|
2425 | add('--spam', action='store_true', help=argparse.SUPPRESS)
|
---|
2426 | add('--badger', action='store_false', help=argparse.SUPPRESS)
|
---|
2427 | add('--bladder', help=argparse.SUPPRESS)
|
---|
2428 | return parser
|
---|
2429 |
|
---|
2430 | failures = [
|
---|
2431 | '--spam --badger',
|
---|
2432 | '--badger --bladder B',
|
---|
2433 | '--bladder B --spam',
|
---|
2434 | ]
|
---|
2435 | successes = [
|
---|
2436 | ('--spam', NS(spam=True, badger=True, bladder=None)),
|
---|
2437 | ('--badger', NS(spam=False, badger=False, bladder=None)),
|
---|
2438 | ('--bladder B', NS(spam=False, badger=True, bladder='B')),
|
---|
2439 | ('--spam --spam', NS(spam=True, badger=True, bladder=None)),
|
---|
2440 | ]
|
---|
2441 | successes_when_not_required = [
|
---|
2442 | ('', NS(spam=False, badger=True, bladder=None)),
|
---|
2443 | ]
|
---|
2444 |
|
---|
2445 | usage_when_required = usage_when_not_required = '''\
|
---|
2446 | usage: PROG [-h]
|
---|
2447 | '''
|
---|
2448 | help = '''\
|
---|
2449 |
|
---|
2450 | optional arguments:
|
---|
2451 | -h, --help show this help message and exit
|
---|
2452 | '''
|
---|
2453 |
|
---|
2454 |
|
---|
2455 | class TestMutuallyExclusiveOptionalAndPositional(MEMixin, TestCase):
|
---|
2456 |
|
---|
2457 | def get_parser(self, required):
|
---|
2458 | parser = ErrorRaisingArgumentParser(prog='PROG')
|
---|
2459 | group = parser.add_mutually_exclusive_group(required=required)
|
---|
2460 | group.add_argument('--foo', action='store_true', help='FOO')
|
---|
2461 | group.add_argument('--spam', help='SPAM')
|
---|
2462 | group.add_argument('badger', nargs='*', default='X', help='BADGER')
|
---|
2463 | return parser
|
---|
2464 |
|
---|
2465 | failures = [
|
---|
2466 | '--foo --spam S',
|
---|
2467 | '--spam S X',
|
---|
2468 | 'X --foo',
|
---|
2469 | 'X Y Z --spam S',
|
---|
2470 | '--foo X Y',
|
---|
2471 | ]
|
---|
2472 | successes = [
|
---|
2473 | ('--foo', NS(foo=True, spam=None, badger='X')),
|
---|
2474 | ('--spam S', NS(foo=False, spam='S', badger='X')),
|
---|
2475 | ('X', NS(foo=False, spam=None, badger=['X'])),
|
---|
2476 | ('X Y Z', NS(foo=False, spam=None, badger=['X', 'Y', 'Z'])),
|
---|
2477 | ]
|
---|
2478 | successes_when_not_required = [
|
---|
2479 | ('', NS(foo=False, spam=None, badger='X')),
|
---|
2480 | ]
|
---|
2481 |
|
---|
2482 | usage_when_not_required = '''\
|
---|
2483 | usage: PROG [-h] [--foo | --spam SPAM | badger [badger ...]]
|
---|
2484 | '''
|
---|
2485 | usage_when_required = '''\
|
---|
2486 | usage: PROG [-h] (--foo | --spam SPAM | badger [badger ...])
|
---|
2487 | '''
|
---|
2488 | help = '''\
|
---|
2489 |
|
---|
2490 | positional arguments:
|
---|
2491 | badger BADGER
|
---|
2492 |
|
---|
2493 | optional arguments:
|
---|
2494 | -h, --help show this help message and exit
|
---|
2495 | --foo FOO
|
---|
2496 | --spam SPAM SPAM
|
---|
2497 | '''
|
---|
2498 |
|
---|
2499 |
|
---|
2500 | class TestMutuallyExclusiveOptionalsMixed(MEMixin, TestCase):
|
---|
2501 |
|
---|
2502 | def get_parser(self, required):
|
---|
2503 | parser = ErrorRaisingArgumentParser(prog='PROG')
|
---|
2504 | parser.add_argument('-x', action='store_true', help='x help')
|
---|
2505 | group = parser.add_mutually_exclusive_group(required=required)
|
---|
2506 | group.add_argument('-a', action='store_true', help='a help')
|
---|
2507 | group.add_argument('-b', action='store_true', help='b help')
|
---|
2508 | parser.add_argument('-y', action='store_true', help='y help')
|
---|
2509 | group.add_argument('-c', action='store_true', help='c help')
|
---|
2510 | return parser
|
---|
2511 |
|
---|
2512 | failures = ['-a -b', '-b -c', '-a -c', '-a -b -c']
|
---|
2513 | successes = [
|
---|
2514 | ('-a', NS(a=True, b=False, c=False, x=False, y=False)),
|
---|
2515 | ('-b', NS(a=False, b=True, c=False, x=False, y=False)),
|
---|
2516 | ('-c', NS(a=False, b=False, c=True, x=False, y=False)),
|
---|
2517 | ('-a -x', NS(a=True, b=False, c=False, x=True, y=False)),
|
---|
2518 | ('-y -b', NS(a=False, b=True, c=False, x=False, y=True)),
|
---|
2519 | ('-x -y -c', NS(a=False, b=False, c=True, x=True, y=True)),
|
---|
2520 | ]
|
---|
2521 | successes_when_not_required = [
|
---|
2522 | ('', NS(a=False, b=False, c=False, x=False, y=False)),
|
---|
2523 | ('-x', NS(a=False, b=False, c=False, x=True, y=False)),
|
---|
2524 | ('-y', NS(a=False, b=False, c=False, x=False, y=True)),
|
---|
2525 | ]
|
---|
2526 |
|
---|
2527 | usage_when_required = usage_when_not_required = '''\
|
---|
2528 | usage: PROG [-h] [-x] [-a] [-b] [-y] [-c]
|
---|
2529 | '''
|
---|
2530 | help = '''\
|
---|
2531 |
|
---|
2532 | optional arguments:
|
---|
2533 | -h, --help show this help message and exit
|
---|
2534 | -x x help
|
---|
2535 | -a a help
|
---|
2536 | -b b help
|
---|
2537 | -y y help
|
---|
2538 | -c c help
|
---|
2539 | '''
|
---|
2540 |
|
---|
2541 |
|
---|
2542 | class TestMutuallyExclusiveInGroup(MEMixin, TestCase):
|
---|
2543 |
|
---|
2544 | def get_parser(self, required=None):
|
---|
2545 | parser = ErrorRaisingArgumentParser(prog='PROG')
|
---|
2546 | titled_group = parser.add_argument_group(
|
---|
2547 | title='Titled group', description='Group description')
|
---|
2548 | mutex_group = \
|
---|
2549 | titled_group.add_mutually_exclusive_group(required=required)
|
---|
2550 | mutex_group.add_argument('--bar', help='bar help')
|
---|
2551 | mutex_group.add_argument('--baz', help='baz help')
|
---|
2552 | return parser
|
---|
2553 |
|
---|
2554 | failures = ['--bar X --baz Y', '--baz X --bar Y']
|
---|
2555 | successes = [
|
---|
2556 | ('--bar X', NS(bar='X', baz=None)),
|
---|
2557 | ('--baz Y', NS(bar=None, baz='Y')),
|
---|
2558 | ]
|
---|
2559 | successes_when_not_required = [
|
---|
2560 | ('', NS(bar=None, baz=None)),
|
---|
2561 | ]
|
---|
2562 |
|
---|
2563 | usage_when_not_required = '''\
|
---|
2564 | usage: PROG [-h] [--bar BAR | --baz BAZ]
|
---|
2565 | '''
|
---|
2566 | usage_when_required = '''\
|
---|
2567 | usage: PROG [-h] (--bar BAR | --baz BAZ)
|
---|
2568 | '''
|
---|
2569 | help = '''\
|
---|
2570 |
|
---|
2571 | optional arguments:
|
---|
2572 | -h, --help show this help message and exit
|
---|
2573 |
|
---|
2574 | Titled group:
|
---|
2575 | Group description
|
---|
2576 |
|
---|
2577 | --bar BAR bar help
|
---|
2578 | --baz BAZ baz help
|
---|
2579 | '''
|
---|
2580 |
|
---|
2581 |
|
---|
2582 | class TestMutuallyExclusiveOptionalsAndPositionalsMixed(MEMixin, TestCase):
|
---|
2583 |
|
---|
2584 | def get_parser(self, required):
|
---|
2585 | parser = ErrorRaisingArgumentParser(prog='PROG')
|
---|
2586 | parser.add_argument('x', help='x help')
|
---|
2587 | parser.add_argument('-y', action='store_true', help='y help')
|
---|
2588 | group = parser.add_mutually_exclusive_group(required=required)
|
---|
2589 | group.add_argument('a', nargs='?', help='a help')
|
---|
2590 | group.add_argument('-b', action='store_true', help='b help')
|
---|
2591 | group.add_argument('-c', action='store_true', help='c help')
|
---|
2592 | return parser
|
---|
2593 |
|
---|
2594 | failures = ['X A -b', '-b -c', '-c X A']
|
---|
2595 | successes = [
|
---|
2596 | ('X A', NS(a='A', b=False, c=False, x='X', y=False)),
|
---|
2597 | ('X -b', NS(a=None, b=True, c=False, x='X', y=False)),
|
---|
2598 | ('X -c', NS(a=None, b=False, c=True, x='X', y=False)),
|
---|
2599 | ('X A -y', NS(a='A', b=False, c=False, x='X', y=True)),
|
---|
2600 | ('X -y -b', NS(a=None, b=True, c=False, x='X', y=True)),
|
---|
2601 | ]
|
---|
2602 | successes_when_not_required = [
|
---|
2603 | ('X', NS(a=None, b=False, c=False, x='X', y=False)),
|
---|
2604 | ('X -y', NS(a=None, b=False, c=False, x='X', y=True)),
|
---|
2605 | ]
|
---|
2606 |
|
---|
2607 | usage_when_required = usage_when_not_required = '''\
|
---|
2608 | usage: PROG [-h] [-y] [-b] [-c] x [a]
|
---|
2609 | '''
|
---|
2610 | help = '''\
|
---|
2611 |
|
---|
2612 | positional arguments:
|
---|
2613 | x x help
|
---|
2614 | a a help
|
---|
2615 |
|
---|
2616 | optional arguments:
|
---|
2617 | -h, --help show this help message and exit
|
---|
2618 | -y y help
|
---|
2619 | -b b help
|
---|
2620 | -c c help
|
---|
2621 | '''
|
---|
2622 |
|
---|
2623 | # =================================================
|
---|
2624 | # Mutually exclusive group in parent parser tests
|
---|
2625 | # =================================================
|
---|
2626 |
|
---|
2627 | class MEPBase(object):
|
---|
2628 |
|
---|
2629 | def get_parser(self, required=None):
|
---|
2630 | parent = super(MEPBase, self).get_parser(required=required)
|
---|
2631 | parser = ErrorRaisingArgumentParser(
|
---|
2632 | prog=parent.prog, add_help=False, parents=[parent])
|
---|
2633 | return parser
|
---|
2634 |
|
---|
2635 |
|
---|
2636 | class TestMutuallyExclusiveGroupErrorsParent(
|
---|
2637 | MEPBase, TestMutuallyExclusiveGroupErrors):
|
---|
2638 | pass
|
---|
2639 |
|
---|
2640 |
|
---|
2641 | class TestMutuallyExclusiveSimpleParent(
|
---|
2642 | MEPBase, TestMutuallyExclusiveSimple):
|
---|
2643 | pass
|
---|
2644 |
|
---|
2645 |
|
---|
2646 | class TestMutuallyExclusiveLongParent(
|
---|
2647 | MEPBase, TestMutuallyExclusiveLong):
|
---|
2648 | pass
|
---|
2649 |
|
---|
2650 |
|
---|
2651 | class TestMutuallyExclusiveFirstSuppressedParent(
|
---|
2652 | MEPBase, TestMutuallyExclusiveFirstSuppressed):
|
---|
2653 | pass
|
---|
2654 |
|
---|
2655 |
|
---|
2656 | class TestMutuallyExclusiveManySuppressedParent(
|
---|
2657 | MEPBase, TestMutuallyExclusiveManySuppressed):
|
---|
2658 | pass
|
---|
2659 |
|
---|
2660 |
|
---|
2661 | class TestMutuallyExclusiveOptionalAndPositionalParent(
|
---|
2662 | MEPBase, TestMutuallyExclusiveOptionalAndPositional):
|
---|
2663 | pass
|
---|
2664 |
|
---|
2665 |
|
---|
2666 | class TestMutuallyExclusiveOptionalsMixedParent(
|
---|
2667 | MEPBase, TestMutuallyExclusiveOptionalsMixed):
|
---|
2668 | pass
|
---|
2669 |
|
---|
2670 |
|
---|
2671 | class TestMutuallyExclusiveOptionalsAndPositionalsMixedParent(
|
---|
2672 | MEPBase, TestMutuallyExclusiveOptionalsAndPositionalsMixed):
|
---|
2673 | pass
|
---|
2674 |
|
---|
2675 | # =================
|
---|
2676 | # Set default tests
|
---|
2677 | # =================
|
---|
2678 |
|
---|
2679 | class TestSetDefaults(TestCase):
|
---|
2680 |
|
---|
2681 | def test_set_defaults_no_args(self):
|
---|
2682 | parser = ErrorRaisingArgumentParser()
|
---|
2683 | parser.set_defaults(x='foo')
|
---|
2684 | parser.set_defaults(y='bar', z=1)
|
---|
2685 | self.assertEqual(NS(x='foo', y='bar', z=1),
|
---|
2686 | parser.parse_args([]))
|
---|
2687 | self.assertEqual(NS(x='foo', y='bar', z=1),
|
---|
2688 | parser.parse_args([], NS()))
|
---|
2689 | self.assertEqual(NS(x='baz', y='bar', z=1),
|
---|
2690 | parser.parse_args([], NS(x='baz')))
|
---|
2691 | self.assertEqual(NS(x='baz', y='bar', z=2),
|
---|
2692 | parser.parse_args([], NS(x='baz', z=2)))
|
---|
2693 |
|
---|
2694 | def test_set_defaults_with_args(self):
|
---|
2695 | parser = ErrorRaisingArgumentParser()
|
---|
2696 | parser.set_defaults(x='foo', y='bar')
|
---|
2697 | parser.add_argument('-x', default='xfoox')
|
---|
2698 | self.assertEqual(NS(x='xfoox', y='bar'),
|
---|
2699 | parser.parse_args([]))
|
---|
2700 | self.assertEqual(NS(x='xfoox', y='bar'),
|
---|
2701 | parser.parse_args([], NS()))
|
---|
2702 | self.assertEqual(NS(x='baz', y='bar'),
|
---|
2703 | parser.parse_args([], NS(x='baz')))
|
---|
2704 | self.assertEqual(NS(x='1', y='bar'),
|
---|
2705 | parser.parse_args('-x 1'.split()))
|
---|
2706 | self.assertEqual(NS(x='1', y='bar'),
|
---|
2707 | parser.parse_args('-x 1'.split(), NS()))
|
---|
2708 | self.assertEqual(NS(x='1', y='bar'),
|
---|
2709 | parser.parse_args('-x 1'.split(), NS(x='baz')))
|
---|
2710 |
|
---|
2711 | def test_set_defaults_subparsers(self):
|
---|
2712 | parser = ErrorRaisingArgumentParser()
|
---|
2713 | parser.set_defaults(x='foo')
|
---|
2714 | subparsers = parser.add_subparsers()
|
---|
2715 | parser_a = subparsers.add_parser('a')
|
---|
2716 | parser_a.set_defaults(y='bar')
|
---|
2717 | self.assertEqual(NS(x='foo', y='bar'),
|
---|
2718 | parser.parse_args('a'.split()))
|
---|
2719 |
|
---|
2720 | def test_set_defaults_parents(self):
|
---|
2721 | parent = ErrorRaisingArgumentParser(add_help=False)
|
---|
2722 | parent.set_defaults(x='foo')
|
---|
2723 | parser = ErrorRaisingArgumentParser(parents=[parent])
|
---|
2724 | self.assertEqual(NS(x='foo'), parser.parse_args([]))
|
---|
2725 |
|
---|
2726 | def test_set_defaults_same_as_add_argument(self):
|
---|
2727 | parser = ErrorRaisingArgumentParser()
|
---|
2728 | parser.set_defaults(w='W', x='X', y='Y', z='Z')
|
---|
2729 | parser.add_argument('-w')
|
---|
2730 | parser.add_argument('-x', default='XX')
|
---|
2731 | parser.add_argument('y', nargs='?')
|
---|
2732 | parser.add_argument('z', nargs='?', default='ZZ')
|
---|
2733 |
|
---|
2734 | # defaults set previously
|
---|
2735 | self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'),
|
---|
2736 | parser.parse_args([]))
|
---|
2737 |
|
---|
2738 | # reset defaults
|
---|
2739 | parser.set_defaults(w='WW', x='X', y='YY', z='Z')
|
---|
2740 | self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'),
|
---|
2741 | parser.parse_args([]))
|
---|
2742 |
|
---|
2743 | def test_set_defaults_same_as_add_argument_group(self):
|
---|
2744 | parser = ErrorRaisingArgumentParser()
|
---|
2745 | parser.set_defaults(w='W', x='X', y='Y', z='Z')
|
---|
2746 | group = parser.add_argument_group('foo')
|
---|
2747 | group.add_argument('-w')
|
---|
2748 | group.add_argument('-x', default='XX')
|
---|
2749 | group.add_argument('y', nargs='?')
|
---|
2750 | group.add_argument('z', nargs='?', default='ZZ')
|
---|
2751 |
|
---|
2752 |
|
---|
2753 | # defaults set previously
|
---|
2754 | self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'),
|
---|
2755 | parser.parse_args([]))
|
---|
2756 |
|
---|
2757 | # reset defaults
|
---|
2758 | parser.set_defaults(w='WW', x='X', y='YY', z='Z')
|
---|
2759 | self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'),
|
---|
2760 | parser.parse_args([]))
|
---|
2761 |
|
---|
2762 | # =================
|
---|
2763 | # Get default tests
|
---|
2764 | # =================
|
---|
2765 |
|
---|
2766 | class TestGetDefault(TestCase):
|
---|
2767 |
|
---|
2768 | def test_get_default(self):
|
---|
2769 | parser = ErrorRaisingArgumentParser()
|
---|
2770 | self.assertEqual(None, parser.get_default("foo"))
|
---|
2771 | self.assertEqual(None, parser.get_default("bar"))
|
---|
2772 |
|
---|
2773 | parser.add_argument("--foo")
|
---|
2774 | self.assertEqual(None, parser.get_default("foo"))
|
---|
2775 | self.assertEqual(None, parser.get_default("bar"))
|
---|
2776 |
|
---|
2777 | parser.add_argument("--bar", type=int, default=42)
|
---|
2778 | self.assertEqual(None, parser.get_default("foo"))
|
---|
2779 | self.assertEqual(42, parser.get_default("bar"))
|
---|
2780 |
|
---|
2781 | parser.set_defaults(foo="badger")
|
---|
2782 | self.assertEqual("badger", parser.get_default("foo"))
|
---|
2783 | self.assertEqual(42, parser.get_default("bar"))
|
---|
2784 |
|
---|
2785 | # ==========================
|
---|
2786 | # Namespace 'contains' tests
|
---|
2787 | # ==========================
|
---|
2788 |
|
---|
2789 | class TestNamespaceContainsSimple(TestCase):
|
---|
2790 |
|
---|
2791 | def test_empty(self):
|
---|
2792 | ns = argparse.Namespace()
|
---|
2793 | self.assertEqual('' in ns, False)
|
---|
2794 | self.assertEqual('' not in ns, True)
|
---|
2795 | self.assertEqual('x' in ns, False)
|
---|
2796 |
|
---|
2797 | def test_non_empty(self):
|
---|
2798 | ns = argparse.Namespace(x=1, y=2)
|
---|
2799 | self.assertEqual('x' in ns, True)
|
---|
2800 | self.assertEqual('x' not in ns, False)
|
---|
2801 | self.assertEqual('y' in ns, True)
|
---|
2802 | self.assertEqual('' in ns, False)
|
---|
2803 | self.assertEqual('xx' in ns, False)
|
---|
2804 | self.assertEqual('z' in ns, False)
|
---|
2805 |
|
---|
2806 | # =====================
|
---|
2807 | # Help formatting tests
|
---|
2808 | # =====================
|
---|
2809 |
|
---|
2810 | class TestHelpFormattingMetaclass(type):
|
---|
2811 |
|
---|
2812 | def __init__(cls, name, bases, bodydict):
|
---|
2813 | if name == 'HelpTestCase':
|
---|
2814 | return
|
---|
2815 |
|
---|
2816 | class AddTests(object):
|
---|
2817 |
|
---|
2818 | def __init__(self, test_class, func_suffix, std_name):
|
---|
2819 | self.func_suffix = func_suffix
|
---|
2820 | self.std_name = std_name
|
---|
2821 |
|
---|
2822 | for test_func in [self.test_format,
|
---|
2823 | self.test_print,
|
---|
2824 | self.test_print_file]:
|
---|
2825 | test_name = '%s_%s' % (test_func.__name__, func_suffix)
|
---|
2826 |
|
---|
2827 | def test_wrapper(self, test_func=test_func):
|
---|
2828 | test_func(self)
|
---|
2829 | try:
|
---|
2830 | test_wrapper.__name__ = test_name
|
---|
2831 | except TypeError:
|
---|
2832 | pass
|
---|
2833 | setattr(test_class, test_name, test_wrapper)
|
---|
2834 |
|
---|
2835 | def _get_parser(self, tester):
|
---|
2836 | parser = argparse.ArgumentParser(
|
---|
2837 | *tester.parser_signature.args,
|
---|
2838 | **tester.parser_signature.kwargs)
|
---|
2839 | for argument_sig in getattr(tester, 'argument_signatures', []):
|
---|
2840 | parser.add_argument(*argument_sig.args,
|
---|
2841 | **argument_sig.kwargs)
|
---|
2842 | group_sigs = getattr(tester, 'argument_group_signatures', [])
|
---|
2843 | for group_sig, argument_sigs in group_sigs:
|
---|
2844 | group = parser.add_argument_group(*group_sig.args,
|
---|
2845 | **group_sig.kwargs)
|
---|
2846 | for argument_sig in argument_sigs:
|
---|
2847 | group.add_argument(*argument_sig.args,
|
---|
2848 | **argument_sig.kwargs)
|
---|
2849 | subparsers_sigs = getattr(tester, 'subparsers_signatures', [])
|
---|
2850 | if subparsers_sigs:
|
---|
2851 | subparsers = parser.add_subparsers()
|
---|
2852 | for subparser_sig in subparsers_sigs:
|
---|
2853 | subparsers.add_parser(*subparser_sig.args,
|
---|
2854 | **subparser_sig.kwargs)
|
---|
2855 | return parser
|
---|
2856 |
|
---|
2857 | def _test(self, tester, parser_text):
|
---|
2858 | expected_text = getattr(tester, self.func_suffix)
|
---|
2859 | expected_text = textwrap.dedent(expected_text)
|
---|
2860 | if expected_text != parser_text:
|
---|
2861 | print(repr(expected_text))
|
---|
2862 | print(repr(parser_text))
|
---|
2863 | for char1, char2 in zip(expected_text, parser_text):
|
---|
2864 | if char1 != char2:
|
---|
2865 | print('first diff: %r %r' % (char1, char2))
|
---|
2866 | break
|
---|
2867 | tester.assertEqual(expected_text, parser_text)
|
---|
2868 |
|
---|
2869 | def test_format(self, tester):
|
---|
2870 | parser = self._get_parser(tester)
|
---|
2871 | format = getattr(parser, 'format_%s' % self.func_suffix)
|
---|
2872 | self._test(tester, format())
|
---|
2873 |
|
---|
2874 | def test_print(self, tester):
|
---|
2875 | parser = self._get_parser(tester)
|
---|
2876 | print_ = getattr(parser, 'print_%s' % self.func_suffix)
|
---|
2877 | old_stream = getattr(sys, self.std_name)
|
---|
2878 | setattr(sys, self.std_name, StdIOBuffer())
|
---|
2879 | try:
|
---|
2880 | print_()
|
---|
2881 | parser_text = getattr(sys, self.std_name).getvalue()
|
---|
2882 | finally:
|
---|
2883 | setattr(sys, self.std_name, old_stream)
|
---|
2884 | self._test(tester, parser_text)
|
---|
2885 |
|
---|
2886 | def test_print_file(self, tester):
|
---|
2887 | parser = self._get_parser(tester)
|
---|
2888 | print_ = getattr(parser, 'print_%s' % self.func_suffix)
|
---|
2889 | sfile = StdIOBuffer()
|
---|
2890 | print_(sfile)
|
---|
2891 | parser_text = sfile.getvalue()
|
---|
2892 | self._test(tester, parser_text)
|
---|
2893 |
|
---|
2894 | # add tests for {format,print}_{usage,help,version}
|
---|
2895 | for func_suffix, std_name in [('usage', 'stdout'),
|
---|
2896 | ('help', 'stdout'),
|
---|
2897 | ('version', 'stderr')]:
|
---|
2898 | AddTests(cls, func_suffix, std_name)
|
---|
2899 |
|
---|
2900 | bases = TestCase,
|
---|
2901 | HelpTestCase = TestHelpFormattingMetaclass('HelpTestCase', bases, {})
|
---|
2902 |
|
---|
2903 |
|
---|
2904 | class TestHelpBiggerOptionals(HelpTestCase):
|
---|
2905 | """Make sure that argument help aligns when options are longer"""
|
---|
2906 |
|
---|
2907 | parser_signature = Sig(prog='PROG', description='DESCRIPTION',
|
---|
2908 | epilog='EPILOG', version='0.1')
|
---|
2909 | argument_signatures = [
|
---|
2910 | Sig('-x', action='store_true', help='X HELP'),
|
---|
2911 | Sig('--y', help='Y HELP'),
|
---|
2912 | Sig('foo', help='FOO HELP'),
|
---|
2913 | Sig('bar', help='BAR HELP'),
|
---|
2914 | ]
|
---|
2915 | argument_group_signatures = []
|
---|
2916 | usage = '''\
|
---|
2917 | usage: PROG [-h] [-v] [-x] [--y Y] foo bar
|
---|
2918 | '''
|
---|
2919 | help = usage + '''\
|
---|
2920 |
|
---|
2921 | DESCRIPTION
|
---|
2922 |
|
---|
2923 | positional arguments:
|
---|
2924 | foo FOO HELP
|
---|
2925 | bar BAR HELP
|
---|
2926 |
|
---|
2927 | optional arguments:
|
---|
2928 | -h, --help show this help message and exit
|
---|
2929 | -v, --version show program's version number and exit
|
---|
2930 | -x X HELP
|
---|
2931 | --y Y Y HELP
|
---|
2932 |
|
---|
2933 | EPILOG
|
---|
2934 | '''
|
---|
2935 | version = '''\
|
---|
2936 | 0.1
|
---|
2937 | '''
|
---|
2938 |
|
---|
2939 |
|
---|
2940 | class TestHelpBiggerOptionalGroups(HelpTestCase):
|
---|
2941 | """Make sure that argument help aligns when options are longer"""
|
---|
2942 |
|
---|
2943 | parser_signature = Sig(prog='PROG', description='DESCRIPTION',
|
---|
2944 | epilog='EPILOG', version='0.1')
|
---|
2945 | argument_signatures = [
|
---|
2946 | Sig('-x', action='store_true', help='X HELP'),
|
---|
2947 | Sig('--y', help='Y HELP'),
|
---|
2948 | Sig('foo', help='FOO HELP'),
|
---|
2949 | Sig('bar', help='BAR HELP'),
|
---|
2950 | ]
|
---|
2951 | argument_group_signatures = [
|
---|
2952 | (Sig('GROUP TITLE', description='GROUP DESCRIPTION'), [
|
---|
2953 | Sig('baz', help='BAZ HELP'),
|
---|
2954 | Sig('-z', nargs='+', help='Z HELP')]),
|
---|
2955 | ]
|
---|
2956 | usage = '''\
|
---|
2957 | usage: PROG [-h] [-v] [-x] [--y Y] [-z Z [Z ...]] foo bar baz
|
---|
2958 | '''
|
---|
2959 | help = usage + '''\
|
---|
2960 |
|
---|
2961 | DESCRIPTION
|
---|
2962 |
|
---|
2963 | positional arguments:
|
---|
2964 | foo FOO HELP
|
---|
2965 | bar BAR HELP
|
---|
2966 |
|
---|
2967 | optional arguments:
|
---|
2968 | -h, --help show this help message and exit
|
---|
2969 | -v, --version show program's version number and exit
|
---|
2970 | -x X HELP
|
---|
2971 | --y Y Y HELP
|
---|
2972 |
|
---|
2973 | GROUP TITLE:
|
---|
2974 | GROUP DESCRIPTION
|
---|
2975 |
|
---|
2976 | baz BAZ HELP
|
---|
2977 | -z Z [Z ...] Z HELP
|
---|
2978 |
|
---|
2979 | EPILOG
|
---|
2980 | '''
|
---|
2981 | version = '''\
|
---|
2982 | 0.1
|
---|
2983 | '''
|
---|
2984 |
|
---|
2985 |
|
---|
2986 | class TestHelpBiggerPositionals(HelpTestCase):
|
---|
2987 | """Make sure that help aligns when arguments are longer"""
|
---|
2988 |
|
---|
2989 | parser_signature = Sig(usage='USAGE', description='DESCRIPTION')
|
---|
2990 | argument_signatures = [
|
---|
2991 | Sig('-x', action='store_true', help='X HELP'),
|
---|
2992 | Sig('--y', help='Y HELP'),
|
---|
2993 | Sig('ekiekiekifekang', help='EKI HELP'),
|
---|
2994 | Sig('bar', help='BAR HELP'),
|
---|
2995 | ]
|
---|
2996 | argument_group_signatures = []
|
---|
2997 | usage = '''\
|
---|
2998 | usage: USAGE
|
---|
2999 | '''
|
---|
3000 | help = usage + '''\
|
---|
3001 |
|
---|
3002 | DESCRIPTION
|
---|
3003 |
|
---|
3004 | positional arguments:
|
---|
3005 | ekiekiekifekang EKI HELP
|
---|
3006 | bar BAR HELP
|
---|
3007 |
|
---|
3008 | optional arguments:
|
---|
3009 | -h, --help show this help message and exit
|
---|
3010 | -x X HELP
|
---|
3011 | --y Y Y HELP
|
---|
3012 | '''
|
---|
3013 |
|
---|
3014 | version = ''
|
---|
3015 |
|
---|
3016 |
|
---|
3017 | class TestHelpReformatting(HelpTestCase):
|
---|
3018 | """Make sure that text after short names starts on the first line"""
|
---|
3019 |
|
---|
3020 | parser_signature = Sig(
|
---|
3021 | prog='PROG',
|
---|
3022 | description=' oddly formatted\n'
|
---|
3023 | 'description\n'
|
---|
3024 | '\n'
|
---|
3025 | 'that is so long that it should go onto multiple '
|
---|
3026 | 'lines when wrapped')
|
---|
3027 | argument_signatures = [
|
---|
3028 | Sig('-x', metavar='XX', help='oddly\n'
|
---|
3029 | ' formatted -x help'),
|
---|
3030 | Sig('y', metavar='yyy', help='normal y help'),
|
---|
3031 | ]
|
---|
3032 | argument_group_signatures = [
|
---|
3033 | (Sig('title', description='\n'
|
---|
3034 | ' oddly formatted group\n'
|
---|
3035 | '\n'
|
---|
3036 | 'description'),
|
---|
3037 | [Sig('-a', action='store_true',
|
---|
3038 | help=' oddly \n'
|
---|
3039 | 'formatted -a help \n'
|
---|
3040 | ' again, so long that it should be wrapped over '
|
---|
3041 | 'multiple lines')]),
|
---|
3042 | ]
|
---|
3043 | usage = '''\
|
---|
3044 | usage: PROG [-h] [-x XX] [-a] yyy
|
---|
3045 | '''
|
---|
3046 | help = usage + '''\
|
---|
3047 |
|
---|
3048 | oddly formatted description that is so long that it should go onto \
|
---|
3049 | multiple
|
---|
3050 | lines when wrapped
|
---|
3051 |
|
---|
3052 | positional arguments:
|
---|
3053 | yyy normal y help
|
---|
3054 |
|
---|
3055 | optional arguments:
|
---|
3056 | -h, --help show this help message and exit
|
---|
3057 | -x XX oddly formatted -x help
|
---|
3058 |
|
---|
3059 | title:
|
---|
3060 | oddly formatted group description
|
---|
3061 |
|
---|
3062 | -a oddly formatted -a help again, so long that it should \
|
---|
3063 | be wrapped
|
---|
3064 | over multiple lines
|
---|
3065 | '''
|
---|
3066 | version = ''
|
---|
3067 |
|
---|
3068 |
|
---|
3069 | class TestHelpWrappingShortNames(HelpTestCase):
|
---|
3070 | """Make sure that text after short names starts on the first line"""
|
---|
3071 |
|
---|
3072 | parser_signature = Sig(prog='PROG', description= 'D\nD' * 30)
|
---|
3073 | argument_signatures = [
|
---|
3074 | Sig('-x', metavar='XX', help='XHH HX' * 20),
|
---|
3075 | Sig('y', metavar='yyy', help='YH YH' * 20),
|
---|
3076 | ]
|
---|
3077 | argument_group_signatures = [
|
---|
3078 | (Sig('ALPHAS'), [
|
---|
3079 | Sig('-a', action='store_true', help='AHHH HHA' * 10)]),
|
---|
3080 | ]
|
---|
3081 | usage = '''\
|
---|
3082 | usage: PROG [-h] [-x XX] [-a] yyy
|
---|
3083 | '''
|
---|
3084 | help = usage + '''\
|
---|
3085 |
|
---|
3086 | D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
|
---|
3087 | DD DD DD
|
---|
3088 | DD DD DD DD D
|
---|
3089 |
|
---|
3090 | positional arguments:
|
---|
3091 | yyy YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
|
---|
3092 | YHYH YHYH
|
---|
3093 | YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
|
---|
3094 |
|
---|
3095 | optional arguments:
|
---|
3096 | -h, --help show this help message and exit
|
---|
3097 | -x XX XHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH \
|
---|
3098 | HXXHH HXXHH
|
---|
3099 | HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HX
|
---|
3100 |
|
---|
3101 | ALPHAS:
|
---|
3102 | -a AHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH \
|
---|
3103 | HHAAHHH
|
---|
3104 | HHAAHHH HHAAHHH HHA
|
---|
3105 | '''
|
---|
3106 | version = ''
|
---|
3107 |
|
---|
3108 |
|
---|
3109 | class TestHelpWrappingLongNames(HelpTestCase):
|
---|
3110 | """Make sure that text after long names starts on the next line"""
|
---|
3111 |
|
---|
3112 | parser_signature = Sig(usage='USAGE', description= 'D D' * 30,
|
---|
3113 | version='V V'*30)
|
---|
3114 | argument_signatures = [
|
---|
3115 | Sig('-x', metavar='X' * 25, help='XH XH' * 20),
|
---|
3116 | Sig('y', metavar='y' * 25, help='YH YH' * 20),
|
---|
3117 | ]
|
---|
3118 | argument_group_signatures = [
|
---|
3119 | (Sig('ALPHAS'), [
|
---|
3120 | Sig('-a', metavar='A' * 25, help='AH AH' * 20),
|
---|
3121 | Sig('z', metavar='z' * 25, help='ZH ZH' * 20)]),
|
---|
3122 | ]
|
---|
3123 | usage = '''\
|
---|
3124 | usage: USAGE
|
---|
3125 | '''
|
---|
3126 | help = usage + '''\
|
---|
3127 |
|
---|
3128 | D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
|
---|
3129 | DD DD DD
|
---|
3130 | DD DD DD DD D
|
---|
3131 |
|
---|
3132 | positional arguments:
|
---|
3133 | yyyyyyyyyyyyyyyyyyyyyyyyy
|
---|
3134 | YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
|
---|
3135 | YHYH YHYH
|
---|
3136 | YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
|
---|
3137 |
|
---|
3138 | optional arguments:
|
---|
3139 | -h, --help show this help message and exit
|
---|
3140 | -v, --version show program's version number and exit
|
---|
3141 | -x XXXXXXXXXXXXXXXXXXXXXXXXX
|
---|
3142 | XH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH \
|
---|
3143 | XHXH XHXH
|
---|
3144 | XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XH
|
---|
3145 |
|
---|
3146 | ALPHAS:
|
---|
3147 | -a AAAAAAAAAAAAAAAAAAAAAAAAA
|
---|
3148 | AH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH \
|
---|
3149 | AHAH AHAH
|
---|
3150 | AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AH
|
---|
3151 | zzzzzzzzzzzzzzzzzzzzzzzzz
|
---|
3152 | ZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH \
|
---|
3153 | ZHZH ZHZH
|
---|
3154 | ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZH
|
---|
3155 | '''
|
---|
3156 | version = '''\
|
---|
3157 | V VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV \
|
---|
3158 | VV VV VV
|
---|
3159 | VV VV VV VV V
|
---|
3160 | '''
|
---|
3161 |
|
---|
3162 |
|
---|
3163 | class TestHelpUsage(HelpTestCase):
|
---|
3164 | """Test basic usage messages"""
|
---|
3165 |
|
---|
3166 | parser_signature = Sig(prog='PROG')
|
---|
3167 | argument_signatures = [
|
---|
3168 | Sig('-w', nargs='+', help='w'),
|
---|
3169 | Sig('-x', nargs='*', help='x'),
|
---|
3170 | Sig('a', help='a'),
|
---|
3171 | Sig('b', help='b', nargs=2),
|
---|
3172 | Sig('c', help='c', nargs='?'),
|
---|
3173 | ]
|
---|
3174 | argument_group_signatures = [
|
---|
3175 | (Sig('group'), [
|
---|
3176 | Sig('-y', nargs='?', help='y'),
|
---|
3177 | Sig('-z', nargs=3, help='z'),
|
---|
3178 | Sig('d', help='d', nargs='*'),
|
---|
3179 | Sig('e', help='e', nargs='+'),
|
---|
3180 | ])
|
---|
3181 | ]
|
---|
3182 | usage = '''\
|
---|
3183 | usage: PROG [-h] [-w W [W ...]] [-x [X [X ...]]] [-y [Y]] [-z Z Z Z]
|
---|
3184 | a b b [c] [d [d ...]] e [e ...]
|
---|
3185 | '''
|
---|
3186 | help = usage + '''\
|
---|
3187 |
|
---|
3188 | positional arguments:
|
---|
3189 | a a
|
---|
3190 | b b
|
---|
3191 | c c
|
---|
3192 |
|
---|
3193 | optional arguments:
|
---|
3194 | -h, --help show this help message and exit
|
---|
3195 | -w W [W ...] w
|
---|
3196 | -x [X [X ...]] x
|
---|
3197 |
|
---|
3198 | group:
|
---|
3199 | -y [Y] y
|
---|
3200 | -z Z Z Z z
|
---|
3201 | d d
|
---|
3202 | e e
|
---|
3203 | '''
|
---|
3204 | version = ''
|
---|
3205 |
|
---|
3206 |
|
---|
3207 | class TestHelpOnlyUserGroups(HelpTestCase):
|
---|
3208 | """Test basic usage messages"""
|
---|
3209 |
|
---|
3210 | parser_signature = Sig(prog='PROG', add_help=False)
|
---|
3211 | argument_signatures = []
|
---|
3212 | argument_group_signatures = [
|
---|
3213 | (Sig('xxxx'), [
|
---|
3214 | Sig('-x', help='x'),
|
---|
3215 | Sig('a', help='a'),
|
---|
3216 | ]),
|
---|
3217 | (Sig('yyyy'), [
|
---|
3218 | Sig('b', help='b'),
|
---|
3219 | Sig('-y', help='y'),
|
---|
3220 | ]),
|
---|
3221 | ]
|
---|
3222 | usage = '''\
|
---|
3223 | usage: PROG [-x X] [-y Y] a b
|
---|
3224 | '''
|
---|
3225 | help = usage + '''\
|
---|
3226 |
|
---|
3227 | xxxx:
|
---|
3228 | -x X x
|
---|
3229 | a a
|
---|
3230 |
|
---|
3231 | yyyy:
|
---|
3232 | b b
|
---|
3233 | -y Y y
|
---|
3234 | '''
|
---|
3235 | version = ''
|
---|
3236 |
|
---|
3237 |
|
---|
3238 | class TestHelpUsageLongProg(HelpTestCase):
|
---|
3239 | """Test usage messages where the prog is long"""
|
---|
3240 |
|
---|
3241 | parser_signature = Sig(prog='P' * 60)
|
---|
3242 | argument_signatures = [
|
---|
3243 | Sig('-w', metavar='W'),
|
---|
3244 | Sig('-x', metavar='X'),
|
---|
3245 | Sig('a'),
|
---|
3246 | Sig('b'),
|
---|
3247 | ]
|
---|
3248 | argument_group_signatures = []
|
---|
3249 | usage = '''\
|
---|
3250 | usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
|
---|
3251 | [-h] [-w W] [-x X] a b
|
---|
3252 | '''
|
---|
3253 | help = usage + '''\
|
---|
3254 |
|
---|
3255 | positional arguments:
|
---|
3256 | a
|
---|
3257 | b
|
---|
3258 |
|
---|
3259 | optional arguments:
|
---|
3260 | -h, --help show this help message and exit
|
---|
3261 | -w W
|
---|
3262 | -x X
|
---|
3263 | '''
|
---|
3264 | version = ''
|
---|
3265 |
|
---|
3266 |
|
---|
3267 | class TestHelpUsageLongProgOptionsWrap(HelpTestCase):
|
---|
3268 | """Test usage messages where the prog is long and the optionals wrap"""
|
---|
3269 |
|
---|
3270 | parser_signature = Sig(prog='P' * 60)
|
---|
3271 | argument_signatures = [
|
---|
3272 | Sig('-w', metavar='W' * 25),
|
---|
3273 | Sig('-x', metavar='X' * 25),
|
---|
3274 | Sig('-y', metavar='Y' * 25),
|
---|
3275 | Sig('-z', metavar='Z' * 25),
|
---|
3276 | Sig('a'),
|
---|
3277 | Sig('b'),
|
---|
3278 | ]
|
---|
3279 | argument_group_signatures = []
|
---|
3280 | usage = '''\
|
---|
3281 | usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
|
---|
3282 | [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
|
---|
3283 | [-x XXXXXXXXXXXXXXXXXXXXXXXXX]
|
---|
3284 | [-y YYYYYYYYYYYYYYYYYYYYYYYYY] [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
|
---|
3285 | a b
|
---|
3286 | '''
|
---|
3287 | help = usage + '''\
|
---|
3288 |
|
---|
3289 | positional arguments:
|
---|
3290 | a
|
---|
3291 | b
|
---|
3292 |
|
---|
3293 | optional arguments:
|
---|
3294 | -h, --help show this help message and exit
|
---|
3295 | -w WWWWWWWWWWWWWWWWWWWWWWWWW
|
---|
3296 | -x XXXXXXXXXXXXXXXXXXXXXXXXX
|
---|
3297 | -y YYYYYYYYYYYYYYYYYYYYYYYYY
|
---|
3298 | -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
|
---|
3299 | '''
|
---|
3300 | version = ''
|
---|
3301 |
|
---|
3302 |
|
---|
3303 | class TestHelpUsageLongProgPositionalsWrap(HelpTestCase):
|
---|
3304 | """Test usage messages where the prog is long and the positionals wrap"""
|
---|
3305 |
|
---|
3306 | parser_signature = Sig(prog='P' * 60, add_help=False)
|
---|
3307 | argument_signatures = [
|
---|
3308 | Sig('a' * 25),
|
---|
3309 | Sig('b' * 25),
|
---|
3310 | Sig('c' * 25),
|
---|
3311 | ]
|
---|
3312 | argument_group_signatures = []
|
---|
3313 | usage = '''\
|
---|
3314 | usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
|
---|
3315 | aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
|
---|
3316 | ccccccccccccccccccccccccc
|
---|
3317 | '''
|
---|
3318 | help = usage + '''\
|
---|
3319 |
|
---|
3320 | positional arguments:
|
---|
3321 | aaaaaaaaaaaaaaaaaaaaaaaaa
|
---|
3322 | bbbbbbbbbbbbbbbbbbbbbbbbb
|
---|
3323 | ccccccccccccccccccccccccc
|
---|
3324 | '''
|
---|
3325 | version = ''
|
---|
3326 |
|
---|
3327 |
|
---|
3328 | class TestHelpUsageOptionalsWrap(HelpTestCase):
|
---|
3329 | """Test usage messages where the optionals wrap"""
|
---|
3330 |
|
---|
3331 | parser_signature = Sig(prog='PROG')
|
---|
3332 | argument_signatures = [
|
---|
3333 | Sig('-w', metavar='W' * 25),
|
---|
3334 | Sig('-x', metavar='X' * 25),
|
---|
3335 | Sig('-y', metavar='Y' * 25),
|
---|
3336 | Sig('-z', metavar='Z' * 25),
|
---|
3337 | Sig('a'),
|
---|
3338 | Sig('b'),
|
---|
3339 | Sig('c'),
|
---|
3340 | ]
|
---|
3341 | argument_group_signatures = []
|
---|
3342 | usage = '''\
|
---|
3343 | usage: PROG [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
|
---|
3344 | [-x XXXXXXXXXXXXXXXXXXXXXXXXX]
|
---|
3345 | [-y YYYYYYYYYYYYYYYYYYYYYYYYY] \
|
---|
3346 | [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
|
---|
3347 | a b c
|
---|
3348 | '''
|
---|
3349 | help = usage + '''\
|
---|
3350 |
|
---|
3351 | positional arguments:
|
---|
3352 | a
|
---|
3353 | b
|
---|
3354 | c
|
---|
3355 |
|
---|
3356 | optional arguments:
|
---|
3357 | -h, --help show this help message and exit
|
---|
3358 | -w WWWWWWWWWWWWWWWWWWWWWWWWW
|
---|
3359 | -x XXXXXXXXXXXXXXXXXXXXXXXXX
|
---|
3360 | -y YYYYYYYYYYYYYYYYYYYYYYYYY
|
---|
3361 | -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
|
---|
3362 | '''
|
---|
3363 | version = ''
|
---|
3364 |
|
---|
3365 |
|
---|
3366 | class TestHelpUsagePositionalsWrap(HelpTestCase):
|
---|
3367 | """Test usage messages where the positionals wrap"""
|
---|
3368 |
|
---|
3369 | parser_signature = Sig(prog='PROG')
|
---|
3370 | argument_signatures = [
|
---|
3371 | Sig('-x'),
|
---|
3372 | Sig('-y'),
|
---|
3373 | Sig('-z'),
|
---|
3374 | Sig('a' * 25),
|
---|
3375 | Sig('b' * 25),
|
---|
3376 | Sig('c' * 25),
|
---|
3377 | ]
|
---|
3378 | argument_group_signatures = []
|
---|
3379 | usage = '''\
|
---|
3380 | usage: PROG [-h] [-x X] [-y Y] [-z Z]
|
---|
3381 | aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
|
---|
3382 | ccccccccccccccccccccccccc
|
---|
3383 | '''
|
---|
3384 | help = usage + '''\
|
---|
3385 |
|
---|
3386 | positional arguments:
|
---|
3387 | aaaaaaaaaaaaaaaaaaaaaaaaa
|
---|
3388 | bbbbbbbbbbbbbbbbbbbbbbbbb
|
---|
3389 | ccccccccccccccccccccccccc
|
---|
3390 |
|
---|
3391 | optional arguments:
|
---|
3392 | -h, --help show this help message and exit
|
---|
3393 | -x X
|
---|
3394 | -y Y
|
---|
3395 | -z Z
|
---|
3396 | '''
|
---|
3397 | version = ''
|
---|
3398 |
|
---|
3399 |
|
---|
3400 | class TestHelpUsageOptionalsPositionalsWrap(HelpTestCase):
|
---|
3401 | """Test usage messages where the optionals and positionals wrap"""
|
---|
3402 |
|
---|
3403 | parser_signature = Sig(prog='PROG')
|
---|
3404 | argument_signatures = [
|
---|
3405 | Sig('-x', metavar='X' * 25),
|
---|
3406 | Sig('-y', metavar='Y' * 25),
|
---|
3407 | Sig('-z', metavar='Z' * 25),
|
---|
3408 | Sig('a' * 25),
|
---|
3409 | Sig('b' * 25),
|
---|
3410 | Sig('c' * 25),
|
---|
3411 | ]
|
---|
3412 | argument_group_signatures = []
|
---|
3413 | usage = '''\
|
---|
3414 | usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
|
---|
3415 | [-y YYYYYYYYYYYYYYYYYYYYYYYYY]
|
---|
3416 | [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
|
---|
3417 | aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
|
---|
3418 | ccccccccccccccccccccccccc
|
---|
3419 | '''
|
---|
3420 | help = usage + '''\
|
---|
3421 |
|
---|
3422 | positional arguments:
|
---|
3423 | aaaaaaaaaaaaaaaaaaaaaaaaa
|
---|
3424 | bbbbbbbbbbbbbbbbbbbbbbbbb
|
---|
3425 | ccccccccccccccccccccccccc
|
---|
3426 |
|
---|
3427 | optional arguments:
|
---|
3428 | -h, --help show this help message and exit
|
---|
3429 | -x XXXXXXXXXXXXXXXXXXXXXXXXX
|
---|
3430 | -y YYYYYYYYYYYYYYYYYYYYYYYYY
|
---|
3431 | -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
|
---|
3432 | '''
|
---|
3433 | version = ''
|
---|
3434 |
|
---|
3435 |
|
---|
3436 | class TestHelpUsageOptionalsOnlyWrap(HelpTestCase):
|
---|
3437 | """Test usage messages where there are only optionals and they wrap"""
|
---|
3438 |
|
---|
3439 | parser_signature = Sig(prog='PROG')
|
---|
3440 | argument_signatures = [
|
---|
3441 | Sig('-x', metavar='X' * 25),
|
---|
3442 | Sig('-y', metavar='Y' * 25),
|
---|
3443 | Sig('-z', metavar='Z' * 25),
|
---|
3444 | ]
|
---|
3445 | argument_group_signatures = []
|
---|
3446 | usage = '''\
|
---|
3447 | usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
|
---|
3448 | [-y YYYYYYYYYYYYYYYYYYYYYYYYY]
|
---|
3449 | [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
|
---|
3450 | '''
|
---|
3451 | help = usage + '''\
|
---|
3452 |
|
---|
3453 | optional arguments:
|
---|
3454 | -h, --help show this help message and exit
|
---|
3455 | -x XXXXXXXXXXXXXXXXXXXXXXXXX
|
---|
3456 | -y YYYYYYYYYYYYYYYYYYYYYYYYY
|
---|
3457 | -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
|
---|
3458 | '''
|
---|
3459 | version = ''
|
---|
3460 |
|
---|
3461 |
|
---|
3462 | class TestHelpUsagePositionalsOnlyWrap(HelpTestCase):
|
---|
3463 | """Test usage messages where there are only positionals and they wrap"""
|
---|
3464 |
|
---|
3465 | parser_signature = Sig(prog='PROG', add_help=False)
|
---|
3466 | argument_signatures = [
|
---|
3467 | Sig('a' * 25),
|
---|
3468 | Sig('b' * 25),
|
---|
3469 | Sig('c' * 25),
|
---|
3470 | ]
|
---|
3471 | argument_group_signatures = []
|
---|
3472 | usage = '''\
|
---|
3473 | usage: PROG aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
|
---|
3474 | ccccccccccccccccccccccccc
|
---|
3475 | '''
|
---|
3476 | help = usage + '''\
|
---|
3477 |
|
---|
3478 | positional arguments:
|
---|
3479 | aaaaaaaaaaaaaaaaaaaaaaaaa
|
---|
3480 | bbbbbbbbbbbbbbbbbbbbbbbbb
|
---|
3481 | ccccccccccccccccccccccccc
|
---|
3482 | '''
|
---|
3483 | version = ''
|
---|
3484 |
|
---|
3485 |
|
---|
3486 | class TestHelpVariableExpansion(HelpTestCase):
|
---|
3487 | """Test that variables are expanded properly in help messages"""
|
---|
3488 |
|
---|
3489 | parser_signature = Sig(prog='PROG')
|
---|
3490 | argument_signatures = [
|
---|
3491 | Sig('-x', type=int,
|
---|
3492 | help='x %(prog)s %(default)s %(type)s %%'),
|
---|
3493 | Sig('-y', action='store_const', default=42, const='XXX',
|
---|
3494 | help='y %(prog)s %(default)s %(const)s'),
|
---|
3495 | Sig('--foo', choices='abc',
|
---|
3496 | help='foo %(prog)s %(default)s %(choices)s'),
|
---|
3497 | Sig('--bar', default='baz', choices=[1, 2], metavar='BBB',
|
---|
3498 | help='bar %(prog)s %(default)s %(dest)s'),
|
---|
3499 | Sig('spam', help='spam %(prog)s %(default)s'),
|
---|
3500 | Sig('badger', default=0.5, help='badger %(prog)s %(default)s'),
|
---|
3501 | ]
|
---|
3502 | argument_group_signatures = [
|
---|
3503 | (Sig('group'), [
|
---|
3504 | Sig('-a', help='a %(prog)s %(default)s'),
|
---|
3505 | Sig('-b', default=-1, help='b %(prog)s %(default)s'),
|
---|
3506 | ])
|
---|
3507 | ]
|
---|
3508 | usage = ('''\
|
---|
3509 | usage: PROG [-h] [-x X] [-y] [--foo {a,b,c}] [--bar BBB] [-a A] [-b B]
|
---|
3510 | spam badger
|
---|
3511 | ''')
|
---|
3512 | help = usage + '''\
|
---|
3513 |
|
---|
3514 | positional arguments:
|
---|
3515 | spam spam PROG None
|
---|
3516 | badger badger PROG 0.5
|
---|
3517 |
|
---|
3518 | optional arguments:
|
---|
3519 | -h, --help show this help message and exit
|
---|
3520 | -x X x PROG None int %
|
---|
3521 | -y y PROG 42 XXX
|
---|
3522 | --foo {a,b,c} foo PROG None a, b, c
|
---|
3523 | --bar BBB bar PROG baz bar
|
---|
3524 |
|
---|
3525 | group:
|
---|
3526 | -a A a PROG None
|
---|
3527 | -b B b PROG -1
|
---|
3528 | '''
|
---|
3529 | version = ''
|
---|
3530 |
|
---|
3531 |
|
---|
3532 | class TestHelpVariableExpansionUsageSupplied(HelpTestCase):
|
---|
3533 | """Test that variables are expanded properly when usage= is present"""
|
---|
3534 |
|
---|
3535 | parser_signature = Sig(prog='PROG', usage='%(prog)s FOO')
|
---|
3536 | argument_signatures = []
|
---|
3537 | argument_group_signatures = []
|
---|
3538 | usage = ('''\
|
---|
3539 | usage: PROG FOO
|
---|
3540 | ''')
|
---|
3541 | help = usage + '''\
|
---|
3542 |
|
---|
3543 | optional arguments:
|
---|
3544 | -h, --help show this help message and exit
|
---|
3545 | '''
|
---|
3546 | version = ''
|
---|
3547 |
|
---|
3548 |
|
---|
3549 | class TestHelpVariableExpansionNoArguments(HelpTestCase):
|
---|
3550 | """Test that variables are expanded properly with no arguments"""
|
---|
3551 |
|
---|
3552 | parser_signature = Sig(prog='PROG', add_help=False)
|
---|
3553 | argument_signatures = []
|
---|
3554 | argument_group_signatures = []
|
---|
3555 | usage = ('''\
|
---|
3556 | usage: PROG
|
---|
3557 | ''')
|
---|
3558 | help = usage
|
---|
3559 | version = ''
|
---|
3560 |
|
---|
3561 |
|
---|
3562 | class TestHelpSuppressUsage(HelpTestCase):
|
---|
3563 | """Test that items can be suppressed in usage messages"""
|
---|
3564 |
|
---|
3565 | parser_signature = Sig(prog='PROG', usage=argparse.SUPPRESS)
|
---|
3566 | argument_signatures = [
|
---|
3567 | Sig('--foo', help='foo help'),
|
---|
3568 | Sig('spam', help='spam help'),
|
---|
3569 | ]
|
---|
3570 | argument_group_signatures = []
|
---|
3571 | help = '''\
|
---|
3572 | positional arguments:
|
---|
3573 | spam spam help
|
---|
3574 |
|
---|
3575 | optional arguments:
|
---|
3576 | -h, --help show this help message and exit
|
---|
3577 | --foo FOO foo help
|
---|
3578 | '''
|
---|
3579 | usage = ''
|
---|
3580 | version = ''
|
---|
3581 |
|
---|
3582 |
|
---|
3583 | class TestHelpSuppressOptional(HelpTestCase):
|
---|
3584 | """Test that optional arguments can be suppressed in help messages"""
|
---|
3585 |
|
---|
3586 | parser_signature = Sig(prog='PROG', add_help=False)
|
---|
3587 | argument_signatures = [
|
---|
3588 | Sig('--foo', help=argparse.SUPPRESS),
|
---|
3589 | Sig('spam', help='spam help'),
|
---|
3590 | ]
|
---|
3591 | argument_group_signatures = []
|
---|
3592 | usage = '''\
|
---|
3593 | usage: PROG spam
|
---|
3594 | '''
|
---|
3595 | help = usage + '''\
|
---|
3596 |
|
---|
3597 | positional arguments:
|
---|
3598 | spam spam help
|
---|
3599 | '''
|
---|
3600 | version = ''
|
---|
3601 |
|
---|
3602 |
|
---|
3603 | class TestHelpSuppressOptionalGroup(HelpTestCase):
|
---|
3604 | """Test that optional groups can be suppressed in help messages"""
|
---|
3605 |
|
---|
3606 | parser_signature = Sig(prog='PROG')
|
---|
3607 | argument_signatures = [
|
---|
3608 | Sig('--foo', help='foo help'),
|
---|
3609 | Sig('spam', help='spam help'),
|
---|
3610 | ]
|
---|
3611 | argument_group_signatures = [
|
---|
3612 | (Sig('group'), [Sig('--bar', help=argparse.SUPPRESS)]),
|
---|
3613 | ]
|
---|
3614 | usage = '''\
|
---|
3615 | usage: PROG [-h] [--foo FOO] spam
|
---|
3616 | '''
|
---|
3617 | help = usage + '''\
|
---|
3618 |
|
---|
3619 | positional arguments:
|
---|
3620 | spam spam help
|
---|
3621 |
|
---|
3622 | optional arguments:
|
---|
3623 | -h, --help show this help message and exit
|
---|
3624 | --foo FOO foo help
|
---|
3625 | '''
|
---|
3626 | version = ''
|
---|
3627 |
|
---|
3628 |
|
---|
3629 | class TestHelpSuppressPositional(HelpTestCase):
|
---|
3630 | """Test that positional arguments can be suppressed in help messages"""
|
---|
3631 |
|
---|
3632 | parser_signature = Sig(prog='PROG')
|
---|
3633 | argument_signatures = [
|
---|
3634 | Sig('--foo', help='foo help'),
|
---|
3635 | Sig('spam', help=argparse.SUPPRESS),
|
---|
3636 | ]
|
---|
3637 | argument_group_signatures = []
|
---|
3638 | usage = '''\
|
---|
3639 | usage: PROG [-h] [--foo FOO]
|
---|
3640 | '''
|
---|
3641 | help = usage + '''\
|
---|
3642 |
|
---|
3643 | optional arguments:
|
---|
3644 | -h, --help show this help message and exit
|
---|
3645 | --foo FOO foo help
|
---|
3646 | '''
|
---|
3647 | version = ''
|
---|
3648 |
|
---|
3649 |
|
---|
3650 | class TestHelpRequiredOptional(HelpTestCase):
|
---|
3651 | """Test that required options don't look optional"""
|
---|
3652 |
|
---|
3653 | parser_signature = Sig(prog='PROG')
|
---|
3654 | argument_signatures = [
|
---|
3655 | Sig('--foo', required=True, help='foo help'),
|
---|
3656 | ]
|
---|
3657 | argument_group_signatures = []
|
---|
3658 | usage = '''\
|
---|
3659 | usage: PROG [-h] --foo FOO
|
---|
3660 | '''
|
---|
3661 | help = usage + '''\
|
---|
3662 |
|
---|
3663 | optional arguments:
|
---|
3664 | -h, --help show this help message and exit
|
---|
3665 | --foo FOO foo help
|
---|
3666 | '''
|
---|
3667 | version = ''
|
---|
3668 |
|
---|
3669 |
|
---|
3670 | class TestHelpAlternatePrefixChars(HelpTestCase):
|
---|
3671 | """Test that options display with different prefix characters"""
|
---|
3672 |
|
---|
3673 | parser_signature = Sig(prog='PROG', prefix_chars='^;', add_help=False)
|
---|
3674 | argument_signatures = [
|
---|
3675 | Sig('^^foo', action='store_true', help='foo help'),
|
---|
3676 | Sig(';b', ';;bar', help='bar help'),
|
---|
3677 | ]
|
---|
3678 | argument_group_signatures = []
|
---|
3679 | usage = '''\
|
---|
3680 | usage: PROG [^^foo] [;b BAR]
|
---|
3681 | '''
|
---|
3682 | help = usage + '''\
|
---|
3683 |
|
---|
3684 | optional arguments:
|
---|
3685 | ^^foo foo help
|
---|
3686 | ;b BAR, ;;bar BAR bar help
|
---|
3687 | '''
|
---|
3688 | version = ''
|
---|
3689 |
|
---|
3690 |
|
---|
3691 | class TestHelpNoHelpOptional(HelpTestCase):
|
---|
3692 | """Test that the --help argument can be suppressed help messages"""
|
---|
3693 |
|
---|
3694 | parser_signature = Sig(prog='PROG', add_help=False)
|
---|
3695 | argument_signatures = [
|
---|
3696 | Sig('--foo', help='foo help'),
|
---|
3697 | Sig('spam', help='spam help'),
|
---|
3698 | ]
|
---|
3699 | argument_group_signatures = []
|
---|
3700 | usage = '''\
|
---|
3701 | usage: PROG [--foo FOO] spam
|
---|
3702 | '''
|
---|
3703 | help = usage + '''\
|
---|
3704 |
|
---|
3705 | positional arguments:
|
---|
3706 | spam spam help
|
---|
3707 |
|
---|
3708 | optional arguments:
|
---|
3709 | --foo FOO foo help
|
---|
3710 | '''
|
---|
3711 | version = ''
|
---|
3712 |
|
---|
3713 |
|
---|
3714 | class TestHelpVersionOptional(HelpTestCase):
|
---|
3715 | """Test that the --version argument can be suppressed help messages"""
|
---|
3716 |
|
---|
3717 | parser_signature = Sig(prog='PROG', version='1.0')
|
---|
3718 | argument_signatures = [
|
---|
3719 | Sig('--foo', help='foo help'),
|
---|
3720 | Sig('spam', help='spam help'),
|
---|
3721 | ]
|
---|
3722 | argument_group_signatures = []
|
---|
3723 | usage = '''\
|
---|
3724 | usage: PROG [-h] [-v] [--foo FOO] spam
|
---|
3725 | '''
|
---|
3726 | help = usage + '''\
|
---|
3727 |
|
---|
3728 | positional arguments:
|
---|
3729 | spam spam help
|
---|
3730 |
|
---|
3731 | optional arguments:
|
---|
3732 | -h, --help show this help message and exit
|
---|
3733 | -v, --version show program's version number and exit
|
---|
3734 | --foo FOO foo help
|
---|
3735 | '''
|
---|
3736 | version = '''\
|
---|
3737 | 1.0
|
---|
3738 | '''
|
---|
3739 |
|
---|
3740 |
|
---|
3741 | class TestHelpNone(HelpTestCase):
|
---|
3742 | """Test that no errors occur if no help is specified"""
|
---|
3743 |
|
---|
3744 | parser_signature = Sig(prog='PROG')
|
---|
3745 | argument_signatures = [
|
---|
3746 | Sig('--foo'),
|
---|
3747 | Sig('spam'),
|
---|
3748 | ]
|
---|
3749 | argument_group_signatures = []
|
---|
3750 | usage = '''\
|
---|
3751 | usage: PROG [-h] [--foo FOO] spam
|
---|
3752 | '''
|
---|
3753 | help = usage + '''\
|
---|
3754 |
|
---|
3755 | positional arguments:
|
---|
3756 | spam
|
---|
3757 |
|
---|
3758 | optional arguments:
|
---|
3759 | -h, --help show this help message and exit
|
---|
3760 | --foo FOO
|
---|
3761 | '''
|
---|
3762 | version = ''
|
---|
3763 |
|
---|
3764 |
|
---|
3765 | class TestHelpTupleMetavar(HelpTestCase):
|
---|
3766 | """Test specifying metavar as a tuple"""
|
---|
3767 |
|
---|
3768 | parser_signature = Sig(prog='PROG')
|
---|
3769 | argument_signatures = [
|
---|
3770 | Sig('-w', help='w', nargs='+', metavar=('W1', 'W2')),
|
---|
3771 | Sig('-x', help='x', nargs='*', metavar=('X1', 'X2')),
|
---|
3772 | Sig('-y', help='y', nargs=3, metavar=('Y1', 'Y2', 'Y3')),
|
---|
3773 | Sig('-z', help='z', nargs='?', metavar=('Z1', )),
|
---|
3774 | ]
|
---|
3775 | argument_group_signatures = []
|
---|
3776 | usage = '''\
|
---|
3777 | usage: PROG [-h] [-w W1 [W2 ...]] [-x [X1 [X2 ...]]] [-y Y1 Y2 Y3] \
|
---|
3778 | [-z [Z1]]
|
---|
3779 | '''
|
---|
3780 | help = usage + '''\
|
---|
3781 |
|
---|
3782 | optional arguments:
|
---|
3783 | -h, --help show this help message and exit
|
---|
3784 | -w W1 [W2 ...] w
|
---|
3785 | -x [X1 [X2 ...]] x
|
---|
3786 | -y Y1 Y2 Y3 y
|
---|
3787 | -z [Z1] z
|
---|
3788 | '''
|
---|
3789 | version = ''
|
---|
3790 |
|
---|
3791 |
|
---|
3792 | class TestHelpRawText(HelpTestCase):
|
---|
3793 | """Test the RawTextHelpFormatter"""
|
---|
3794 |
|
---|
3795 | parser_signature = Sig(
|
---|
3796 | prog='PROG', formatter_class=argparse.RawTextHelpFormatter,
|
---|
3797 | description='Keep the formatting\n'
|
---|
3798 | ' exactly as it is written\n'
|
---|
3799 | '\n'
|
---|
3800 | 'here\n')
|
---|
3801 |
|
---|
3802 | argument_signatures = [
|
---|
3803 | Sig('--foo', help=' foo help should also\n'
|
---|
3804 | 'appear as given here'),
|
---|
3805 | Sig('spam', help='spam help'),
|
---|
3806 | ]
|
---|
3807 | argument_group_signatures = [
|
---|
3808 | (Sig('title', description=' This text\n'
|
---|
3809 | ' should be indented\n'
|
---|
3810 | ' exactly like it is here\n'),
|
---|
3811 | [Sig('--bar', help='bar help')]),
|
---|
3812 | ]
|
---|
3813 | usage = '''\
|
---|
3814 | usage: PROG [-h] [--foo FOO] [--bar BAR] spam
|
---|
3815 | '''
|
---|
3816 | help = usage + '''\
|
---|
3817 |
|
---|
3818 | Keep the formatting
|
---|
3819 | exactly as it is written
|
---|
3820 |
|
---|
3821 | here
|
---|
3822 |
|
---|
3823 | positional arguments:
|
---|
3824 | spam spam help
|
---|
3825 |
|
---|
3826 | optional arguments:
|
---|
3827 | -h, --help show this help message and exit
|
---|
3828 | --foo FOO foo help should also
|
---|
3829 | appear as given here
|
---|
3830 |
|
---|
3831 | title:
|
---|
3832 | This text
|
---|
3833 | should be indented
|
---|
3834 | exactly like it is here
|
---|
3835 |
|
---|
3836 | --bar BAR bar help
|
---|
3837 | '''
|
---|
3838 | version = ''
|
---|
3839 |
|
---|
3840 |
|
---|
3841 | class TestHelpRawDescription(HelpTestCase):
|
---|
3842 | """Test the RawTextHelpFormatter"""
|
---|
3843 |
|
---|
3844 | parser_signature = Sig(
|
---|
3845 | prog='PROG', formatter_class=argparse.RawDescriptionHelpFormatter,
|
---|
3846 | description='Keep the formatting\n'
|
---|
3847 | ' exactly as it is written\n'
|
---|
3848 | '\n'
|
---|
3849 | 'here\n')
|
---|
3850 |
|
---|
3851 | argument_signatures = [
|
---|
3852 | Sig('--foo', help=' foo help should not\n'
|
---|
3853 | ' retain this odd formatting'),
|
---|
3854 | Sig('spam', help='spam help'),
|
---|
3855 | ]
|
---|
3856 | argument_group_signatures = [
|
---|
3857 | (Sig('title', description=' This text\n'
|
---|
3858 | ' should be indented\n'
|
---|
3859 | ' exactly like it is here\n'),
|
---|
3860 | [Sig('--bar', help='bar help')]),
|
---|
3861 | ]
|
---|
3862 | usage = '''\
|
---|
3863 | usage: PROG [-h] [--foo FOO] [--bar BAR] spam
|
---|
3864 | '''
|
---|
3865 | help = usage + '''\
|
---|
3866 |
|
---|
3867 | Keep the formatting
|
---|
3868 | exactly as it is written
|
---|
3869 |
|
---|
3870 | here
|
---|
3871 |
|
---|
3872 | positional arguments:
|
---|
3873 | spam spam help
|
---|
3874 |
|
---|
3875 | optional arguments:
|
---|
3876 | -h, --help show this help message and exit
|
---|
3877 | --foo FOO foo help should not retain this odd formatting
|
---|
3878 |
|
---|
3879 | title:
|
---|
3880 | This text
|
---|
3881 | should be indented
|
---|
3882 | exactly like it is here
|
---|
3883 |
|
---|
3884 | --bar BAR bar help
|
---|
3885 | '''
|
---|
3886 | version = ''
|
---|
3887 |
|
---|
3888 |
|
---|
3889 | class TestHelpArgumentDefaults(HelpTestCase):
|
---|
3890 | """Test the ArgumentDefaultsHelpFormatter"""
|
---|
3891 |
|
---|
3892 | parser_signature = Sig(
|
---|
3893 | prog='PROG', formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
---|
3894 | description='description')
|
---|
3895 |
|
---|
3896 | argument_signatures = [
|
---|
3897 | Sig('--foo', help='foo help - oh and by the way, %(default)s'),
|
---|
3898 | Sig('--bar', action='store_true', help='bar help'),
|
---|
3899 | Sig('spam', help='spam help'),
|
---|
3900 | Sig('badger', nargs='?', default='wooden', help='badger help'),
|
---|
3901 | ]
|
---|
3902 | argument_group_signatures = [
|
---|
3903 | (Sig('title', description='description'),
|
---|
3904 | [Sig('--baz', type=int, default=42, help='baz help')]),
|
---|
3905 | ]
|
---|
3906 | usage = '''\
|
---|
3907 | usage: PROG [-h] [--foo FOO] [--bar] [--baz BAZ] spam [badger]
|
---|
3908 | '''
|
---|
3909 | help = usage + '''\
|
---|
3910 |
|
---|
3911 | description
|
---|
3912 |
|
---|
3913 | positional arguments:
|
---|
3914 | spam spam help
|
---|
3915 | badger badger help (default: wooden)
|
---|
3916 |
|
---|
3917 | optional arguments:
|
---|
3918 | -h, --help show this help message and exit
|
---|
3919 | --foo FOO foo help - oh and by the way, None
|
---|
3920 | --bar bar help (default: False)
|
---|
3921 |
|
---|
3922 | title:
|
---|
3923 | description
|
---|
3924 |
|
---|
3925 | --baz BAZ baz help (default: 42)
|
---|
3926 | '''
|
---|
3927 | version = ''
|
---|
3928 |
|
---|
3929 | class TestHelpVersionAction(HelpTestCase):
|
---|
3930 | """Test the default help for the version action"""
|
---|
3931 |
|
---|
3932 | parser_signature = Sig(prog='PROG', description='description')
|
---|
3933 | argument_signatures = [Sig('-V', '--version', action='version', version='3.6')]
|
---|
3934 | argument_group_signatures = []
|
---|
3935 | usage = '''\
|
---|
3936 | usage: PROG [-h] [-V]
|
---|
3937 | '''
|
---|
3938 | help = usage + '''\
|
---|
3939 |
|
---|
3940 | description
|
---|
3941 |
|
---|
3942 | optional arguments:
|
---|
3943 | -h, --help show this help message and exit
|
---|
3944 | -V, --version show program's version number and exit
|
---|
3945 | '''
|
---|
3946 | version = ''
|
---|
3947 |
|
---|
3948 | class TestHelpSubparsersOrdering(HelpTestCase):
|
---|
3949 | """Test ordering of subcommands in help matches the code"""
|
---|
3950 | parser_signature = Sig(prog='PROG',
|
---|
3951 | description='display some subcommands',
|
---|
3952 | version='0.1')
|
---|
3953 |
|
---|
3954 | subparsers_signatures = [Sig(name=name)
|
---|
3955 | for name in ('a', 'b', 'c', 'd', 'e')]
|
---|
3956 |
|
---|
3957 | usage = '''\
|
---|
3958 | usage: PROG [-h] [-v] {a,b,c,d,e} ...
|
---|
3959 | '''
|
---|
3960 |
|
---|
3961 | help = usage + '''\
|
---|
3962 |
|
---|
3963 | display some subcommands
|
---|
3964 |
|
---|
3965 | positional arguments:
|
---|
3966 | {a,b,c,d,e}
|
---|
3967 |
|
---|
3968 | optional arguments:
|
---|
3969 | -h, --help show this help message and exit
|
---|
3970 | -v, --version show program's version number and exit
|
---|
3971 | '''
|
---|
3972 |
|
---|
3973 | version = '''\
|
---|
3974 | 0.1
|
---|
3975 | '''
|
---|
3976 |
|
---|
3977 | class TestHelpSubparsersWithHelpOrdering(HelpTestCase):
|
---|
3978 | """Test ordering of subcommands in help matches the code"""
|
---|
3979 | parser_signature = Sig(prog='PROG',
|
---|
3980 | description='display some subcommands',
|
---|
3981 | version='0.1')
|
---|
3982 |
|
---|
3983 | subcommand_data = (('a', 'a subcommand help'),
|
---|
3984 | ('b', 'b subcommand help'),
|
---|
3985 | ('c', 'c subcommand help'),
|
---|
3986 | ('d', 'd subcommand help'),
|
---|
3987 | ('e', 'e subcommand help'),
|
---|
3988 | )
|
---|
3989 |
|
---|
3990 | subparsers_signatures = [Sig(name=name, help=help)
|
---|
3991 | for name, help in subcommand_data]
|
---|
3992 |
|
---|
3993 | usage = '''\
|
---|
3994 | usage: PROG [-h] [-v] {a,b,c,d,e} ...
|
---|
3995 | '''
|
---|
3996 |
|
---|
3997 | help = usage + '''\
|
---|
3998 |
|
---|
3999 | display some subcommands
|
---|
4000 |
|
---|
4001 | positional arguments:
|
---|
4002 | {a,b,c,d,e}
|
---|
4003 | a a subcommand help
|
---|
4004 | b b subcommand help
|
---|
4005 | c c subcommand help
|
---|
4006 | d d subcommand help
|
---|
4007 | e e subcommand help
|
---|
4008 |
|
---|
4009 | optional arguments:
|
---|
4010 | -h, --help show this help message and exit
|
---|
4011 | -v, --version show program's version number and exit
|
---|
4012 | '''
|
---|
4013 |
|
---|
4014 | version = '''\
|
---|
4015 | 0.1
|
---|
4016 | '''
|
---|
4017 |
|
---|
4018 |
|
---|
4019 | # =====================================
|
---|
4020 | # Optional/Positional constructor tests
|
---|
4021 | # =====================================
|
---|
4022 |
|
---|
4023 | class TestInvalidArgumentConstructors(TestCase):
|
---|
4024 | """Test a bunch of invalid Argument constructors"""
|
---|
4025 |
|
---|
4026 | def assertTypeError(self, *args, **kwargs):
|
---|
4027 | parser = argparse.ArgumentParser()
|
---|
4028 | self.assertRaises(TypeError, parser.add_argument,
|
---|
4029 | *args, **kwargs)
|
---|
4030 |
|
---|
4031 | def assertValueError(self, *args, **kwargs):
|
---|
4032 | parser = argparse.ArgumentParser()
|
---|
4033 | self.assertRaises(ValueError, parser.add_argument,
|
---|
4034 | *args, **kwargs)
|
---|
4035 |
|
---|
4036 | def test_invalid_keyword_arguments(self):
|
---|
4037 | self.assertTypeError('-x', bar=None)
|
---|
4038 | self.assertTypeError('-y', callback='foo')
|
---|
4039 | self.assertTypeError('-y', callback_args=())
|
---|
4040 | self.assertTypeError('-y', callback_kwargs={})
|
---|
4041 |
|
---|
4042 | def test_missing_destination(self):
|
---|
4043 | self.assertTypeError()
|
---|
4044 | for action in ['append', 'store']:
|
---|
4045 | self.assertTypeError(action=action)
|
---|
4046 |
|
---|
4047 | def test_invalid_option_strings(self):
|
---|
4048 | self.assertValueError('--')
|
---|
4049 | self.assertValueError('---')
|
---|
4050 |
|
---|
4051 | def test_invalid_type(self):
|
---|
4052 | self.assertValueError('--foo', type='int')
|
---|
4053 | self.assertValueError('--foo', type=(int, float))
|
---|
4054 |
|
---|
4055 | def test_invalid_action(self):
|
---|
4056 | self.assertValueError('-x', action='foo')
|
---|
4057 | self.assertValueError('foo', action='baz')
|
---|
4058 | self.assertValueError('--foo', action=('store', 'append'))
|
---|
4059 | parser = argparse.ArgumentParser()
|
---|
4060 | try:
|
---|
4061 | parser.add_argument("--foo", action="store-true")
|
---|
4062 | except ValueError:
|
---|
4063 | e = sys.exc_info()[1]
|
---|
4064 | expected = 'unknown action'
|
---|
4065 | msg = 'expected %r, found %r' % (expected, e)
|
---|
4066 | self.assertTrue(expected in str(e), msg)
|
---|
4067 |
|
---|
4068 | def test_multiple_dest(self):
|
---|
4069 | parser = argparse.ArgumentParser()
|
---|
4070 | parser.add_argument(dest='foo')
|
---|
4071 | try:
|
---|
4072 | parser.add_argument('bar', dest='baz')
|
---|
4073 | except ValueError:
|
---|
4074 | e = sys.exc_info()[1]
|
---|
4075 | expected = 'dest supplied twice for positional argument'
|
---|
4076 | msg = 'expected %r, found %r' % (expected, e)
|
---|
4077 | self.assertTrue(expected in str(e), msg)
|
---|
4078 |
|
---|
4079 | def test_no_argument_actions(self):
|
---|
4080 | for action in ['store_const', 'store_true', 'store_false',
|
---|
4081 | 'append_const', 'count']:
|
---|
4082 | for attrs in [dict(type=int), dict(nargs='+'),
|
---|
4083 | dict(choices='ab')]:
|
---|
4084 | self.assertTypeError('-x', action=action, **attrs)
|
---|
4085 |
|
---|
4086 | def test_no_argument_no_const_actions(self):
|
---|
4087 | # options with zero arguments
|
---|
4088 | for action in ['store_true', 'store_false', 'count']:
|
---|
4089 |
|
---|
4090 | # const is always disallowed
|
---|
4091 | self.assertTypeError('-x', const='foo', action=action)
|
---|
4092 |
|
---|
4093 | # nargs is always disallowed
|
---|
4094 | self.assertTypeError('-x', nargs='*', action=action)
|
---|
4095 |
|
---|
4096 | def test_more_than_one_argument_actions(self):
|
---|
4097 | for action in ['store', 'append']:
|
---|
4098 |
|
---|
4099 | # nargs=0 is disallowed
|
---|
4100 | self.assertValueError('-x', nargs=0, action=action)
|
---|
4101 | self.assertValueError('spam', nargs=0, action=action)
|
---|
4102 |
|
---|
4103 | # const is disallowed with non-optional arguments
|
---|
4104 | for nargs in [1, '*', '+']:
|
---|
4105 | self.assertValueError('-x', const='foo',
|
---|
4106 | nargs=nargs, action=action)
|
---|
4107 | self.assertValueError('spam', const='foo',
|
---|
4108 | nargs=nargs, action=action)
|
---|
4109 |
|
---|
4110 | def test_required_const_actions(self):
|
---|
4111 | for action in ['store_const', 'append_const']:
|
---|
4112 |
|
---|
4113 | # nargs is always disallowed
|
---|
4114 | self.assertTypeError('-x', nargs='+', action=action)
|
---|
4115 |
|
---|
4116 | def test_parsers_action_missing_params(self):
|
---|
4117 | self.assertTypeError('command', action='parsers')
|
---|
4118 | self.assertTypeError('command', action='parsers', prog='PROG')
|
---|
4119 | self.assertTypeError('command', action='parsers',
|
---|
4120 | parser_class=argparse.ArgumentParser)
|
---|
4121 |
|
---|
4122 | def test_required_positional(self):
|
---|
4123 | self.assertTypeError('foo', required=True)
|
---|
4124 |
|
---|
4125 | def test_user_defined_action(self):
|
---|
4126 |
|
---|
4127 | class Success(Exception):
|
---|
4128 | pass
|
---|
4129 |
|
---|
4130 | class Action(object):
|
---|
4131 |
|
---|
4132 | def __init__(self,
|
---|
4133 | option_strings,
|
---|
4134 | dest,
|
---|
4135 | const,
|
---|
4136 | default,
|
---|
4137 | required=False):
|
---|
4138 | if dest == 'spam':
|
---|
4139 | if const is Success:
|
---|
4140 | if default is Success:
|
---|
4141 | raise Success()
|
---|
4142 |
|
---|
4143 | def __call__(self, *args, **kwargs):
|
---|
4144 | pass
|
---|
4145 |
|
---|
4146 | parser = argparse.ArgumentParser()
|
---|
4147 | self.assertRaises(Success, parser.add_argument, '--spam',
|
---|
4148 | action=Action, default=Success, const=Success)
|
---|
4149 | self.assertRaises(Success, parser.add_argument, 'spam',
|
---|
4150 | action=Action, default=Success, const=Success)
|
---|
4151 |
|
---|
4152 | # ================================
|
---|
4153 | # Actions returned by add_argument
|
---|
4154 | # ================================
|
---|
4155 |
|
---|
4156 | class TestActionsReturned(TestCase):
|
---|
4157 |
|
---|
4158 | def test_dest(self):
|
---|
4159 | parser = argparse.ArgumentParser()
|
---|
4160 | action = parser.add_argument('--foo')
|
---|
4161 | self.assertEqual(action.dest, 'foo')
|
---|
4162 | action = parser.add_argument('-b', '--bar')
|
---|
4163 | self.assertEqual(action.dest, 'bar')
|
---|
4164 | action = parser.add_argument('-x', '-y')
|
---|
4165 | self.assertEqual(action.dest, 'x')
|
---|
4166 |
|
---|
4167 | def test_misc(self):
|
---|
4168 | parser = argparse.ArgumentParser()
|
---|
4169 | action = parser.add_argument('--foo', nargs='?', const=42,
|
---|
4170 | default=84, type=int, choices=[1, 2],
|
---|
4171 | help='FOO', metavar='BAR', dest='baz')
|
---|
4172 | self.assertEqual(action.nargs, '?')
|
---|
4173 | self.assertEqual(action.const, 42)
|
---|
4174 | self.assertEqual(action.default, 84)
|
---|
4175 | self.assertEqual(action.type, int)
|
---|
4176 | self.assertEqual(action.choices, [1, 2])
|
---|
4177 | self.assertEqual(action.help, 'FOO')
|
---|
4178 | self.assertEqual(action.metavar, 'BAR')
|
---|
4179 | self.assertEqual(action.dest, 'baz')
|
---|
4180 |
|
---|
4181 |
|
---|
4182 | # ================================
|
---|
4183 | # Argument conflict handling tests
|
---|
4184 | # ================================
|
---|
4185 |
|
---|
4186 | class TestConflictHandling(TestCase):
|
---|
4187 |
|
---|
4188 | def test_bad_type(self):
|
---|
4189 | self.assertRaises(ValueError, argparse.ArgumentParser,
|
---|
4190 | conflict_handler='foo')
|
---|
4191 |
|
---|
4192 | def test_conflict_error(self):
|
---|
4193 | parser = argparse.ArgumentParser()
|
---|
4194 | parser.add_argument('-x')
|
---|
4195 | self.assertRaises(argparse.ArgumentError,
|
---|
4196 | parser.add_argument, '-x')
|
---|
4197 | parser.add_argument('--spam')
|
---|
4198 | self.assertRaises(argparse.ArgumentError,
|
---|
4199 | parser.add_argument, '--spam')
|
---|
4200 |
|
---|
4201 | def test_resolve_error(self):
|
---|
4202 | get_parser = argparse.ArgumentParser
|
---|
4203 | parser = get_parser(prog='PROG', conflict_handler='resolve')
|
---|
4204 |
|
---|
4205 | parser.add_argument('-x', help='OLD X')
|
---|
4206 | parser.add_argument('-x', help='NEW X')
|
---|
4207 | self.assertEqual(parser.format_help(), textwrap.dedent('''\
|
---|
4208 | usage: PROG [-h] [-x X]
|
---|
4209 |
|
---|
4210 | optional arguments:
|
---|
4211 | -h, --help show this help message and exit
|
---|
4212 | -x X NEW X
|
---|
4213 | '''))
|
---|
4214 |
|
---|
4215 | parser.add_argument('--spam', metavar='OLD_SPAM')
|
---|
4216 | parser.add_argument('--spam', metavar='NEW_SPAM')
|
---|
4217 | self.assertEqual(parser.format_help(), textwrap.dedent('''\
|
---|
4218 | usage: PROG [-h] [-x X] [--spam NEW_SPAM]
|
---|
4219 |
|
---|
4220 | optional arguments:
|
---|
4221 | -h, --help show this help message and exit
|
---|
4222 | -x X NEW X
|
---|
4223 | --spam NEW_SPAM
|
---|
4224 | '''))
|
---|
4225 |
|
---|
4226 |
|
---|
4227 | # =============================
|
---|
4228 | # Help and Version option tests
|
---|
4229 | # =============================
|
---|
4230 |
|
---|
4231 | class TestOptionalsHelpVersionActions(TestCase):
|
---|
4232 | """Test the help and version actions"""
|
---|
4233 |
|
---|
4234 | def _get_error(self, func, *args, **kwargs):
|
---|
4235 | try:
|
---|
4236 | func(*args, **kwargs)
|
---|
4237 | except ArgumentParserError:
|
---|
4238 | return sys.exc_info()[1]
|
---|
4239 | else:
|
---|
4240 | self.assertRaises(ArgumentParserError, func, *args, **kwargs)
|
---|
4241 |
|
---|
4242 | def assertPrintHelpExit(self, parser, args_str):
|
---|
4243 | self.assertEqual(
|
---|
4244 | parser.format_help(),
|
---|
4245 | self._get_error(parser.parse_args, args_str.split()).stdout)
|
---|
4246 |
|
---|
4247 | def assertPrintVersionExit(self, parser, args_str):
|
---|
4248 | self.assertEqual(
|
---|
4249 | parser.format_version(),
|
---|
4250 | self._get_error(parser.parse_args, args_str.split()).stderr)
|
---|
4251 |
|
---|
4252 | def assertArgumentParserError(self, parser, *args):
|
---|
4253 | self.assertRaises(ArgumentParserError, parser.parse_args, args)
|
---|
4254 |
|
---|
4255 | def test_version(self):
|
---|
4256 | parser = ErrorRaisingArgumentParser(version='1.0')
|
---|
4257 | self.assertPrintHelpExit(parser, '-h')
|
---|
4258 | self.assertPrintHelpExit(parser, '--help')
|
---|
4259 | self.assertPrintVersionExit(parser, '-v')
|
---|
4260 | self.assertPrintVersionExit(parser, '--version')
|
---|
4261 |
|
---|
4262 | def test_version_format(self):
|
---|
4263 | parser = ErrorRaisingArgumentParser(prog='PPP', version='%(prog)s 3.5')
|
---|
4264 | msg = self._get_error(parser.parse_args, ['-v']).stderr
|
---|
4265 | self.assertEqual('PPP 3.5\n', msg)
|
---|
4266 |
|
---|
4267 | def test_version_no_help(self):
|
---|
4268 | parser = ErrorRaisingArgumentParser(add_help=False, version='1.0')
|
---|
4269 | self.assertArgumentParserError(parser, '-h')
|
---|
4270 | self.assertArgumentParserError(parser, '--help')
|
---|
4271 | self.assertPrintVersionExit(parser, '-v')
|
---|
4272 | self.assertPrintVersionExit(parser, '--version')
|
---|
4273 |
|
---|
4274 | def test_version_action(self):
|
---|
4275 | parser = ErrorRaisingArgumentParser(prog='XXX')
|
---|
4276 | parser.add_argument('-V', action='version', version='%(prog)s 3.7')
|
---|
4277 | msg = self._get_error(parser.parse_args, ['-V']).stderr
|
---|
4278 | self.assertEqual('XXX 3.7\n', msg)
|
---|
4279 |
|
---|
4280 | def test_no_help(self):
|
---|
4281 | parser = ErrorRaisingArgumentParser(add_help=False)
|
---|
4282 | self.assertArgumentParserError(parser, '-h')
|
---|
4283 | self.assertArgumentParserError(parser, '--help')
|
---|
4284 | self.assertArgumentParserError(parser, '-v')
|
---|
4285 | self.assertArgumentParserError(parser, '--version')
|
---|
4286 |
|
---|
4287 | def test_alternate_help_version(self):
|
---|
4288 | parser = ErrorRaisingArgumentParser()
|
---|
4289 | parser.add_argument('-x', action='help')
|
---|
4290 | parser.add_argument('-y', action='version')
|
---|
4291 | self.assertPrintHelpExit(parser, '-x')
|
---|
4292 | self.assertPrintVersionExit(parser, '-y')
|
---|
4293 | self.assertArgumentParserError(parser, '-v')
|
---|
4294 | self.assertArgumentParserError(parser, '--version')
|
---|
4295 |
|
---|
4296 | def test_help_version_extra_arguments(self):
|
---|
4297 | parser = ErrorRaisingArgumentParser(version='1.0')
|
---|
4298 | parser.add_argument('-x', action='store_true')
|
---|
4299 | parser.add_argument('y')
|
---|
4300 |
|
---|
4301 | # try all combinations of valid prefixes and suffixes
|
---|
4302 | valid_prefixes = ['', '-x', 'foo', '-x bar', 'baz -x']
|
---|
4303 | valid_suffixes = valid_prefixes + ['--bad-option', 'foo bar baz']
|
---|
4304 | for prefix in valid_prefixes:
|
---|
4305 | for suffix in valid_suffixes:
|
---|
4306 | format = '%s %%s %s' % (prefix, suffix)
|
---|
4307 | self.assertPrintHelpExit(parser, format % '-h')
|
---|
4308 | self.assertPrintHelpExit(parser, format % '--help')
|
---|
4309 | self.assertPrintVersionExit(parser, format % '-v')
|
---|
4310 | self.assertPrintVersionExit(parser, format % '--version')
|
---|
4311 |
|
---|
4312 |
|
---|
4313 | # ======================
|
---|
4314 | # str() and repr() tests
|
---|
4315 | # ======================
|
---|
4316 |
|
---|
4317 | class TestStrings(TestCase):
|
---|
4318 | """Test str() and repr() on Optionals and Positionals"""
|
---|
4319 |
|
---|
4320 | def assertStringEqual(self, obj, result_string):
|
---|
4321 | for func in [str, repr]:
|
---|
4322 | self.assertEqual(func(obj), result_string)
|
---|
4323 |
|
---|
4324 | def test_optional(self):
|
---|
4325 | option = argparse.Action(
|
---|
4326 | option_strings=['--foo', '-a', '-b'],
|
---|
4327 | dest='b',
|
---|
4328 | type='int',
|
---|
4329 | nargs='+',
|
---|
4330 | default=42,
|
---|
4331 | choices=[1, 2, 3],
|
---|
4332 | help='HELP',
|
---|
4333 | metavar='METAVAR')
|
---|
4334 | string = (
|
---|
4335 | "Action(option_strings=['--foo', '-a', '-b'], dest='b', "
|
---|
4336 | "nargs='+', const=None, default=42, type='int', "
|
---|
4337 | "choices=[1, 2, 3], help='HELP', metavar='METAVAR')")
|
---|
4338 | self.assertStringEqual(option, string)
|
---|
4339 |
|
---|
4340 | def test_argument(self):
|
---|
4341 | argument = argparse.Action(
|
---|
4342 | option_strings=[],
|
---|
4343 | dest='x',
|
---|
4344 | type=float,
|
---|
4345 | nargs='?',
|
---|
4346 | default=2.5,
|
---|
4347 | choices=[0.5, 1.5, 2.5],
|
---|
4348 | help='H HH H',
|
---|
4349 | metavar='MV MV MV')
|
---|
4350 | string = (
|
---|
4351 | "Action(option_strings=[], dest='x', nargs='?', "
|
---|
4352 | "const=None, default=2.5, type=%r, choices=[0.5, 1.5, 2.5], "
|
---|
4353 | "help='H HH H', metavar='MV MV MV')" % float)
|
---|
4354 | self.assertStringEqual(argument, string)
|
---|
4355 |
|
---|
4356 | def test_namespace(self):
|
---|
4357 | ns = argparse.Namespace(foo=42, bar='spam')
|
---|
4358 | string = "Namespace(bar='spam', foo=42)"
|
---|
4359 | self.assertStringEqual(ns, string)
|
---|
4360 |
|
---|
4361 | def test_parser(self):
|
---|
4362 | parser = argparse.ArgumentParser(prog='PROG')
|
---|
4363 | string = (
|
---|
4364 | "ArgumentParser(prog='PROG', usage=None, description=None, "
|
---|
4365 | "version=None, formatter_class=%r, conflict_handler='error', "
|
---|
4366 | "add_help=True)" % argparse.HelpFormatter)
|
---|
4367 | self.assertStringEqual(parser, string)
|
---|
4368 |
|
---|
4369 | # ===============
|
---|
4370 | # Namespace tests
|
---|
4371 | # ===============
|
---|
4372 |
|
---|
4373 | class TestNamespace(TestCase):
|
---|
4374 |
|
---|
4375 | def test_constructor(self):
|
---|
4376 | ns = argparse.Namespace()
|
---|
4377 | self.assertRaises(AttributeError, getattr, ns, 'x')
|
---|
4378 |
|
---|
4379 | ns = argparse.Namespace(a=42, b='spam')
|
---|
4380 | self.assertEqual(ns.a, 42)
|
---|
4381 | self.assertEqual(ns.b, 'spam')
|
---|
4382 |
|
---|
4383 | def test_equality(self):
|
---|
4384 | ns1 = argparse.Namespace(a=1, b=2)
|
---|
4385 | ns2 = argparse.Namespace(b=2, a=1)
|
---|
4386 | ns3 = argparse.Namespace(a=1)
|
---|
4387 | ns4 = argparse.Namespace(b=2)
|
---|
4388 |
|
---|
4389 | self.assertEqual(ns1, ns2)
|
---|
4390 | self.assertNotEqual(ns1, ns3)
|
---|
4391 | self.assertNotEqual(ns1, ns4)
|
---|
4392 | self.assertNotEqual(ns2, ns3)
|
---|
4393 | self.assertNotEqual(ns2, ns4)
|
---|
4394 | self.assertTrue(ns1 != ns3)
|
---|
4395 | self.assertTrue(ns1 != ns4)
|
---|
4396 | self.assertTrue(ns2 != ns3)
|
---|
4397 | self.assertTrue(ns2 != ns4)
|
---|
4398 |
|
---|
4399 |
|
---|
4400 | # ===================
|
---|
4401 | # File encoding tests
|
---|
4402 | # ===================
|
---|
4403 |
|
---|
4404 | class TestEncoding(TestCase):
|
---|
4405 |
|
---|
4406 | def _test_module_encoding(self, path):
|
---|
4407 | path, _ = os.path.splitext(path)
|
---|
4408 | path += ".py"
|
---|
4409 | with codecs.open(path, 'r', 'utf8') as f:
|
---|
4410 | f.read()
|
---|
4411 |
|
---|
4412 | def test_argparse_module_encoding(self):
|
---|
4413 | self._test_module_encoding(argparse.__file__)
|
---|
4414 |
|
---|
4415 | def test_test_argparse_module_encoding(self):
|
---|
4416 | self._test_module_encoding(__file__)
|
---|
4417 |
|
---|
4418 | # ===================
|
---|
4419 | # ArgumentError tests
|
---|
4420 | # ===================
|
---|
4421 |
|
---|
4422 | class TestArgumentError(TestCase):
|
---|
4423 |
|
---|
4424 | def test_argument_error(self):
|
---|
4425 | msg = "my error here"
|
---|
4426 | error = argparse.ArgumentError(None, msg)
|
---|
4427 | self.assertEqual(str(error), msg)
|
---|
4428 |
|
---|
4429 | # =======================
|
---|
4430 | # ArgumentTypeError tests
|
---|
4431 | # =======================
|
---|
4432 |
|
---|
4433 | class TestArgumentTypeError(TestCase):
|
---|
4434 |
|
---|
4435 | def test_argument_type_error(self):
|
---|
4436 |
|
---|
4437 | def spam(string):
|
---|
4438 | raise argparse.ArgumentTypeError('spam!')
|
---|
4439 |
|
---|
4440 | parser = ErrorRaisingArgumentParser(prog='PROG', add_help=False)
|
---|
4441 | parser.add_argument('x', type=spam)
|
---|
4442 | try:
|
---|
4443 | parser.parse_args(['XXX'])
|
---|
4444 | except ArgumentParserError:
|
---|
4445 | expected = 'usage: PROG x\nPROG: error: argument x: spam!\n'
|
---|
4446 | msg = sys.exc_info()[1].stderr
|
---|
4447 | self.assertEqual(expected, msg)
|
---|
4448 | else:
|
---|
4449 | self.fail()
|
---|
4450 |
|
---|
4451 | # ================================================
|
---|
4452 | # Check that the type function is called only once
|
---|
4453 | # ================================================
|
---|
4454 |
|
---|
4455 | class TestTypeFunctionCallOnlyOnce(TestCase):
|
---|
4456 |
|
---|
4457 | def test_type_function_call_only_once(self):
|
---|
4458 | def spam(string_to_convert):
|
---|
4459 | self.assertEqual(string_to_convert, 'spam!')
|
---|
4460 | return 'foo_converted'
|
---|
4461 |
|
---|
4462 | parser = argparse.ArgumentParser()
|
---|
4463 | parser.add_argument('--foo', type=spam, default='bar')
|
---|
4464 | args = parser.parse_args('--foo spam!'.split())
|
---|
4465 | self.assertEqual(NS(foo='foo_converted'), args)
|
---|
4466 |
|
---|
4467 | # ==================================================================
|
---|
4468 | # Check semantics regarding the default argument and type conversion
|
---|
4469 | # ==================================================================
|
---|
4470 |
|
---|
4471 | class TestTypeFunctionCalledOnDefault(TestCase):
|
---|
4472 |
|
---|
4473 | def test_type_function_call_with_non_string_default(self):
|
---|
4474 | def spam(int_to_convert):
|
---|
4475 | self.assertEqual(int_to_convert, 0)
|
---|
4476 | return 'foo_converted'
|
---|
4477 |
|
---|
4478 | parser = argparse.ArgumentParser()
|
---|
4479 | parser.add_argument('--foo', type=spam, default=0)
|
---|
4480 | args = parser.parse_args([])
|
---|
4481 | # foo should *not* be converted because its default is not a string.
|
---|
4482 | self.assertEqual(NS(foo=0), args)
|
---|
4483 |
|
---|
4484 | def test_type_function_call_with_string_default(self):
|
---|
4485 | def spam(int_to_convert):
|
---|
4486 | return 'foo_converted'
|
---|
4487 |
|
---|
4488 | parser = argparse.ArgumentParser()
|
---|
4489 | parser.add_argument('--foo', type=spam, default='0')
|
---|
4490 | args = parser.parse_args([])
|
---|
4491 | # foo is converted because its default is a string.
|
---|
4492 | self.assertEqual(NS(foo='foo_converted'), args)
|
---|
4493 |
|
---|
4494 | def test_no_double_type_conversion_of_default(self):
|
---|
4495 | def extend(str_to_convert):
|
---|
4496 | return str_to_convert + '*'
|
---|
4497 |
|
---|
4498 | parser = argparse.ArgumentParser()
|
---|
4499 | parser.add_argument('--test', type=extend, default='*')
|
---|
4500 | args = parser.parse_args([])
|
---|
4501 | # The test argument will be two stars, one coming from the default
|
---|
4502 | # value and one coming from the type conversion being called exactly
|
---|
4503 | # once.
|
---|
4504 | self.assertEqual(NS(test='**'), args)
|
---|
4505 |
|
---|
4506 | def test_issue_15906(self):
|
---|
4507 | # Issue #15906: When action='append', type=str, default=[] are
|
---|
4508 | # providing, the dest value was the string representation "[]" when it
|
---|
4509 | # should have been an empty list.
|
---|
4510 | parser = argparse.ArgumentParser()
|
---|
4511 | parser.add_argument('--test', dest='test', type=str,
|
---|
4512 | default=[], action='append')
|
---|
4513 | args = parser.parse_args([])
|
---|
4514 | self.assertEqual(args.test, [])
|
---|
4515 |
|
---|
4516 | # ======================
|
---|
4517 | # parse_known_args tests
|
---|
4518 | # ======================
|
---|
4519 |
|
---|
4520 | class TestParseKnownArgs(TestCase):
|
---|
4521 |
|
---|
4522 | def test_arguments_tuple(self):
|
---|
4523 | parser = argparse.ArgumentParser()
|
---|
4524 | parser.parse_args(())
|
---|
4525 |
|
---|
4526 | def test_arguments_list(self):
|
---|
4527 | parser = argparse.ArgumentParser()
|
---|
4528 | parser.parse_args([])
|
---|
4529 |
|
---|
4530 | def test_arguments_tuple_positional(self):
|
---|
4531 | parser = argparse.ArgumentParser()
|
---|
4532 | parser.add_argument('x')
|
---|
4533 | parser.parse_args(('x',))
|
---|
4534 |
|
---|
4535 | def test_arguments_list_positional(self):
|
---|
4536 | parser = argparse.ArgumentParser()
|
---|
4537 | parser.add_argument('x')
|
---|
4538 | parser.parse_args(['x'])
|
---|
4539 |
|
---|
4540 | def test_optionals(self):
|
---|
4541 | parser = argparse.ArgumentParser()
|
---|
4542 | parser.add_argument('--foo')
|
---|
4543 | args, extras = parser.parse_known_args('--foo F --bar --baz'.split())
|
---|
4544 | self.assertEqual(NS(foo='F'), args)
|
---|
4545 | self.assertEqual(['--bar', '--baz'], extras)
|
---|
4546 |
|
---|
4547 | def test_mixed(self):
|
---|
4548 | parser = argparse.ArgumentParser()
|
---|
4549 | parser.add_argument('-v', nargs='?', const=1, type=int)
|
---|
4550 | parser.add_argument('--spam', action='store_false')
|
---|
4551 | parser.add_argument('badger')
|
---|
4552 |
|
---|
4553 | argv = ["B", "C", "--foo", "-v", "3", "4"]
|
---|
4554 | args, extras = parser.parse_known_args(argv)
|
---|
4555 | self.assertEqual(NS(v=3, spam=True, badger="B"), args)
|
---|
4556 | self.assertEqual(["C", "--foo", "4"], extras)
|
---|
4557 |
|
---|
4558 | # ==========================
|
---|
4559 | # add_argument metavar tests
|
---|
4560 | # ==========================
|
---|
4561 |
|
---|
4562 | class TestAddArgumentMetavar(TestCase):
|
---|
4563 |
|
---|
4564 | EXPECTED_MESSAGE = "length of metavar tuple does not match nargs"
|
---|
4565 |
|
---|
4566 | def do_test_no_exception(self, nargs, metavar):
|
---|
4567 | parser = argparse.ArgumentParser()
|
---|
4568 | parser.add_argument("--foo", nargs=nargs, metavar=metavar)
|
---|
4569 |
|
---|
4570 | def do_test_exception(self, nargs, metavar):
|
---|
4571 | parser = argparse.ArgumentParser()
|
---|
4572 | with self.assertRaises(ValueError) as cm:
|
---|
4573 | parser.add_argument("--foo", nargs=nargs, metavar=metavar)
|
---|
4574 | self.assertEqual(cm.exception.args[0], self.EXPECTED_MESSAGE)
|
---|
4575 |
|
---|
4576 | # Unit tests for different values of metavar when nargs=None
|
---|
4577 |
|
---|
4578 | def test_nargs_None_metavar_string(self):
|
---|
4579 | self.do_test_no_exception(nargs=None, metavar="1")
|
---|
4580 |
|
---|
4581 | def test_nargs_None_metavar_length0(self):
|
---|
4582 | self.do_test_exception(nargs=None, metavar=tuple())
|
---|
4583 |
|
---|
4584 | def test_nargs_None_metavar_length1(self):
|
---|
4585 | self.do_test_no_exception(nargs=None, metavar=("1"))
|
---|
4586 |
|
---|
4587 | def test_nargs_None_metavar_length2(self):
|
---|
4588 | self.do_test_exception(nargs=None, metavar=("1", "2"))
|
---|
4589 |
|
---|
4590 | def test_nargs_None_metavar_length3(self):
|
---|
4591 | self.do_test_exception(nargs=None, metavar=("1", "2", "3"))
|
---|
4592 |
|
---|
4593 | # Unit tests for different values of metavar when nargs=?
|
---|
4594 |
|
---|
4595 | def test_nargs_optional_metavar_string(self):
|
---|
4596 | self.do_test_no_exception(nargs="?", metavar="1")
|
---|
4597 |
|
---|
4598 | def test_nargs_optional_metavar_length0(self):
|
---|
4599 | self.do_test_exception(nargs="?", metavar=tuple())
|
---|
4600 |
|
---|
4601 | def test_nargs_optional_metavar_length1(self):
|
---|
4602 | self.do_test_no_exception(nargs="?", metavar=("1"))
|
---|
4603 |
|
---|
4604 | def test_nargs_optional_metavar_length2(self):
|
---|
4605 | self.do_test_exception(nargs="?", metavar=("1", "2"))
|
---|
4606 |
|
---|
4607 | def test_nargs_optional_metavar_length3(self):
|
---|
4608 | self.do_test_exception(nargs="?", metavar=("1", "2", "3"))
|
---|
4609 |
|
---|
4610 | # Unit tests for different values of metavar when nargs=*
|
---|
4611 |
|
---|
4612 | def test_nargs_zeroormore_metavar_string(self):
|
---|
4613 | self.do_test_no_exception(nargs="*", metavar="1")
|
---|
4614 |
|
---|
4615 | def test_nargs_zeroormore_metavar_length0(self):
|
---|
4616 | self.do_test_exception(nargs="*", metavar=tuple())
|
---|
4617 |
|
---|
4618 | def test_nargs_zeroormore_metavar_length1(self):
|
---|
4619 | self.do_test_no_exception(nargs="*", metavar=("1"))
|
---|
4620 |
|
---|
4621 | def test_nargs_zeroormore_metavar_length2(self):
|
---|
4622 | self.do_test_no_exception(nargs="*", metavar=("1", "2"))
|
---|
4623 |
|
---|
4624 | def test_nargs_zeroormore_metavar_length3(self):
|
---|
4625 | self.do_test_exception(nargs="*", metavar=("1", "2", "3"))
|
---|
4626 |
|
---|
4627 | # Unit tests for different values of metavar when nargs=+
|
---|
4628 |
|
---|
4629 | def test_nargs_oneormore_metavar_string(self):
|
---|
4630 | self.do_test_no_exception(nargs="+", metavar="1")
|
---|
4631 |
|
---|
4632 | def test_nargs_oneormore_metavar_length0(self):
|
---|
4633 | self.do_test_exception(nargs="+", metavar=tuple())
|
---|
4634 |
|
---|
4635 | def test_nargs_oneormore_metavar_length1(self):
|
---|
4636 | self.do_test_no_exception(nargs="+", metavar=("1"))
|
---|
4637 |
|
---|
4638 | def test_nargs_oneormore_metavar_length2(self):
|
---|
4639 | self.do_test_no_exception(nargs="+", metavar=("1", "2"))
|
---|
4640 |
|
---|
4641 | def test_nargs_oneormore_metavar_length3(self):
|
---|
4642 | self.do_test_exception(nargs="+", metavar=("1", "2", "3"))
|
---|
4643 |
|
---|
4644 | # Unit tests for different values of metavar when nargs=...
|
---|
4645 |
|
---|
4646 | def test_nargs_remainder_metavar_string(self):
|
---|
4647 | self.do_test_no_exception(nargs="...", metavar="1")
|
---|
4648 |
|
---|
4649 | def test_nargs_remainder_metavar_length0(self):
|
---|
4650 | self.do_test_no_exception(nargs="...", metavar=tuple())
|
---|
4651 |
|
---|
4652 | def test_nargs_remainder_metavar_length1(self):
|
---|
4653 | self.do_test_no_exception(nargs="...", metavar=("1"))
|
---|
4654 |
|
---|
4655 | def test_nargs_remainder_metavar_length2(self):
|
---|
4656 | self.do_test_no_exception(nargs="...", metavar=("1", "2"))
|
---|
4657 |
|
---|
4658 | def test_nargs_remainder_metavar_length3(self):
|
---|
4659 | self.do_test_no_exception(nargs="...", metavar=("1", "2", "3"))
|
---|
4660 |
|
---|
4661 | # Unit tests for different values of metavar when nargs=A...
|
---|
4662 |
|
---|
4663 | def test_nargs_parser_metavar_string(self):
|
---|
4664 | self.do_test_no_exception(nargs="A...", metavar="1")
|
---|
4665 |
|
---|
4666 | def test_nargs_parser_metavar_length0(self):
|
---|
4667 | self.do_test_exception(nargs="A...", metavar=tuple())
|
---|
4668 |
|
---|
4669 | def test_nargs_parser_metavar_length1(self):
|
---|
4670 | self.do_test_no_exception(nargs="A...", metavar=("1"))
|
---|
4671 |
|
---|
4672 | def test_nargs_parser_metavar_length2(self):
|
---|
4673 | self.do_test_exception(nargs="A...", metavar=("1", "2"))
|
---|
4674 |
|
---|
4675 | def test_nargs_parser_metavar_length3(self):
|
---|
4676 | self.do_test_exception(nargs="A...", metavar=("1", "2", "3"))
|
---|
4677 |
|
---|
4678 | # Unit tests for different values of metavar when nargs=1
|
---|
4679 |
|
---|
4680 | def test_nargs_1_metavar_string(self):
|
---|
4681 | self.do_test_no_exception(nargs=1, metavar="1")
|
---|
4682 |
|
---|
4683 | def test_nargs_1_metavar_length0(self):
|
---|
4684 | self.do_test_exception(nargs=1, metavar=tuple())
|
---|
4685 |
|
---|
4686 | def test_nargs_1_metavar_length1(self):
|
---|
4687 | self.do_test_no_exception(nargs=1, metavar=("1"))
|
---|
4688 |
|
---|
4689 | def test_nargs_1_metavar_length2(self):
|
---|
4690 | self.do_test_exception(nargs=1, metavar=("1", "2"))
|
---|
4691 |
|
---|
4692 | def test_nargs_1_metavar_length3(self):
|
---|
4693 | self.do_test_exception(nargs=1, metavar=("1", "2", "3"))
|
---|
4694 |
|
---|
4695 | # Unit tests for different values of metavar when nargs=2
|
---|
4696 |
|
---|
4697 | def test_nargs_2_metavar_string(self):
|
---|
4698 | self.do_test_no_exception(nargs=2, metavar="1")
|
---|
4699 |
|
---|
4700 | def test_nargs_2_metavar_length0(self):
|
---|
4701 | self.do_test_exception(nargs=2, metavar=tuple())
|
---|
4702 |
|
---|
4703 | def test_nargs_2_metavar_length1(self):
|
---|
4704 | self.do_test_no_exception(nargs=2, metavar=("1"))
|
---|
4705 |
|
---|
4706 | def test_nargs_2_metavar_length2(self):
|
---|
4707 | self.do_test_no_exception(nargs=2, metavar=("1", "2"))
|
---|
4708 |
|
---|
4709 | def test_nargs_2_metavar_length3(self):
|
---|
4710 | self.do_test_exception(nargs=2, metavar=("1", "2", "3"))
|
---|
4711 |
|
---|
4712 | # Unit tests for different values of metavar when nargs=3
|
---|
4713 |
|
---|
4714 | def test_nargs_3_metavar_string(self):
|
---|
4715 | self.do_test_no_exception(nargs=3, metavar="1")
|
---|
4716 |
|
---|
4717 | def test_nargs_3_metavar_length0(self):
|
---|
4718 | self.do_test_exception(nargs=3, metavar=tuple())
|
---|
4719 |
|
---|
4720 | def test_nargs_3_metavar_length1(self):
|
---|
4721 | self.do_test_no_exception(nargs=3, metavar=("1"))
|
---|
4722 |
|
---|
4723 | def test_nargs_3_metavar_length2(self):
|
---|
4724 | self.do_test_exception(nargs=3, metavar=("1", "2"))
|
---|
4725 |
|
---|
4726 | def test_nargs_3_metavar_length3(self):
|
---|
4727 | self.do_test_no_exception(nargs=3, metavar=("1", "2", "3"))
|
---|
4728 |
|
---|
4729 | # ============================
|
---|
4730 | # from argparse import * tests
|
---|
4731 | # ============================
|
---|
4732 |
|
---|
4733 | class TestImportStar(TestCase):
|
---|
4734 |
|
---|
4735 | def test(self):
|
---|
4736 | for name in argparse.__all__:
|
---|
4737 | self.assertTrue(hasattr(argparse, name))
|
---|
4738 |
|
---|
4739 | def test_all_exports_everything_but_modules(self):
|
---|
4740 | items = [
|
---|
4741 | name
|
---|
4742 | for name, value in vars(argparse).items()
|
---|
4743 | if not name.startswith("_")
|
---|
4744 | if not inspect.ismodule(value)
|
---|
4745 | ]
|
---|
4746 | self.assertEqual(sorted(items), sorted(argparse.__all__))
|
---|
4747 |
|
---|
4748 | def test_main():
|
---|
4749 | # silence warnings about version argument - these are expected
|
---|
4750 | with test_support.check_warnings(
|
---|
4751 | ('The "version" argument to ArgumentParser is deprecated.',
|
---|
4752 | DeprecationWarning),
|
---|
4753 | ('The (format|print)_version method is deprecated',
|
---|
4754 | DeprecationWarning)):
|
---|
4755 | test_support.run_unittest(__name__)
|
---|
4756 | # Remove global references to avoid looking like we have refleaks.
|
---|
4757 | RFile.seen = {}
|
---|
4758 | WFile.seen = set()
|
---|
4759 |
|
---|
4760 |
|
---|
4761 |
|
---|
4762 | if __name__ == '__main__':
|
---|
4763 | test_main()
|
---|