Why does Python have a limit on the number of static blocks that can be nested?

The number of statically nested blocks in Python is limited to 20. That is, nested 19 for loops will be good (albeit excessively time consuming, O(n^19) crazy), but nesting 20 will fail:

 SyntaxError: too many statically nested blocks 

What is the reason for this restriction? Is there a way to increase the limit?

+54
python nested-loops language-implementation
Jul 07 '17 at 14:00
source share
3 answers

This limit applies not only to for loops, but to all other blocks of the control flow. The limit for the number of blocks of nested control blocks is defined inside code.h with a constant named CO_MAXBLOCKS :

 #define CO_MAXBLOCKS 20 /* Max static block nesting within a function */ 

This constant is used to set the maximum size for the stack. Using Python to execute exceptions and loops called blockstack . This restriction is imposed on all frame objects and is shown in frameobject.h :

 int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */ 

The most likely reason for this limitation is to keep the memory at a normal level when executing nested blocks. This probably looks like the limit Python imposes on recursive calls . This limit can be seen in compile.c :

 if (c->u->u_nfblocks >= CO_MAXBLOCKS) { PyErr_SetString(PyExc_SyntaxError, "too many statically nested blocks"); return 0; } 

A more specific answer about why Python has this specfic limit and why it cannot get rid of it was provided by Michael Hudson on the 2004 Python mailing list :

Spot included. This is due to the "blockstack", a very internal detail for the Python implementation. We would like to get rid of it (not because we want people to write code with more than 20 nested for the loop :-), but this is not particularly easy (finally: blocks are the biggest problem).

Note that in Python 2.6 and below, breaking the maximum number of nested loops will cause a SystemError not a SyntaxError . This was changed, however, in Python 3 and fixed before Python 2.7, so a SyntaxError will be created SyntaxError . This has been described in # issue 27514 :

Problem # 27514: Making too many statically nested blocks with syntax instead of SystemError.

The reason for this change in exception types was given by Serhiy Storchaka :

[...] SystemError is not an exception that should be thrown. SystemError - these are errors that cannot be performed in the usual case. This should be caused by misuse of the C API or hacking of Python internal components. I think SyntaxError is more suitable in this case [...].

+67
Jul 07 '17 at 2:31 on
source share

This is due to blockstack , which is a stack of blockstack addresses and is used to execute blocks of code such as loops and exceptions.

It so happened that the version of C (older than C99) set this limit to 20 , and since the CPython interpreter was built with C, the same convention was observed :

 #define CO_MAXBLOCKS 20 /* Max static block nesting within a function */ 

The constant 20 , apparently, is fixed, and nothing more.

[Links courtesy of Christian Dean.]




Why is the limit of 20?

If the convention argument is not convincing, look at Zen of Python:

 In [4]: import this The Zen of Python, by Tim Peters ... Flat is better than nested. ... 



How can you increase this value?

Since this value is a hard-coded constant, the only way to change it in your programs is to rebuild your python distribution and run the script in a new assembly.

  • Download cpython source code from github

  • Go to cpython/Include/code.h

  • Change the value of CO_MAXBLOCKS to greater than 20

  • Recompile Python (disable tests, they will complain )

+20
Jul 07 '17 at 14:15
source share

See the answer here: there are too many statically nested python blocks. You cannot increase it because it is built into the python syntax. The limit applies to any stack of code (exceptions, loops, etc.) and is the decision of the developers (presumably to make judicious use of memory). One thing is strange here: https://github.com/python/cpython/blob/6f0eb93183519024cb360162bdd81b9faec97ba6/Include/code.h#L95 says that 20 is the maximum number in a function. But I just tried nesting 23 for loops, not inside the function, and you still get the error.

+2
Jul 07 '17 at 14:11
source share



All Articles