(Simplified from an excessively verbose question I posted earlier!)
Given a Python string containing valid Python code that contains a "yield" statement, how can I construct a generator that exec's that string?
For example, given the string:
code_string = """for x in range(0, 10):
yield x
"""
I want to construct a generator f that executes code_string such that (in this particular example):
assert(list(f()) == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Note that code_string is arbitrary, so this assertion is only valid for the example above. code_string can contain any valid python code that contains a yield statement.
Thanks!
Edit:
The first solution I thought of was to just munge "def f():" into the string and indent each line programmatically. However, that fails if code_string uses different indentation. I was hoping there were some little-known functools kung-fu that can construct a function from a blob of text.
Edit2:
I also tried an exec inside a function like so:
code = "for x in range(0, 10): yield x"
def f():
exec code in globals(), locals()
This results in "SyntaxError: 'yield' outside function"
Solved: I stand corrected, indentation is relative, so this works:
code_string = """for x in range(0, 10):
yield x
"""
exec "def f():\n" + [(" " + line) for line in code_string.split('\n')]) + "\n"
assert list(f()) == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]