From: Kyle Bowman Date: Sun, 14 Apr 2024 22:17:01 +0000 (-0400) Subject: Stashing temporary work. X-Git-Url: https://git.rocketbowman.com/?a=commitdiff_plain;h=630c52c0284877cb5907269dd5085175f592c16a;p=proto.git Stashing temporary work. --- diff --git a/src/proto/command.py b/src/proto/command.py index 0c80c7d..ac97392 100644 --- a/src/proto/command.py +++ b/src/proto/command.py @@ -1,4 +1,4 @@ -from argparse import ArgumentError +from argparse import ArgumentError, ArgumentParser from collections.abc import Callable from functools import partial from typing import Optional @@ -45,6 +45,20 @@ class Command: args = args if args else self.args kwargs = kwargs if kwargs else self.kwargs return self._run(*args, **kwargs) + +class MainCli(ArgumentParser): + + def __init__(self): + super().__init__() + self.subparsers=self.add_subparsers() + pass + + def register_command(self, cmd: Command): + cmd_subparser = self.subparsers.add_parser(cmd.name) + _ = get_parser(cmd._run, cmd_subparser) + + def dispatch(self): + pass def command(fn: Callable): """ Defines a decorator that is used to turn a function into a Command. """ diff --git a/src/proto/infer.py b/src/proto/infer.py index 98ff1be..0603f1e 100644 --- a/src/proto/infer.py +++ b/src/proto/infer.py @@ -1,9 +1,9 @@ -import argparse +from argparse import ArgumentParser from collections.abc import Callable from functools import singledispatch import inspect from pathlib import Path -from typing import Union +from typing import Union, Optional def get_defaults(fn: Callable)->tuple[list, dict]: @@ -72,10 +72,11 @@ class _ArgSpec(dict): else: raise TypeError(f"Cannot instantiate. Check the type of {prm.annotation}") -def get_parser(fn: Callable)->argparse.ArgumentParser: - """ Returns an argparse.ArgumentParser based on the function's signature. """ +def get_parser(fn: Callable, parser: Optional[ArgumentParser]=None)->ArgumentParser: + """ Returns an ArgumentParser based on the function's signature. """ sig = inspect.signature(fn) - parser = argparse.ArgumentParser() + if parser is None: + parser = ArgumentParser() for prm in sig.parameters.values(): # ASSUME: It's a Pythonic standard to use self, but it's convention, not rule. Beware. if prm.name == "self" or prm.name == "cls": diff --git a/tests/scratch.py b/tests/scratch.py new file mode 100644 index 0000000..617a668 --- /dev/null +++ b/tests/scratch.py @@ -0,0 +1,54 @@ +import argparse + +from proto import command, get_parser +from test_command import echo_fn + +@command +#def echo(arg: Stringable)->str: +def echo(arg: str)->str: + return echo_fn(arg) + + +if __name__ == "__main__": + # TODO: Standardize on "commands", not "parsers" for Main CLI interface + # Main CLI Ideas: + # cli = MainCli() + + # (Defer import work - for now, focus on commands in same module) + # cli = MainCli(register_commands=['module.command']) + # cli = MainCli(register_commands_from=['module1', 'module2']) + + # cli.register_subparser(cmd) # preferred, but disallows cli as an ArgumentParser + # The following have side effects: + # Command.register(cli) + # @command(parser=cli) or cmd = command(fn, parser=cli) + # _ = register_command(cli, command) # you can use this for Argparser (maybe create a method alias too) + + # cli.dispatch() # dispatch = parse + run + # cli.dispatch(args=shlex.join("command line")) + + # Start: Register_command(cli, command) - abstract subparser nonsense + # cli=argparse.ArgumentParser() + # subparsers = cli.add_subparsers() + # echo_subparser = subparsers.add_parser(echo.name) + from proto.command import MainCli + cli=MainCli() + cli.register_command(echo) + + # NOTE: Uses echo._run to Command.__call__ which has a different sig. + # TODO: Do I want to add the parser argument? + # If parser is not None, it has side effects... + # +# _ = get_parser(echo._run, parser=echo_subparser) + args = cli.parse_args() + # End: register_command() + print(echo(**vars(args))) + + # NOTE: This is the single-command preference + #echo.parse() + #print(echo.run()) + + # NOTE: This works for kw-only signatures + #cli = echo.parser + #args = cli.parse_args() + #print(echo(**vars(args)))