0

I am making a Python 3 app that has a prompt where the user enters commands. I'm running Python 3.5 on macOS Sierra.

I'm trying to prevent exiting with Ctrl+C and having users exit instead by simply typing exit into the prompt.

I am doing this using this method: https://stackoverflow.com/a/6019460/7450368

However, when prompting the user again, I get RuntimeError: can't re-enter readline.

Is there a way I can fix this?

Here's my code:

import interpret
import signal
def SigIntHand(SIG, FRM):
    print("\nUse 'exit' to exit.")
    prompt()

signal.signal(signal.SIGINT, SigIntHand)




version = ("v0.0.3")




class CommandError(Exception):
    pass




def prompt():
    try:
        task = input("Einstein " + version + "  > ")
    except RuntimeError:
        task = input("Einstein " + version + "  > ")
    try:
        execute(task)
    except CommandError as e:
        print(e)
    prompt()


def execute(command):
    command = command.lower()
    interpret.interpret(command)

prompt()

interpret.interpret("command") is called by main.py to execute the command command if it exists.

Any help would be hugely appreciated. Thanks!

Community
  • 1
  • 1
  • What are you expecting to throw the runtime error in the first try-except of `prompt`? – Christopher Apple Apr 13 '17 at 20:30
  • I don't expect anything to cause it, but it happens nonetheless. I just get `RuntimeError: can't re-enter readline`. –  Apr 14 '17 at 13:36
  • The user pressing `Ctrl+C` triggers it, but I'm not sure why. Adding a `try`...`except` allows it to be caught once, but if the user presses `Ctrl+C` again, the same error pops up. –  Apr 14 '17 at 13:38
  • I can't reproduce by replacing `interpret.interpret` with `os.system` which is sort of what I was expecting you to be doing, could you try to post a [MCVE](http://stackoverflow.com/help/mcve)? – Tadhg McDonald-Jensen Apr 14 '17 at 13:54

1 Answers1

0

Your control flow looks a bit strange. To handle the user pressing Ctrl+C more than once, you should use a loop to keep asking for input.

Also, you can catch a KeyboardInterrupt in Python which gets raised every time you hit Ctrl+C. It's a bit easier than messing with signal handlers.

version = ("v0.0.3")

class CommandError(Exception):
    pass

def prompt():
    try:
        return input("Einstein " + version + "  > ")
    except KeyboardInterrupt:
        print('') # Go to the next line so printing looks better.
        return None

def force_prompt():
    task = None
    while task is None:
        task = prompt()
    return task

def get_and_execute_command():
    task = force_prompt()
    try:
        execute(task)
    except CommandError as e:
        print(e)

def execute(command):
    command = command.lower()
    print('Command: %s' % command)

get_and_execute_command()
supersam654
  • 3,126
  • 33
  • 34
  • The reason I don't catch `KeyboardInterrupt` is that (for me at least) it doesn't prevent the user exiting with `Ctrl+C` - I can `print` out 'Exit with 'exit' next time!` but it still exits after that. –  Apr 15 '17 at 06:56