6

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()?

14
  • 1
    Perhaps printing the message of the exception could give you a clue. Commented Dec 23, 2013 at 9:15
  • works as expected for me Commented Dec 23, 2013 at 9:15
  • And you could just use sys.getrecursionlimit() to get the same information. :-) Commented Dec 23, 2013 at 9:17
  • @MartijnPieters reproduced with 2.7 Commented Dec 23, 2013 at 9:18
  • 1
    Ah, AH! exit() is not sys.exit. It is the exit() callable set by the site module. Commented Dec 23, 2013 at 9:20

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

Comments

4

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.