I have the following code at the moment:
executed = False
while executed == False:
try:
inp = input("Enter the variable you want to change (e.g.: limit = 10): ")
eval(inp, globals())
except:
print("Invalid input")
continue
print("Variable has been changed")
executed = True
and I don't quite understand why if I put exit()
as an input it goes into an infinite loop outputting the following line over and over again:
Enter the variable you want to change (e.g.: limit = 10): Invalid input
without me further inputting anything.
I am absolutely lost on why it even goes into an infinite loop since I expected it to either completely quit out of it or just print "Invalid input" and then ask me to input something different again. Why does it keep skipping the input() part and directly jumps to the eval part? (Or at least I assume that's what it's doing).
To debug the problem, change the code to following:
from time import sleep
executed = False
while executed is False:
try:
inp = input("Enter the variable you want to change (e.g.: limit = 10): \n")
eval(inp, globals())
except BaseException as e:
print("error is:", e, type(e))
print("Invalid input")
sleep(2)
continue
print("Variable has been changed")
executed = True
Now the following is happening:
exit()
, eval
can correctly execute the command exit()
.SystemExit
exception.except
clause(which is equivalent to except BaseException
), which means you don't let the script to be finished by that SystemExit
exception.input()
, it cannot read from a closed file(stdin).Yes I checked the source code and it indeed closes the stdin.
Here it adds exit
callable to the builtins:
builtins.exit = _sitebuiltins.Quitter('exit', eof)
and this is what gets called when you say `exit():
class Quitter(object):
...
def __call__(self, code=None):
# Shells like IDLE catch the SystemExit, but listen when their
# stdin wrapper is closed.
try:
sys.stdin.close()
except:
pass
raise SystemExit(code)