pycom / pycom-micropython-sigfox

A fork of MicroPython with the ESP32 port customized to run on Pycom's IoT multi-network modules.
MIT License
199 stars 167 forks source link

Disable keyboard interrupt does not work ( micropython.kbd_intr(-1) ) #391

Open Cees-Meijer opened 4 years ago

Cees-Meijer commented 4 years ago

Firmware and board details: (sysname='GPy', nodename='GPy', release='1.20.0.rc13', version='v1.9.4-94bb382 on 2019-08-22', machine='GPy with ESP32')

I'm using the following code:

ExitMenu = False
micropython.kbd_intr(-1)
while not ExitMenu:
    In = input(">")
    if In == "Q" or In == "q":
        ExitMenu=True
    print("You typed:",In)

print("I'm Back!")
micropython.kbd_intr(3)

However, when the system is waiting for input and I send \<ctrl>C it still gives me 'KeyboardInterrupt:' and falls back to a '>' prompt. It will not respond to any keypress, except a \<ctrl>B

robert-hh commented 4 years ago

micropython.kbd_intr(-1) works, but it seems that calling input re-enables interrupt with Ctrl-C. You can verify that by using sys.stdin.read(1) instead of input(). Whether this re-enabling is good, may be discussed.

Cees-Meijer commented 4 years ago

Indeed, using sys.stdin.read() works and ignores Ctrl-C. Thanks for clarifying. I'll just write my own 'Input()' function using the sys.stdin as a workaround.

robert-hh commented 4 years ago

The culprit is in modbuiltins.c, lines 246-248. The readline() function uses sys.stdin.read() to get a character, and returns Ctrl-C is pressed, but then modbuildin.c raises the KeybdIntr exception if Ctrl-c is returned. But if you do not need the Ctrl-C as part of your input, you can as well use a try/except KeybdInterrupt clause around the call to input and just catch Ctrl-C there.

import micropython

ExitMenu = False
micropython.kbd_intr(-1)
while not ExitMenu:
    try:
        In = input(">")
    except (KeyboardInterrupt, EOFError):
        In = ""
    if In == "Q" or In == "q":
        ExitMenu=True
    print("You typed:",In)

print("I'm Back!")
micropython.kbd_intr(3)

Catching EOFError to covers Ctrl-D