4

I want to allow arbitrary command line arguments. If the user provides me with a command line that looks like this

myscript.py --a valueofa --b valueofb posarg1 posarg2

I know that a was passed with valueofa, b passed with valueofb and that I have these last two positional arguments.

I've always used optparse, for which you specify exactly which arguments to look for. But I want the user to be able to define arbitrary "macros" from the command line. Surely there's a python module that does it more elegantly than anything I'd write. What is?

pythonic metaphor
  • 10,296
  • 18
  • 68
  • 110

3 Answers3

4

arbitrary_args.py:

#!/usr/bin/env python3

import sys


def parse_args_any(args):
    pos = []
    named = {}
    key = None
    for arg in args:
        if key:
            if arg.startswith('--'):
                named[key] = True
                key = arg[2:]
            else:
                named[key] = arg
                key = None
        elif arg.startswith('--'):
            key = arg[2:]
        else:
            pos.append(arg)
    if key:
        named[key] = True
    return (pos, named)


def main(argv):
    print(parse_args_any(argv))


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))

$./arbitrary_args.py cmd posarg1 posarg2 --foo --bar baz posarg3 --quux:

(['cmd', 'posarg1', 'posarg2', 'posarg3'], {'foo': True, 'bar': 'baz', 'quux': True})

argparse_arbitrary.py:

#!/usr/bin/env python3
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-D', action='append', )
D = {L[0]:L[1] for L in [s.split('=') for s in parser.parse_args().D]}
print(D)

$./argparse_arbitrary.py -Ddrink=coffee -Dsnack=peanut

{'snack': 'peanut', 'drink': 'coffee'}

2

Sadly, you can't. If you have to support this, you'll need to write your own option parser =(.

Community
  • 1
  • 1
Katriel
  • 120,462
  • 19
  • 136
  • 170
0

Will argparse do what you want? It was recently added to the standard library. Specifically, you might want to look at this section of the documentation.

ʇsәɹoɈ
  • 22,757
  • 7
  • 55
  • 61
  • 1
    I think it doesn't: "The parse_args method attempts to give errors whenever the user has clearly made a mistake" means that undefined arguments will cause errors. In fact, I think this is deliberate behaviour -- it's not often that you want to allow e.g. spelling mistakes. – Katriel Jul 28 '10 at 19:35