Wednesday, 4 September 2019

Ctrl+C sends EOFError once after cancelling process

I'm making a very basic command line utility using python, and I'm trying to set it up such that the user has the ability to interrupt any running operation during execution with Ctrl+C, and exit the program by sending an EOF with Ctrl+Z. However, I've been fighting with this frustrating issue for the last day where after cancelling a running operation with a KeyboardInterrupt, pressing Ctrl+C a second time sends an EOFError instead of a KeyboardInterrupt, which causes the program to exit. Hitting Ctrl+C subsequent times sends KeyboardInterrupt's as usual, except until I input any command or an empty line, where an additional KeyboardInterrupt is sent instead of the input I give. After doing so, hitting Ctrl+C again will send an EOFError again, and continues from there. Here's a minimal example of code demonstrating my issue;

import time

def parse(inp):
    time.sleep(1)
    print(inp)
    if inp == 'e':
        return 'exit'

while True:
    try:
        user_in = input("> ").strip()
    except (KeyboardInterrupt, Exception) as e:
        print(e.__class__.__name__)
        continue

    if not user_in:
        continue

    try:
        if parse(user_in) == 'exit':
            break
    except KeyboardInterrupt:
        print("Cancelled")

And here's some sample output of my code;

>
>
>
> KeyboardInterrupt
> KeyboardInterrupt
> KeyboardInterrupt
> KeyboardInterrupt
> KeyboardInterrupt
> KeyboardInterrupt
>
>
>
> ^Z
EOFError
> ^Z
EOFError
> ^Z
EOFError
> KeyboardInterrupt
> KeyboardInterrupt
> KeyboardInterrupt
>
>
> ^Z
EOFError
> KeyboardInterrupt
>
>

As you can see, when hitting Ctrl+C, Ctrl+Z, or a blank line, the prompt responds as you would expect with each error appropriately. However, if I run a command and try cancelling it during execution by hitting Ctrl+C;

> test
Cancelled
>
>
>
> EOFError
> KeyboardInterrupt
> KeyboardInterrupt
> KeyboardInterrupt
> KeyboardInterrupt
>
KeyboardInterrupt
>
>
> EOFError
> KeyboardInterrupt
> KeyboardInterrupt
> KeyboardInterrupt
>
KeyboardInterrupt
>
>
>

I only hit Ctrl+C and Enter in the above example; I first hit enter to send several blank lines, then hit Ctrl+C, which sends an EOFError at first. Hitting Ctrl+C mutliple times afterwards then sends KeyboardInterrupt's correctly. Afterwards, sending a blank line instead then sends a KeyboardInterrupt, and subsequent blank lines entered are received normally. This functionality is repeated onward from the program's execution there.

Why is this happening, and how can I fix it?



from Ctrl+C sends EOFError once after cancelling process

No comments:

Post a Comment