Skip to content

Recursion limitation in Python 3.13 #114413

Open

Description

@serhiy-storchaka

Bug report

Every recursive call of Python function increases the recursion_depth counter. Some recursive calls of C functions also increase it. A RecursionError is raised when it exceed the limit (sys.getrecursionlimit()).

The following code expectedly prints a value close to 1/2 of sys.getrecursionlimit() in all Python versions before 3.7 (including 2.7):

def test(n):
    if n > 0:
        a = []
        a.extend(test(n-1) for _ in [1])

for i in range(1000):
    try:
        test(i)
    except RecursionError:
        print(i)
        break

One for every test() function call and one for every generator expression. Both are shown in a traceback.

In Python 3.7 to 3.11 it prints 1/3 of the limit. Perhaps it adds one level for every list.extend() call?

In Python 3.12 it returns to 1/2 of the limit.

But in the main branch it only prints 1/6 of the limit. How can it increase the recursion_depth counter 6 times per the recursion level? It is a regression, because now the code that was successfully passed in previous versions starts to raise a RecursionError. See #111803 for example.

Activity

  1. serhiy-storchaka commented on Jan 22, 2024

    @serhiy-storchaka
    MemberAuthor

    Other example that involves only one Python (generator) function call per recursion level:

    def test(n):
        if n > 0:
            a = []
            a.extend(test(n-1))
            yield
    
    for i in range(1000):
        try:
            list(test(i))
        except RecursionError:
            print(i)
            break

    It prints the whole limit in Python before 3.7, 1/2 of the limit in Python 3.7 to 3.12 (no difference between 3.11 and 3.12!), and only 1/6 of the limit in the main branch.

  2. terryjreedy commented on Jan 22, 2024

    @terryjreedy
    Member

    On installed 3.13.0a3, (tags/v3.13.0a3:f009305, Jan 17 2024, 13:25:20), I get 513: IDLE, Win10, rc=1000. With debug no-gil build, (heads/main-dirty:b04c5005cc, Jan 21 2024, 02:00:08), I get 165 (rc same). Recompile plain build.bat, 513 again. Recompile with -d, back to 165.

  3. brettcannon commented on Jan 22, 2024

    @brettcannon
    Member

    Under a debug build of WASI w/ a modification to print before calling list(test(i)), I got to 58 on main and then the call stack was exhausted (i.e. the WASI host killed the run before RecursionError was reached). A non-debug build gets to 167 and doesn't crash. 3.12 non-debug is 165. For a non-debug build of 3.11 it's 198.

  4. added a commit that references this issue on Jan 23, 2024
  5. added a commit that references this issue on Feb 11, 2024
  6. added a commit that references this issue on Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13only security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions