How Can I Inject Code In Python Programs So That They Can Print The Conditions Inside The If Statement?
Solution 1:
You can use the ast
module, but you still need the sources. If you have only the bytecode, you must use something like uncompyle6 in order to get the source back - since you are doing this automatically it doesn't matter if the source is obfuscated.
Suppose you have a module like this:
deffoo(x):
if x > 100:
print('big')
else:
print('small')
if __name__ == '__main__':
foo(5)
foo(500)
If you exec foo, you get:
small
big
Now you want to print the test clause of every if
statement if the test is True
. Lets start by importing foo:
>>>import foo
Then get the source code:
>>>source = inspect.getsource(foo)
Lets parse the source in order to get an abstract syntax tree:
>>>tree = ast.parse(source)
The next step is defining a NodeTransformer that will modify the tree:
>>> class IfTransformer(ast.NodeTransformer):
def visit_If(self, node):
new_node = ast.Expr(value=ast.Call(
func=ast.Name(id='print', ctx=ast.Load()),
args=[ast.Str(s=astunparse.unparse(node.test))],
keywords=[]
))
node.body.insert(0, new_node)
return ast.fix_missing_locations(node)
In order to modify the tree we make our IfTransformer
visit all nodes:
>>> IfTransformer().visit(tree)
Then you can compile and execute your new source:
>>> exec(compile(tree, 'foo.py', 'exec'))
(__name__ == '__main__')
small
(x > 100)
big
For each if
clause where the test is True, you got the test printed. A smart guy like you can figure everything out from here.
Check out this video from Pycon 2011.
Post a Comment for "How Can I Inject Code In Python Programs So That They Can Print The Conditions Inside The If Statement?"