Reputation: 1291
I was trying to experimentally determine Python's maximum recursion depth with the following code:
def recursive(i):
i = i + 1
try:
recursive(i)
except RuntimeError:
print 'max depth == %d' % i
exit(0)
recursive(0)
But when I ran it, this happened:
[ hive ~ ]$ python recursive.py
max depth == 999
max depth == 998
max depth == 997
max depth == 996
max depth == 995
max depth == 994
Why is my program not exiting right away when it encountered RuntimeError
the first time, but continued to run for 5 more calls to recursive()
?
Upvotes: 6
Views: 539
Reputation: 1123630
You are using the exit()
function the Python site
module sets for use in the interactive interpreter.
This is Python code you are calling, not C code. This triggers the recursion depth exception handler a few more times until you are far enough away from the stack limit.
When you are right up against the limit, trying to call exit()
fails because you hit the stack limit. So a RuntimeError
is raised, falling back a call to 998
. Here you try to call exit()
again, which tries to do some more work raising the RuntimeError
again, falling back another level, etc. until there is enough stack space left to finally call raise SystemExit()
in the python function.
Use sys.exit()
instead to avoid adding more strain to the stack.
Or, for future reference, use the sys.getrecursionlimit()
function to just ask Python directly what the limit is.
Upvotes: 7
Reputation: 48347
Runtime error is catched in recursive(999) try
-except
, but reraised by exit(0)
. Latter is roughly equivalent to raise SystemExit(0)
modulo some additional calls, those calls makes RuntimeError
happen again, see it as following code:
def recursive(i):
try:
i = i + 1
recursive(i)
except RuntimeError as exc:
print 'max depth == %d' % i
try:
exit(0)
except RuntimeError:
print 'RuntimeError in exit'
recursive(0)
outputs
max depth == 999
RuntimeError in exit
So runtime error is catched again within recursive(998) and so on, totaling 5 catches until the moment your stack is unwinded far away to exit(0)
be able not to raise an RuntimeError.
Upvotes: 4