Skip to content

Instantly share code, notes, and snippets.

@tsibley
Created November 22, 2024 18:21
Show Gist options
  • Save tsibley/5f38fc958f98fcd63e313096548f0acf to your computer and use it in GitHub Desktop.
Save tsibley/5f38fc958f98fcd63e313096548f0acf to your computer and use it in GitHub Desktop.
#!/bin/python3
import argparse
class OverloadAction(argparse.Action):
class OverloadParser(argparse.ArgumentParser):
def exit(self, status = 0, message = None):
raise argparse.ArgumentError(None, message)
def _print_message(self, message, file = None):
pass
class HelpAction(argparse.Action):
def __call__(self, *args, **kwargs):
self.help.print_help()
self.help.exit()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
assert self.nargs == argparse.REMAINDER # XXX FIXME: error better
self._parsers = []
def add_parser(self, **kwargs):
self._parsers.append(_parser := self.OverloadParser(**kwargs, add_help = False))
return _parser
def __call__(self, parser, namespace, values, option_string = None):
unknowns = []
for _parser in self._parsers:
# XXX FIXME: explain
_parser.add_argument("--help", "-h", action = self.HelpAction, help = parser, nargs = 0, dest = argparse.SUPPRESS)
try:
known, unknown = _parser.parse_known_args(values)
except argparse.ArgumentError:
continue
else:
if not unknown:
setattr(namespace, self.dest, known)
return
else:
unknowns.append(unknown)
else:
# XXX FIXME: commentary
if not unknowns:
unknowns.append(values)
# XXX FIXME: show actual usage patterns associated with each unknowns
parser.error("unrecognized arguments for every usage pattern: %s" % ", ".join("[%s]" % " ".join(x) for x in unknowns))
parser = argparse.ArgumentParser(prog='proggy', usage="%(prog)s <xyz>")
overloads = parser.add_argument("xyz", nargs=argparse.REMAINDER, action=OverloadAction, help="TKTK")
x = overloads.add_parser()
x.set_defaults(__which__ = "x")
x.add_argument("letter", choices=["a", "b", "c"])
y = overloads.add_parser()
y.set_defaults(__which__ = "y")
y.add_argument("number", type=int)
print(parser.parse_args())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment