[Tutor] Exception not working as expected?

eryk sun eryksun at gmail.com
Thu Feb 28 21:31:00 EST 2019


On 2/28/19, Chip Wachob <wachobc at gmail.com> wrote:
>
> Python 2.7 & Windows and also Linux are the platforms being used.  Running
> the code from the command line / terminal as   python except.py.  Note that
> it does work properly in Linux.  So I'm guessing I need to test for a
> different exception along with the KeyboardInterrupt??

When reading from the console, we depend on a particular error being
set in order to distinguish an interrupted read from end-of-file
(EOF), but this error doesn't get set in Windows 8+ due to a bug in
the Windows API. I created an issue with Microsoft's console team, but
thus far they've ignored it.

Due to this bug, Python 2 code that calls raw_input() or input() also
needs to handle EOFError, which should probably be handled anyway.
However, it's not enough to separately handle KeyboardInterrupt and
EOFError, since the KeyboardInterrupt may get raised while handling
EOFError. This can happen because Windows calls the console control
handler asynchronously in a new thread. We need a bit of a kludge that
checks for a delayed KeyboardInterrupt. For example, the following
shows a case that uses a common handler for EOF and Ctrl+C:

    import os
    import sys
    import time

    def main():
        try:
            os.system('cls' if os.name == 'nt' else 'clear')
            print "\n\n\n\n Welcome to Test.\n"
            time.sleep(DISPLAY_TIME)
            start_menu()
        except (KeyboardInterrupt, EOFError):
            try:
                time.sleep(0.1)
            except KeyboardInterrupt:
                pass
            # provides a clean exit
            print "\n\n Keyboard Interrupt or EOF - Exiting \n\n"
            time.sleep(5)
        print "End of Script\n"
        return 0

    if __name__ == "__main__":
        sys.exit(main())

>     # trap no choice, just Enter key cases
>     except ValueError:
>         # handles non-entry selections like 'Enter'
>         print "Invalid selection please try again"
>         time.sleep(DISPLAY_TIME / 2)
>         start_menu()

ValueError should be handled near the int() conversion that raises it,
and the exception handler should `continue` the loop instead of
recursively calling start_menu().


More information about the Tutor mailing list