views:

1723

answers:

6

I'm writing a shell for a project of mine, which by design parses commands that looks like this:

COMMAND_NAME ARG1="Long Value" ARG2=123 [email protected]

My problem is that Python's command line parsing libraries (getopt and optparse) forces me to use '-' or '--' in front of the arguments. This behavior doesn't match my requirements.

Any ideas how can this be solved? Any existing library for this?

A: 

Without fairly intensive surgery on optparse or getopt, I don't believe you can sensibly make them parse your format. You can easily parse your own format, though, or translate it into something optparse could handle:

parser = optparse.OptionParser()
parser.add_option("--ARG1", dest="arg1", help="....")
parser.add_option(...)
...
newargs = sys.argv[:1]
for idx, arg in enumerate(sys.argv[1:])
    parts = arg.split('=', 1)
    if len(parts) < 2:
        # End of options, don't translate the rest. 
        newargs.extend(sys.argv[idx+1:])
        break
    argname, argvalue = parts
    newargs.extend(["--%s" % argname, argvalue])

parser.parse_args(newargs)
Thomas Wouters
+3  A: 

You could split them up with shlex.split(), which can handle the quoted values you have, and pretty easily parse this with a very simple regular expression. Or, you can just use regular expressions for both splitting and parsing. Or simply use split().

args = {}
for arg in shlex.split(cmdln_args):
    key, value = arg.split('=', 1)
    args[key] = value
ironfroggy
In python 2.5 and above, you can also do: key, _, value= arg.partition('=')
ΤΖΩΤΖΙΟΥ
args = dict(arg.split('=', 1) for arg in shlex.split(cmdln_args))
J.F. Sebastian
+2  A: 

A small pythonic variation on Ironforggy's shlex answer:

args = dict( arg.split('=', 1) for arg in shlex.split(cmdln_args) )

oops... - corrected.

thanks, J.F. Sebastian (got to remember those single argument generator expressions).

gimel
+6  A: 
  1. Try to follow "Standards for Command Line Interfaces"

  2. Convert your arguments (as Thomas suggested) to OptionParser format.

    parser.parse_args(["--"+p if "=" in p else p for p in sys.argv[1:]])
    

If command-line arguments are not in sys.argv or a similar list but in a string then (as ironfroggy suggested) use shlex.split().

parser.parse_args(["--"+p if "=" in p else p for p in shlex.split(argsline)])
J.F. Sebastian
A: 

What about optmatch (http://www.coderazzi.net/python/optmatch/index.htm)? Is not standard, but takes a different approach to options parsing, and it supports any prefix:

OptionMatcher.setMode(optionPrefix='-')

Luic Pend
A: 

Little late to the party... but PEP 389 allows for this and much more.

Here's a little nice library should your version of Python need it code.google.com/p/argparse

Enjoy.

James