Reputation: 7521
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
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
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
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