AsTeR
AsTeR

Reputation: 7521

Python IndentationError: too many levels of indentation

I've a part of my python program which is generated, the generated codes contains a lot of nested if / else, my problem is that a lot can be too much and I got this Error when running my code:

IndentationError: too many levels of indentation

I've read that this was some limitation defined on the low level of the python interpreter, does anybody know how I can find a workaround for it? Some interpreter parameters would be fine, the only solution proposal I've found suggests to recompile Python in order to set a different value for the MAXINDENT constant, which is not exactly what I'm dreaming of.

EDIT : The code is a big bunch of nested if...else , it's dirty but it was the quickest I found to port a complex decision tree to Python. I know how dirty it is; I did not write it myself — I did not even plan to edit it (I would rather touch the generator).

I know I can modelize this decision tree in other fashions. What I would like is a way simpler than that, like tweaking the interpretor if possible.

EDIT 2 : Now I've done some refactoring, and my tree is stored as a dictionary: The loading of the file gives a new error :

s_push: parser stack overflow
MemoryError

Here again I found a resource suggesting some tweaks of the interpreter's headers.


Upvotes: 9

Views: 3315

Answers (3)

jsbueno
jsbueno

Reputation: 110311

As for @warvariuc answer, the best thing to do would be to split your if-else sequences into several functions - one function for each "if-elif-else" sequence, with an authomated generated name.

Python will have to parse all functions in order for it to be able to call then in an arbitrary order, so the outermost "if-else" pair also has to be put in a function, which would be called at the end of the file.

In other words, the generated code you have now, that looks like this:

if bla:
    if ble:
        #bla
    else:
        #bli
elif ble:
    #bli

should be generated to look like this instead:

def main(state):
    if bla:
        main_1(state)
    elif ble:
        #bli

def main_1(state):
    if ble:
        #bla
    else:
        #bli

main()

Upvotes: 1

jfs
jfs

Reputation: 414345

You can have deeply nested structures that are generated dynamically e.g., ~100 nested-levels list leads to s_push: parser stack overflow as a string literal but it works if you create it dynamically from json-text, example:

import ast
import json

N = 100
s = "["*N + "123" +"]"*N

L1 = json.loads(s)
def flatten(L):
    for el in L:
        try:
            for item in flatten(el):
                yield item
        except TypeError:
            yield el
assert next(flatten(L1)) == 123
print("json ok")

L2 = ast.literal_eval(s) # raises MemoryError

Upvotes: 2

Noufal Ibrahim
Noufal Ibrahim

Reputation: 72765

Your generator is producing bad code. You should treat this exactly as you would if it were producing syntactically invalid code.

Use functions, dictionary dispatching and any other thing that might occur to you to reduce the depth.

OTOH, thanks for showing me that Python does really have a maximum depth. I didn't know that. :)

Upvotes: 3

Related Questions