1

I have a file, "file.txt":

some text
some more text
*
a = 10
if a == 10:
    print (a)
else:
    print ("hello world")
/*
some text
some more text

I extract the text between * and /* from the file and store is line by line into a list:

['a = 10', 'if a == 10:', '    print (a)', 'else:', '    print ("hello world")']

with:

list = []
for line in open("file.txt", 'r'):
    if line.startswith("*"):
        store = True
    if line.startswith("/*"):
        store = False
    if store == True:
        if line.startswith("*"): pass
        else: list.append(line)

After that I want to execute the code inside the list. I came halfway with the following code with exec and compile:

code_to_execute = compile("""
a = 10
if a == 10:
    print (a)
else:
    print ("hello world")
""", '<string>', 'exec')

and:

exec code_to_execute

But I would like to do that with the use of the list: in the sense of:

code_to_execute = compile(list)
exec code_to_execute

How can I do this with python ? (preferably python2.7)

The problem is not how to join the members of a list into a string. The problem is how to execute a multiline variable. Since if I would make a string out of a list I'll lose the newlines and indentation, besides I thought it is not possible to do something like:

string = "print \"hello world\""
code_to_execute = compile(""" """ + string + """ """, '<string>', 'exec')

or is it ?

azbc
  • 399
  • 1
  • 5
  • 12
  • 6
    To get the content of the variable `code_to_execute` from the list by joining them with `'\n'.join(list)`. – dseuss Nov 21 '17 at 13:13
  • 1
    Possible duplicate of [How to join two string with a new line between them?](https://stackoverflow.com/questions/27083445/how-to-join-two-string-with-a-new-line-between-them) – Reti43 Nov 21 '17 at 13:16
  • 1
    Can we assume that the contents of "file.txt" are guaranteed to be safe, or that you don't care if it contains malicious code that could trash your hard drive, spread malware, etc? – PM 2Ring Nov 21 '17 at 13:35
  • @PM 2Ring - I use code inside the list that is safe. Why ? – azbc Nov 21 '17 at 13:37
  • 1
    `eval` and `exec` should generally be avoided because they can be a security risk. For details, please see [Eval really is dangerous](http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html) by SO veteran Ned Batchelder. But of course you're free to use them if you know what you're doing. And sometimes you have no alternative. Also be aware that they aren't very fast. BTW, there's a lot of great info about exec, eval, and compile [here](https://stackoverflow.com/a/29456463/4014959). – PM 2Ring Nov 21 '17 at 13:48
  • @PM 2Ring - Ok... thanks, ... but for exec it seems a bit strange that it would be dangerous. If I execute code stored inside a `list` or if I execute code stored inside a `file` ? If the code inside the `file` is safe, the same code inside a `list` would be just as safe I would think ? Or why would that not be so ? The content of the code is constant the same btw. – azbc Nov 21 '17 at 13:58
  • 1
    Sure, `exec` is no more (or less) dangerous than executing a script file normally. The danger comes when you don't have control over the string you're `exec`ing, eg it's code submitted by person A running on person B's machine. – PM 2Ring Nov 21 '17 at 14:22
  • @PM 2Ring - Ok, thanks, that was helpfull :) – azbc Nov 21 '17 at 14:36

1 Answers1

2

It is kinda unclear what you are asking for, but i'm going to proceed from this statement

But I would like to do that with the use of the list: in the sense of:

code_to_execute = compile(list)
exec code_to_execute

And urge you to adhere to the comment of @dseuss, by simply doing

code_to_execute = compile("\n".join(list), "<string>", "exec")
exec code_to_execute

No, you will not lose the newlines. Have you tried this?

Example:

>>> l = ['a = 10', 'if a == 10:', '    print (a)', 'else:', '    print ("hello world")']
>>> code_to_execute = compile("\n".join(l), "<string>", "exec")
>>> exec code_to_execute
10
Community
  • 1
  • 1
Pax Vobiscum
  • 2,551
  • 2
  • 21
  • 32