Two Machines, One Recursion Limit

This DFS runs over a 200,000-node path graph. Both machines are 64-bit with an 8 MiB thread stack, and the input is identical.

import sys
sys.setrecursionlimit(300000)

def dfs(u):
    seen[u] = True
    for v in adj[u]:
        if not seen[v]:
            dfs(v)

On CPython 3.10 the process dies with a segmentation fault. On CPython 3.13 it finishes. What accounts for the difference?

A

On 3.13 setrecursionlimit also raises RLIMIT_STACK to fit the requested depth; on 3.10 it moved the interpreter counter alone.

B

Before 3.11 every Python call re-entered a C evaluation function, so pure Python recursion was capped by the C stack. From 3.11 the interpreter sets up the new frame and jumps to it inside its own loop, so a Python-to-Python call consumes no C stack and the depth is bounded only by the counter setrecursionlimit moves.

C

3.13 raised the default recursion limit above 200,000, so the setrecursionlimit call is what causes the crash on 3.10 and is redundant on 3.13.

D

3.13 sees that dfs calls only itself and rewrites the recursion as a loop, so no frames accumulate.