| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 | from inspect import getdocfrom docopt import docoptfrom docopt import DocoptExitdef docopt_full_help(docstring, *args, **kwargs):    try:        return docopt(docstring, *args, **kwargs)    except DocoptExit:        raise SystemExit(docstring)class DocoptDispatcher:    def __init__(self, command_class, options):        self.command_class = command_class        self.options = options    def parse(self, argv):        command_help = getdoc(self.command_class)        options = docopt_full_help(command_help, argv, **self.options)        command = options['COMMAND']        if command is None:            raise SystemExit(command_help)        handler = get_handler(self.command_class, command)        docstring = getdoc(handler)        if docstring is None:            raise NoSuchCommand(command, self)        command_options = docopt_full_help(docstring, options['ARGS'], options_first=True)        return options, handler, command_optionsdef get_handler(command_class, command):    command = command.replace('-', '_')    # we certainly want to have "exec" command, since that's what docker client has    # but in python exec is a keyword    if command == "exec":        command = "exec_command"    if not hasattr(command_class, command):        raise NoSuchCommand(command, command_class)    return getattr(command_class, command)class NoSuchCommand(Exception):    def __init__(self, command, supercommand):        super().__init__("No such command: %s" % command)        self.command = command        self.supercommand = supercommand
 |