argshell.argshell
1import argparse 2import cmd 3import shlex 4import sys 5from functools import wraps 6from typing import Any, Callable 7 8 9class Namespace(argparse.Namespace): 10 """Wrapping argparse.Namesapce for convenience.""" 11 12 13class ArgShellParser(argparse.ArgumentParser): 14 """Wrapping argparse.ArgumentParser for convenience 15 and to prevent exit on '-h/--help' switch.""" 16 17 def exit(self, status=0, message=None): 18 """Override to prevent shell exit when passing -h/--help switches.""" 19 if message: 20 self._print_message(message, sys.stderr) 21 22 def parse_args(self, *args, **kwargs) -> Namespace: 23 """Just making the type checker hush.""" 24 return super().parse_args(*args, **kwargs) 25 26 27class ArgShell(cmd.Cmd): 28 intro = "Entering argshell..." 29 prompt = "argshell>" 30 31 def do_quit(self, command: str): 32 """Quit shell""" 33 return True 34 35 36def with_parser( 37 parser: Callable[..., ArgShellParser], 38 post_parsers: list[Callable[[Namespace], Namespace]] = [], 39) -> Callable[[Callable[[Any, Namespace], Any]], Callable[[Any, str], Any]]: 40 """Decorate a 'do_*' function in an argshell.ArgShell class with this function to pass an argshell.Namespace object to the decorated function instead of a string. 41 42 :param parser: A function that creates an argshell.ArgShellParser instance, adds arguments to it, and returns the parser. 43 44 :param post_parsers: An optional list of functions to execute where each function takes an argshell.Namespace instance and returns an argshell.Namespace instance. 45 Functions are executed in the order they are supplied. 46 47 >>> def get_parser() -> argshell.ArgShellParser: 48 >>> parser = argshell.ArgShellParser() 49 >>> parser.add_argument("names", type=str, nargs="*", help="A list of first and last names to print.") 50 >>> parser.add_argument("-i", "--initials", action="store_true", help="Print the initials instead of the full name.") 51 >>> return parser 52 >>> 53 >>> # Convert list of first and last names to a list of tuples 54 >>> def names_list_to_tuples(args: argshell.Namespace) -> argshell.Namespace: 55 >>> args.names = [(first, last) for first, last in zip(args.names[::2], args.names[1::2])] 56 >>> if args.initials: 57 >>> args.names = [(name[0][0], name[1][0]) for name in args.names] 58 >>> return args 59 >>> 60 >>> def capitalize_names(args: argshell.Namespace) -> argshell.Namespace: 61 >>> args.names = [name.capitalize() for name in args.names] 62 >>> return args 63 >>> 64 >>> class NameShell(ArgShell): 65 >>> intro = "Entering nameshell..." 66 >>> prompt = "nameshell>" 67 >>> 68 >>> @with_parser(get_parser, [capitalize_names, names_list_to_tuples]) 69 >>> def do_printnames(self, args: argshell.Namespace): 70 >>> print(*[f"{name[0]} {name[1]}" for name in args.names], sep="\\n") 71 >>> 72 >>> NameShell().cmdloop() 73 >>> Entering nameshell... 74 >>> nameshell>printnames karl marx fred hampton emma goldman angela davis nestor makhno 75 >>> Karl Marx 76 >>> Fred Hampton 77 >>> Emma Goldman 78 >>> Angela Davis 79 >>> Nestor Makhno 80 >>> nameshell>printnames karl marx fred hampton emma goldman angela davis nestor makhno -i 81 >>> K M 82 >>> F H 83 >>> E G 84 >>> A D 85 >>> N M""" 86 87 def decorator( 88 func: Callable[[Any, Namespace], Any | None] 89 ) -> Callable[[Any, str], Any]: 90 @wraps(func) 91 def inner(self: Any, command: str) -> Any: 92 args = parser().parse_args(shlex.split(command)) 93 for post_parser in post_parsers: 94 args = post_parser(args) 95 return func(self, args) 96 97 return inner 98 99 return decorator
Wrapping argparse.Namesapce for convenience.
Inherited Members
- argparse.Namespace
- Namespace
14class ArgShellParser(argparse.ArgumentParser): 15 """Wrapping argparse.ArgumentParser for convenience 16 and to prevent exit on '-h/--help' switch.""" 17 18 def exit(self, status=0, message=None): 19 """Override to prevent shell exit when passing -h/--help switches.""" 20 if message: 21 self._print_message(message, sys.stderr) 22 23 def parse_args(self, *args, **kwargs) -> Namespace: 24 """Just making the type checker hush.""" 25 return super().parse_args(*args, **kwargs)
Wrapping argparse.ArgumentParser for convenience and to prevent exit on '-h/--help' switch.
18 def exit(self, status=0, message=None): 19 """Override to prevent shell exit when passing -h/--help switches.""" 20 if message: 21 self._print_message(message, sys.stderr)
Override to prevent shell exit when passing -h/--help switches.
23 def parse_args(self, *args, **kwargs) -> Namespace: 24 """Just making the type checker hush.""" 25 return super().parse_args(*args, **kwargs)
Just making the type checker hush.
Inherited Members
- argparse.ArgumentParser
- ArgumentParser
- add_subparsers
- parse_known_args
- convert_arg_line_to_args
- parse_intermixed_args
- parse_known_intermixed_args
- format_usage
- format_help
- print_usage
- print_help
- error
- argparse._ActionsContainer
- register
- set_defaults
- get_default
- add_argument
- add_argument_group
- add_mutually_exclusive_group
28class ArgShell(cmd.Cmd): 29 intro = "Entering argshell..." 30 prompt = "argshell>" 31 32 def do_quit(self, command: str): 33 """Quit shell""" 34 return True
A simple framework for writing line-oriented command interpreters.
These are often useful for test harnesses, administrative tools, and prototypes that will later be wrapped in a more sophisticated interface.
A Cmd instance or subclass instance is a line-oriented interpreter framework. There is no good reason to instantiate Cmd itself; rather, it's useful as a superclass of an interpreter class you define yourself in order to inherit Cmd's methods and encapsulate action methods.
Inherited Members
- cmd.Cmd
- Cmd
- cmdloop
- precmd
- postcmd
- preloop
- postloop
- parseline
- onecmd
- emptyline
- default
- completedefault
- completenames
- complete
- get_names
- complete_help
- do_help
- print_topics
- columnize
37def with_parser( 38 parser: Callable[..., ArgShellParser], 39 post_parsers: list[Callable[[Namespace], Namespace]] = [], 40) -> Callable[[Callable[[Any, Namespace], Any]], Callable[[Any, str], Any]]: 41 """Decorate a 'do_*' function in an argshell.ArgShell class with this function to pass an argshell.Namespace object to the decorated function instead of a string. 42 43 :param parser: A function that creates an argshell.ArgShellParser instance, adds arguments to it, and returns the parser. 44 45 :param post_parsers: An optional list of functions to execute where each function takes an argshell.Namespace instance and returns an argshell.Namespace instance. 46 Functions are executed in the order they are supplied. 47 48 >>> def get_parser() -> argshell.ArgShellParser: 49 >>> parser = argshell.ArgShellParser() 50 >>> parser.add_argument("names", type=str, nargs="*", help="A list of first and last names to print.") 51 >>> parser.add_argument("-i", "--initials", action="store_true", help="Print the initials instead of the full name.") 52 >>> return parser 53 >>> 54 >>> # Convert list of first and last names to a list of tuples 55 >>> def names_list_to_tuples(args: argshell.Namespace) -> argshell.Namespace: 56 >>> args.names = [(first, last) for first, last in zip(args.names[::2], args.names[1::2])] 57 >>> if args.initials: 58 >>> args.names = [(name[0][0], name[1][0]) for name in args.names] 59 >>> return args 60 >>> 61 >>> def capitalize_names(args: argshell.Namespace) -> argshell.Namespace: 62 >>> args.names = [name.capitalize() for name in args.names] 63 >>> return args 64 >>> 65 >>> class NameShell(ArgShell): 66 >>> intro = "Entering nameshell..." 67 >>> prompt = "nameshell>" 68 >>> 69 >>> @with_parser(get_parser, [capitalize_names, names_list_to_tuples]) 70 >>> def do_printnames(self, args: argshell.Namespace): 71 >>> print(*[f"{name[0]} {name[1]}" for name in args.names], sep="\\n") 72 >>> 73 >>> NameShell().cmdloop() 74 >>> Entering nameshell... 75 >>> nameshell>printnames karl marx fred hampton emma goldman angela davis nestor makhno 76 >>> Karl Marx 77 >>> Fred Hampton 78 >>> Emma Goldman 79 >>> Angela Davis 80 >>> Nestor Makhno 81 >>> nameshell>printnames karl marx fred hampton emma goldman angela davis nestor makhno -i 82 >>> K M 83 >>> F H 84 >>> E G 85 >>> A D 86 >>> N M""" 87 88 def decorator( 89 func: Callable[[Any, Namespace], Any | None] 90 ) -> Callable[[Any, str], Any]: 91 @wraps(func) 92 def inner(self: Any, command: str) -> Any: 93 args = parser().parse_args(shlex.split(command)) 94 for post_parser in post_parsers: 95 args = post_parser(args) 96 return func(self, args) 97 98 return inner 99 100 return decorator
Decorate a 'do_*' function in an argshell.ArgShell class with this function to pass an argshell.Namespace object to the decorated function instead of a string.
Parameters
parser: A function that creates an argshell.ArgShellParser instance, adds arguments to it, and returns the parser.
post_parsers: An optional list of functions to execute where each function takes an argshell.Namespace instance and returns an argshell.Namespace instance. Functions are executed in the order they are supplied.
>>> def get_parser() -> argshell.ArgShellParser:
>>> parser = argshell.ArgShellParser()
>>> parser.add_argument("names", type=str, nargs="*", help="A list of first and last names to print.")
>>> parser.add_argument("-i", "--initials", action="store_true", help="Print the initials instead of the full name.")
>>> return parser
>>>
>>> # Convert list of first and last names to a list of tuples
>>> def names_list_to_tuples(args: argshell.Namespace) -> argshell.Namespace:
>>> args.names = [(first, last) for first, last in zip(args.names[::2], args.names[1::2])]
>>> if args.initials:
>>> args.names = [(name[0][0], name[1][0]) for name in args.names]
>>> return args
>>>
>>> def capitalize_names(args: argshell.Namespace) -> argshell.Namespace:
>>> args.names = [name.capitalize() for name in args.names]
>>> return args
>>>
>>> class NameShell(ArgShell):
>>> intro = "Entering nameshell..."
>>> prompt = "nameshell>"
>>>
>>> @with_parser(get_parser, [capitalize_names, names_list_to_tuples])
>>> def do_printnames(self, args: argshell.Namespace):
>>> print(*[f"{name[0]} {name[1]}" for name in args.names], sep="\n")
>>>
>>> NameShell().cmdloop()
>>> Entering nameshell...
>>> nameshell>printnames karl marx fred hampton emma goldman angela davis nestor makhno
>>> Karl Marx
>>> Fred Hampton
>>> Emma Goldman
>>> Angela Davis
>>> Nestor Makhno
>>> nameshell>printnames karl marx fred hampton emma goldman angela davis nestor makhno -i
>>> K M
>>> F H
>>> E G
>>> A D
>>> N M