Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a function that returns itself max out recursion in python 3

Why does this code give the error: RuntimeError: maximum recursion depth exceeded during compilation? print_test never calls itself, hence I would think it isn't a recursive function.

def print_test():
    print("test")
    return print_test

print_test() #prints 'test'
print()

#a quick way of writing "print_test()()()()()()()()()()()()()..."
eval("print_test"+"()"*10000) #should print 'test' 10000 times

When I tested it, It worked in Python 2.7.7rc1 but gave the error in Python 3.3.5. Pdb give a short call stack, unlike the tall one that normally exists when exceeding maximum recursion depth.

Traceback (most recent call last):
  File "/usr/lib/python3.3/pdb.py", line 1662, in main
    pdb._runscript(mainpyfile)
  File "/usr/lib/python3.3/pdb.py", line 1543, in _runscript
    self.run(statement)
  File "/usr/lib/python3.3/bdb.py", line 405, in run
    exec(cmd, globals, locals)
  File "<string>", line 1, in <module>
  File "/home/beet/overflow.py", line 1, in <module>
    def print_test():

I am wondering this out of curiosity, and realize this would not be best programming practices.

like image 501
Algorithmic Canary Avatar asked Jun 21 '14 04:06

Algorithmic Canary


People also ask

Why does Python have a maximum recursion depth?

Python uses a maximum recursion depth of 1000 to ensure no stack overflow errors and infinite recursions are possible.

How do you stop infinite recursion in Python?

A recursive function is a function that makes a call to itself. To prevent infinite recursion, you need at least one branch (i.e. of an if/else statement) that does not make a recursive call. Branches without recursive calls are called base cases; branches with recursive calls are called recursive cases.

How can you avoid maximum recursion depth exceeded?

The “maximum recursion depth exceeded in comparison” error is raised when you try to execute a function that exceeds Python's built in recursion limit. You can fix this error by rewriting your program to use an iterative approach or by increasing the recursion limit in Python.

How return works Python recursion?

Well, when recursion is involved, nothing changes. The return statement neither knows nor cares whether it's returning from a recursively invoked function, it behaves exactly the same way in either case. In fact, recursion isn't anything "special" at all; it behaves exactly the same way as ordinary function calls.


1 Answers

I believe this has to do with Issue #5765.

Apply a hard recursion limit in the compiler [as of 3.3]

Not 100% sure, but this code runs on 3.2.3:

def f():
    return f

eval("f" + "()" * 10000)

but fails on my 3.4.1 which leaves me to suspect this change caused it. If someone would confirm or deny this that would be pretty cool.

like image 165
Dair Avatar answered Oct 22 '22 13:10

Dair