Why does this Python script create an infinite loop? (recursion)

python, recursion, stack-overflow

Solution

If you change the code to

i = 0
def foo ():
    global i
    i += 1
    print i
    try :
        foo()
    except RuntimeError :
        # This call recursively goes off toward infinity, apparently.
        foo()
    finally:
        i -= 1
        print i

foo()

You'll observe that the output oscillates short below 999 (1000 being Python's default recursion limit). That means, when the limit is hit (`RuntimeError`) that last call of `foo()` is terminated, and another one is set off to replace it immediately.

If you raise a `KeyboardInterrupt` you'll observe how the entire trace is being terminated at once.

UPDATE

Interestingly the second call of `foo()` is not protected by the `try ... except`-block anymore. Therefore the application will in fact terminate eventually. This becomes apparant if you set the recursion limit to a smaller number, e.g. the output for `sys.setrecursionlimit(3)`:

$ python test.py
1
2
1
2
1
0
Traceback (most recent call last):
  File "test.py", line 19, in <module>
    foo()
  File "test.py", line 14, in foo
    foo()
  File "test.py", line 14, in foo
    foo()
RuntimeError

Problem

Why/how does this create a seemingly infinite loop? Incorrectly, I assumed this would cause some form of a stack overflow type error. ``` i = 0 def foo () : global i i += 1 try : foo() except RuntimeError : # This call recursively goes off toward infinity, apparently. foo() foo() print i ```

Original source