def parse(args, options):
    argmap, defmap, state = {}, {}, {}
    shortlist, namelist, funlist = '', [], []

    for short, name, default, comment in options:
        if not name:
            raise FOError(
                'Long name should be defined for every option')
        # change name to match Python styling
        pyname = name.replace('-', '_').split()[0]
        argmap['-' + short] = argmap['--' + name] = pyname
        defmap[pyname] = default

        # copy defaults to state
        if isinstance(default, list):
            state[pyname] = default[:]
        elif hasattr(default, '__call__'):
            funlist.append(pyname)
            state[pyname] = None
        else:
            state[pyname] = default

        # getopt wants indication that it takes a parameter
        if not (default is None or default is True or default is False):
            if short: short += ':'
            if name: name += '='
        if short:
            shortlist += short
        if name:
            namelist.append(name)

    opts, args = getopt.gnu_getopt(args, shortlist, namelist)

    # transfer result to state
    for opt, val in opts:
        name = argmap[opt]
        t = type(defmap[name])
        if t is types.FunctionType:
            del funlist[funlist.index(name)]
            state[name] = defmap[name](val)
        elif t is types.ListType:
            state[name].append(val)
        elif t in (types.NoneType, types.BooleanType):
            state[name] = not defmap[name]
        else:
            state[name] = t(val)

    for name in funlist:
        state[name] = defmap[name](None)

    return state, args
# --------
# Subcommand system
# --------
Convert IndexDefinitions to set of keys.
dataset/ETHPy150Open kennethreitz-archive/argue/argue/core.py/parse--crossover with--dataset/ETHPy150Open CollabQ/CollabQ/.google_appengine/google/appengine/datastore/datastore_index.py/IndexDefinitionsToKeys