Handling line continuation and escaped characters in Python

59 Views Asked by At

I am working with Python code captured from Nuke, a compositing software, which adds line continuation and escaped characters. The code typed in by the user in Nuke is as follows:

if nuke.frame()>1:
   ret=nuke.frame()/2
else:
   ret=nuke.frame()

To retrieve this code (which is stored in a node's knob in Nuke), i use the expression() method from Nuke's Python API, here's an example:

animation_curve = n['multiply'].animation(0)
code_string = animation_curve.expression()

The resulting code string is as follows:

[python -execlocal if\ nuke.frame()>1:\n\ \ \ ret=nuke.frame()/2\nelse:\n\ \ \ ret=nuke.frame()]

Then via regex pattern matching i capture only the code:

if\ nuke.frame()>1:\n\ \ \ ret=nuke.frame()/2\nelse:\n\ \ \ ret=nuke.frame()

My objective is to parse and execute this code string using the ast module in Python, taking into account the line continuation and escaped characters present. However, I am encountering difficulties due to the syntax error caused by the unexpected characters following the line continuation characters. When I try tree = ast.parse(code_string) I get:

    if\ nuke.frame()>1:\n\ \ \ ret=nuke.frame()/2\nelse:\n\ \ \ ret=nuke.frame()
                                                                               ^
SyntaxError: unexpected character after line continuation character

Note that I probably can't use .replace() to get rid of backslashes in the code because some code might actually have backslashes in it.. I also can't use exec() due to security risks.

I appreciate any insights, suggestions, or code examples that can guide me in correctly parsing and executing the Python code obtained from Nuke's animation expression. Thank you for your valuable assistance!

1

There are 1 best solutions below

0
JonSG On BEST ANSWER

The trick here is that you have spaces that are escaped with backslashes "\ " and the ast package does not like them. I believe we can manually strip them out and things should hopefully work.

Try:

import ast

text = "if\ nuke.frame()>1:\n\ \ \ ret=nuke.frame()/2\nelse:\n\ \ \ ret=nuke.frame()"
parser = ast.parse(text.replace("\ ", " "))  # <---- Take care of the escaped spaces
walker = ast.walk(parser)
print(list(walker))