How To Execute Nested Pycode Objects
Let's say we have a code object like this: code = ''' x = 'unrelated' y = dangerous_function() def foo(): return 'say foo' ''' code_obj = compile(code, '', 'exec
Solution 1:
The co_const
attribute holds just the constant literals defined in a code object, so in your example it holds just the code that loads 'say foo'
as an argument for return, which can be verified with dis
:
import dis
for obj in code_obj.co_consts:
if isinstance(obj, types.CodeType):
dis.dis(obj)
This outputs:
5 0 LOAD_CONST 1 ('say foo')
2 RETURN_VALUE
So by executing this code object it naturally would not define any names.
If you would like to execute just a specific function in a given source code, you can parse the code with ast.parse
and use a ast.NodeVisitor
subclass to extract the function node, wrap it with a Module
node so you can compile and execute it alone:
import ast
classget_function(ast.NodeVisitor):
def__init__(self, name):
self.name = name
self.code = Nonedefvisit_FunctionDef(self, node):
if node.name == self.name:
self.code = compile(ast.fix_missing_locations(ast.Module(body=[node])), '<string>', 'exec')
func = get_function('foo')
func.visit(ast.parse(code, '<string>'))
exec(func.code)
print(eval('foo'))
This outputs:
<function foo at 0x018735D0>
EDIT: Alternatively and more simply, you can use the ast.walk
function to traverse the nodes with a for
loop:
import ast
for node in ast.walk(ast.parse(code, '<string>')):
ifisinstance(node, ast.FunctionDef) and node.name == 'foo':
code_obj = compile(ast.fix_missing_locations(ast.Module(body=[node])), '<string>', 'exec')
exec(code_obj)
print(eval('foo'))
Post a Comment for "How To Execute Nested Pycode Objects"