import argparse NS = argparse.Namespace def run(argv,ns=None): if isinstance(argv,str): print(repr(argv)) argv = argv.split() try: args = parser.parse_args(argv) print(args) if ns: assert(args==ns) except SystemExit as e: pass parser = argparse.ArgumentParser(description='') parser.add_argument('-w') parser.add_argument('-x', nargs='+') parser.add_argument('y',type=int) parser.add_argument('z', nargs='*',type=int) trials = [('-w 1 -x 2 3 4 5', NS(w='1', x=['2', '3', '4'], y=5, z=[])), # prototypical case for this issue ('-w 1 -x2 3 4 5', NS(w='1', x=['2'], y=3, z=[4, 5])), # not an issue case ('-w 1 2 -x 3 4 5', NS(w='1', x=['3', '4', '5'], y=2, z=[])), # not an issue ('-w 1 -x 2 3', NS(w='1', x=['2'], y=3, z=[])), # issue ('-w 1 -x2 3', NS(w='1', x=['2'], y=3, z=[])), # not ('-w 1 -x 2 3 -w 4', NS(w='4', x=['2'], y=3, z=[]) ), # issue ('-x 1 2 -w 3 4 5 6',NS(w='3', x=['1', '2'], y=4, z=[5, 6]) ), # not # if pattern isnt general enough, x=[1],y=2, z=[], [5,6] extras ('-x 1 2 3 4 -w 5 6 7', NS(w='5', x=['1', '2', '3', '4'], y=6, z=[7])), # not # alt? w:5, x:[1,2,3], y:4, z:[6,7] - ('1 2 3 -x 4 5 -w 6', NS(w='6', x=['4', '5'], y=1, z=[2, 3])), # not ('1 2 3',NS(w=None, x=None, y=1, z=[2, 3])), ('1 -x 2 3 -w 4 5 6',NS(w='4', x=['2', '3'], y=1, z=[5, 6])), # not # error: unrecognized arguments: 5 6 # z consumed in 1st positionals group ('-x 1 2 3 4 -w 5',NS(w='5', x=['1', '2', '3'], y=4, z=[])), ] # '-x 1 2 -w 3 4' - how it matches depends on which order of x and w are allowed # [-xA A -wA A] versus [-xAA -wA A] for astr in trials: if isinstance(astr,(tuple,list)): ns = astr[1] astr = astr[0] else: ns = None argv = astr.split() print(repr(astr)) run(argv,ns) print('') parser = argparse.ArgumentParser(description='') parser.add_argument('-x', nargs='?') parser.add_argument('y',type=int) run('-x 1', NS(x=None, y=1)) run('-x 1 2', NS(x='1', y=2)) parser = argparse.ArgumentParser(description='') parser.add_argument('-x', nargs='*') parser.add_argument('y',type=int) run('-x 1', NS(x=[], y=1)) run('-x 1 2', NS(x=['1'], y=2)) run('-x 1 2 3',NS(x=['1', '2'], y=3)) parser = argparse.ArgumentParser(description='') parser.add_argument('-x', nargs='*') parser.add_argument('y',type=int,nargs=2) run('-x 1') # error run('-x 1 2', NS(x=[], y=[1,2])) run('-x 1 2 3',NS(x=['1'], y=[2,3])) parser=argparse.ArgumentParser(prog='TestTypeCallable') parser.add_argument('--eggs', type=complex) parser.add_argument('spam', type=float) run('--eggs=42 42',NS(eggs=(42+0j), spam=42.0)) run('--eggs 42 42',NS(eggs=(42+0j), spam=42.0)) run('--eggs 2j -- -1.5',NS(eggs=2j, spam=-1.5)) parser=argparse.ArgumentParser(prog='TestOptionalsSingleDashCombined') parser.add_argument('-x', action='store_true') parser.add_argument('-yyy', action='store_const', const=42) parser.add_argument('-z') successes = [ ('', NS(x=False, yyy=None, z=None)), ('-x', NS(x=True, yyy=None, z=None)), ('-za', NS(x=False, yyy=None, z='a')), ('-z a', NS(x=False, yyy=None, z='a')), ('-xza', NS(x=True, yyy=None, z='a')), ('-xz a', NS(x=True, yyy=None, z='a')), ('-x -za', NS(x=True, yyy=None, z='a')), ('-x -z a', NS(x=True, yyy=None, z='a')), ('-y', NS(x=False, yyy=42, z=None)), ('-yyy', NS(x=False, yyy=42, z=None)), ('-x -yyy -za', NS(x=True, yyy=42, z='a')), ('-x -yyy -z a', NS(x=True, yyy=42, z='a')), ] for s in successes: run(*s) print('failures') failures = ['a', '--foo', '-xa', '-x --foo', '-x -z', '-z -x', '-yx', '-yz a', '-yyyx', '-yyyza', '-xyza'] for f in failures: run(f) parser = argparse.ArgumentParser(prog='TestMessageContentError') parser.add_argument('req_pos', type=str) parser.add_argument('-req_opt', type=int, required=True) parser.add_argument('need_one', type=str, nargs='+') run('') # error: the following arguments are required: req_pos, -req_opt, need_one # skips subparsers and prefix_chars