Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Script that can’t be stopped
-
Hey so I got pythonista recently and so far I am LOVING it very much! However when working with try, except I found something odd. If you have a loop that runs forever in a try block and try to end the program, before the thread ends it runs the except block. Using this oversight you can make a script that will never end! (or until you reopen pythonista)
def dont_stop_me_now(): try: while True: print('oof') except: dont_stop_me_now() dont_stop_me_now()
I found this quite entertaining but thought it is more of a bug than a feature so here it is lol
-
This is a "feature" in Python and is indeed the expected behavior (though it's not exactly helpful). Stopping a script in Pythonista does the same thing as pressing Ctrl+C when you run Python in a terminal: it raises a
KeyboardInterrupt
exception. Normally that causes the script to cleanly stop, while still running all exception handlers. Of course that doesn't help if you catch theKeyboardInterrupt
exception, which you are doing indirectly here with the unrestrictedexcept
block. As you found out, you can still stop your script by terminating the app though.If you have a real script where you want to catch exceptions but not prevent stopping the script, you should add the exception type you want to catch to the
except
block, for exampleexcept ValueError
. If you want to catch all "normal" exceptions, useexcept Exception
rather thanexcept
- the latter catches literally everything, whereas the former lets some "special" exceptions through (likeKeyboardInterrupt
).By the way, the code that you posted can actually be stopped, you just need to press the stop button roughly 1000 times. At some point you'll hit Python's default recursion limit, because every time you catch the exception, you call
dont_stop_me_now
recursively. -
Each time the "dont_stop_me_now" function is called, the return address is saved on the call stack; so that if the function ever did return, it would return to the caller. So, if you were to try to stop the program enough times, eventually it would run out of stack memory. This would take a very, very, long time though.
I'm not sure what Pythonista will do if it runs out of internal stack memory. I expect it would abort the program, but that's just a guess. Actually, all of that is a guess - but Python has to have a call stack, or it couldn't support recursion.
-
@technoway Python actually has a built-in limit on how deep the Python call stack can go. You can get the current limit with
sys.getrecursionlimit()
and change it withsys.setrecursionlimit(limit)
. The default limit is 1000, which is normally enough that you don't overflow the native stack even if you hit the Python recursion limit. In Pythonista that seems to be too much though, if I run an infinitely recursing function with the default limit, Pythonista crashes. With a lower limit (such as 500) I get a PythonRecursionError
as expected. I have no idea what the size of the native stack is on iOS, but it's probably lower than on Mac.