Skip to content

Instantly share code, notes, and snippets.

@benkehoe
Last active March 21, 2019 04:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benkehoe/2e6a08b385e3385f8a54805c99914c75 to your computer and use it in GitHub Desktop.
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 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