Last active
March 21, 2019 04:32
-
-
Save benkehoe/2e6a08b385e3385f8a54805c99914c75 to your computer and use it in GitHub Desktop.
Simple pattern for adding a REPL to argparse-based command line programs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This came up when I couldn't add dependencies beyond the stdlib for a certain script | |
import argparse | |
import sys, os.path | |
def run(args): | |
# Do actual things | |
pass | |
def main(): | |
parser = argparse.ArgumentParser() | |
# All the args | |
parser.add_argument("--interactive", action="store_true", help="Interactive mode") | |
args = parser.parse_args() | |
if not args.interactive: | |
run(args) | |
return | |
# --Interactive mode-- | |
# First, keep ArgParser from exiting on invalid input | |
class InvalidArgs(Exception): | |
pass | |
def exit(*args, **kwargs): | |
raise InvalidArgs | |
parser.exit = exit | |
# readline adds capabilities to input | |
try: | |
import readline | |
except: | |
pass | |
print("Enter commands. Use 'help' for info, 'exit' to leave.") | |
while True: | |
try: | |
command = input('> ').strip() | |
# remove the program name if they typed it | |
prog_name = os.path.basename(sys.argv[0]) | |
command = re.sub(r'^{}\s+'.format(prog_name), '', command) | |
except KeyboardInterrupt: | |
# Ctrl-c clears the input | |
sys.stdout.write('\n') | |
continue | |
except EOFError: | |
# Ctrl-d exits | |
sys.stdout.write('\n') | |
break | |
if command == 'exit': | |
break | |
if command in ['help', 'h', '?']: | |
parser.print_help() | |
continue | |
try: | |
command_args = parser.parse_args(args=command.split()) | |
except InvalidArgs: | |
print('Invalid command') | |
continue | |
if command_args.interactive: | |
# Don't let them get clever | |
continue | |
run(command_args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment