Search code examples
pythonsyntaxsyntax-erroreval

SyntaxError: invalid syntax, clause on '=' in eval() function


I'm having the following trouble with my program:

  File "C:/Users/6ixpage/Documents/SoftwareDevelopment/Python/Programs/CLI/PrintandCopy/P&C Job System.py", line 75, in set
    eval('self.details['+a+'].'+b+'"'+c+'"');
  File "<string>", line 1
    self.details[0].file = "image"
                         ^
SyntaxError: invalid syntax

Here's the code snippet for reference:

IN = ('details','0','file','image')
if IN[0] == 'details':
    a = IN[1]
    b = IN[2]
    c = IN[3]
    print('self.details['+a+'].'+b+' = "'+c+'"');
    eval('self.details['+a+'].'+b+' = "'+c+'"');
  • IN[0] - used to identify that the command specifies the details of the folder.
  • IN[1] - the task within the folder.
  • IN[2] - the attribute of the task (any of type, file, quantity, tally).
  • IN[3] - the value to set the attribute to.

The entire code is here, unfortunately undocumented as I originally wanted to only have a simple CUI setup. But do quiz me if you have any questions about particular snippets. I have paper documentation too, that shows how the program is supposed to work.

If you can suggest some changes to how the CUI works please do, especially if they will cause less headaches than the one I currently have. (And I'm certain that I don't have to use eval() for every single function.)


Solution

  • From Duncan's comment:

    eval evaluates an expression. Assignment is a statement, not an expression so you can't do it with eval.

    You could use exec (see this answer for the explanation about exec and eval), but seriously, there is no need to obfuscate your code with these.

    Here's what you could do:

    inputs = ('details', '0', 'file', 'image')
    if inputs[0] == 'details':
        a = inputs[1]
        b = inputs[2]
        c = inputs[3]
        setattr(self.details[int(a)], b, c)
    

    (Note there is no test. All inputs are considered valid.)

    Explanation:

    • int(a) turns string '0' into integer 0.
    • setattr sets attribute 'file' of self.details[0] to 'image'

    You should consider eval and exec last resort things. Most likely you don't need those anywhere in your code.

    For instance

    eval('print(self.' + str(arg) + ')')
    

    should be written

    print(getattr(self, arg))