简体   繁体   中英

Python maximum recursion not reached

Why is the maximum recursion of sys.getrecursionlimit() [which is 1000 in my case running Ubuntu 18.04] not reached when I run the following program.

import sys

global count

print(f'sys recursion limit is: {sys.getrecursionlimit()}')

count = 0
def foo(x):
    global count
    if x == 1:
        return 1
    else:
        count += 1
        return x + foo(x - 1)

x = 982
print(f'answer of foo({x}) = {foo(x)}, count = {count}')

result with x = 982

sys recursion limit is: 1000
answer of foo(982) = 482653, count = 981

but with x = 983 I get a RecursionError

sys recursion limit is: 1000
Traceback (most recent call last):
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_frame.py", line 562, in trace_dispatch
    cmd = main_debugger.cmd_factory.make_io_message(info.pydev_message + os.linesep, '1')
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_net_command_factory_json.py", line 253, in make_io_message
    return NetCommand(CMD_WRITE_TO_CONSOLE, 0, event, is_json=True)
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_net_command.py", line 57, in __init__
    text = json.dumps(as_dict)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
RecursionError: maximum recursion depth exceeded while encoding a JSON object
Traceback (most recent call last):
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/ptvsd_launcher.py", line 43, in <module>
    main(ptvsdArgs)
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/__main__.py", line 432, in main
    run()
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/__main__.py", line 316, in run_file
    runpy.run_path(target, run_name='__main__')
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/runpy.py", line 263, in run_path
    pkg_name=pkg_name, script_name=fname)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 18, in <module>
    print(f'answer of foo({x}) = {foo(x)}, count = {count}')
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 15, in foo
    return x + foo(x - 1)
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 15, in foo
    return x + foo(x - 1)
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 15, in foo
    return x + foo(x - 1)
  [Previous line repeated 977 more times]
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 14, in foo
    count += 1
  File "/home/bvermeulen/Python/stackoverflow/recursion.py", line 14, in foo
    count += 1
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_frame.py", line 562, in trace_dispatch
    cmd = main_debugger.cmd_factory.make_io_message(info.pydev_message + os.linesep, '1')
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_net_command_factory_json.py", line 253, in make_io_message
    return NetCommand(CMD_WRITE_TO_CONSOLE, 0, event, is_json=True)
  File "/home/bvermeulen/.vscode/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_net_command.py", line 57, in __init__
    text = json.dumps(as_dict)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/home/bvermeulen/.pyenv/versions/3.7.4/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
RecursionError: maximum recursion depth exceeded while encoding a JSON object

If I open a clean file in Pycharm and print out a stack trace using print_stack :

import traceback

traceback.print_stack()

I get:

File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\pydevconsole.py", line 483, in <module>
    pydevconsole.start_client(host, port)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\pydevconsole.py", line 411, in start_client
    process_exec_queue(interpreter)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\pydevconsole.py", line 258, in process_exec_queue
    more = interpreter.add_exec(code_fragment)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\_pydev_bundle\pydev_console_utils.py", line 151, in add_exec
    more = self.do_add_exec(code_fragment)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\pydevconsole.py", line 84, in do_add_exec
    command.run()
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\_pydev_bundle\pydev_console_types.py", line 35, in run
    self.more = self.interpreter.runsource(text, '<input>', symbol)
File "C:\Users\slomi\AppData\Local\Programs\Python\Python37-32\lib\code.py", line 74, in runsource
    self.runcode(code)
File "C:\Users\slomi\AppData\Local\Programs\Python\Python37-32\lib\code.py", line 90, in runcode
    exec(code, self.locals)
File "<input>", line 1, in <module>
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/slomi/PycharmProjects/chat/cr.py", line 3, in <module>
    traceback.print_stack()

So, it seems that depending on your environment, there will be stuff already on the stack before your own code even runs. On my computer in Pycharm, your code actually fails at x = 986 , and in the comments, someone noted that on an online IDE (which presumably has less going on than Pycharm), it failed at x = 999 . It seems it depends on what your IDE has going on in the background before your code is run.

Before calling the method foo there is already other calls in the stack, like

main -> print ->...

There are many functions calls you can see in your stacktrace. If the full stack size (number of calls before enter in foo + number of foo calls) reach your recursion limit so the error will be thrown.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM