parser for command line options this module helps scripts to parse the command line arguments in sys argv it supports the same conventions as the unix getopt function including the special meanings of arguments of the form and long options similar to those supported by gnu software may be used as well via an optional third argument this module provides two functions and an exception getopt parse command line options gnugetopt like getopt but allow option and nonoption arguments to be intermixed getopterror exception class raised with opt attribute which is the option involved with the exception long option support added by lars wirzenius liwiki fi gerrit holl gerritnl linux org moved the stringbased exceptions to classbased exceptions peter strand astrandlysator liu se added gnugetopt todo for gnugetopt gnu getoptlongonly mechanism allow the caller to specify ordering returninorder option gnu extension with as first character of option string optional arguments specified by double colons an option string with a w followed by semicolon should treat w foo as foo bootstrapping python gettext s dependencies not built yet getoptargs options longoptions opts args parses command line options and parameter list args is the argument list to be parsed without the leading reference to the running program typically this means sys argv1 shortopts is the string of option letters that the script wants to recognize with options that require an argument followed by a colon i e the same format that unix getopt uses if specified longopts is a list of strings with the names of the long options which should be supported the leading characters should not be included in the option name options which require an argument should be followed by an equal sign the return value consists of two elements the first is a list of option value pairs the second is the list of program arguments left after the option list was stripped this is a trailing slice of the first argument each optionandvalue pair returned has the option as its first element prefixed with a hyphen e g x and the option argument as its second element or an empty string if the option has no argument the options occur in the list in the same order in which they were found thus allowing multiple occurrences long and short options may be mixed getoptargs options longoptions opts args this function works like getopt except that gnu style scanning mode is used by default this means that option and nonoption arguments may be intermixed the getopt function stops processing options as soon as a nonoption argument is encountered if the first character of the option string is or if the environment variable posixlycorrect is set then option processing stops as soon as a nonoption argument is encountered allow options after nonoption arguments return hasarg full option name is there an exact match no exact match so better be unique xxx since possibilities contains all valid continuations might be nice to work them into the error msg long option support added by lars wirzenius liw iki fi gerrit holl gerrit nl linux org moved the string based exceptions to class based exceptions peter åstrand astrand lysator liu se added gnu_getopt todo for gnu_getopt gnu getopt_long_only mechanism allow the caller to specify ordering return_in_order option gnu extension with as first character of option string optional arguments specified by double colons an option string with a w followed by semicolon should treat w foo as foo bootstrapping python gettext s dependencies not built yet backward compatibility getopt args options long_options opts args parses command line options and parameter list args is the argument list to be parsed without the leading reference to the running program typically this means sys argv 1 shortopts is the string of option letters that the script wants to recognize with options that require an argument followed by a colon i e the same format that unix getopt uses if specified longopts is a list of strings with the names of the long options which should be supported the leading characters should not be included in the option name options which require an argument should be followed by an equal sign the return value consists of two elements the first is a list of option value pairs the second is the list of program arguments left after the option list was stripped this is a trailing slice of the first argument each option and value pair returned has the option as its first element prefixed with a hyphen e g x and the option argument as its second element or an empty string if the option has no argument the options occur in the list in the same order in which they were found thus allowing multiple occurrences long and short options may be mixed getopt args options long_options opts args this function works like getopt except that gnu style scanning mode is used by default this means that option and non option arguments may be intermixed the getopt function stops processing options as soon as a non option argument is encountered if the first character of the option string is or if the environment variable posixly_correct is set then option processing stops as soon as a non option argument is encountered allow options after non option arguments return has_arg full option name is there an exact match no exact match so better be unique xxx since possibilities contains all valid continuations might be nice to work them into the error msg
__all__ = ["GetoptError","error","getopt","gnu_getopt"]

import os
try:
    from gettext import gettext as _
except ImportError:
    
    def _(s): return s

class GetoptError(Exception):
    opt = ''
    msg = ''
    def __init__(self, msg, opt=''):
        self.msg = msg
        self.opt = opt
        Exception.__init__(self, msg, opt)

    def __str__(self):
        return self.msg

error = GetoptError 

def getopt(args, shortopts, longopts = []):
    

    opts = []
    if isinstance(longopts, str):
        longopts = [longopts]
    else:
        longopts = list(longopts)
    while args and args[0].startswith('-') and args[0] != '-':
        if args[0] == '--':
            args = args[1:]
            break
        if args[0].startswith('--'):
            opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
        else:
            opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])

    return opts, args

def gnu_getopt(args, shortopts, longopts = []):
    

    opts = []
    prog_args = []
    if isinstance(longopts, str):
        longopts = [longopts]
    else:
        longopts = list(longopts)

    
    if shortopts.startswith('+'):
        shortopts = shortopts[1:]
        all_options_first = True
    elif os.environ.get("POSIXLY_CORRECT"):
        all_options_first = True
    else:
        all_options_first = False

    while args:
        if args[0] == '--':
            prog_args += args[1:]
            break

        if args[0][:2] == '--':
            opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
        elif args[0][:1] == '-' and args[0] != '-':
            opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
        else:
            if all_options_first:
                prog_args += args
                break
            else:
                prog_args.append(args[0])
                args = args[1:]

    return opts, prog_args

def do_longs(opts, opt, longopts, args):
    try:
        i = opt.index('=')
    except ValueError:
        optarg = None
    else:
        opt, optarg = opt[:i], opt[i+1:]

    has_arg, opt = long_has_args(opt, longopts)
    if has_arg:
        if optarg is None:
            if not args:
                raise GetoptError(_('option --%s requires argument') % opt, opt)
            optarg, args = args[0], args[1:]
    elif optarg is not None:
        raise GetoptError(_('option --%s must not have an argument') % opt, opt)
    opts.append(('--' + opt, optarg or ''))
    return opts, args


def long_has_args(opt, longopts):
    possibilities = [o for o in longopts if o.startswith(opt)]
    if not possibilities:
        raise GetoptError(_('option --%s not recognized') % opt, opt)
    
    if opt in possibilities:
        return False, opt
    elif opt + '=' in possibilities:
        return True, opt
    
    if len(possibilities) > 1:
        
        raise GetoptError(_('option --%s not a unique prefix') % opt, opt)
    assert len(possibilities) == 1
    unique_match = possibilities[0]
    has_arg = unique_match.endswith('=')
    if has_arg:
        unique_match = unique_match[:-1]
    return has_arg, unique_match

def do_shorts(opts, optstring, shortopts, args):
    while optstring != '':
        opt, optstring = optstring[0], optstring[1:]
        if short_has_arg(opt, shortopts):
            if optstring == '':
                if not args:
                    raise GetoptError(_('option -%s requires argument') % opt,
                                      opt)
                optstring, args = args[0], args[1:]
            optarg, optstring = optstring, ''
        else:
            optarg = ''
        opts.append(('-' + opt, optarg))
    return opts, args

def short_has_arg(opt, shortopts):
    for i in range(len(shortopts)):
        if opt == shortopts[i] != ':':
            return shortopts.startswith(':', i+1)
    raise GetoptError(_('option -%s not recognized') % opt, opt)

if __name__ == '__main__':
    import sys
    print(getopt(sys.argv[1:], "a:b", ["alpha=", "beta"]))