def NAME(self, node):
"""
Handle occurrence of Name (which can be a load/store/delete access.)
"""
# Locate the name in locals / function / globals scopes.
if isinstance(node.ctx, (ast.Load, ast.AugLoad)):
self.handleNodeLoad(node)
if (node.id == 'locals' and isinstance(self.scope, FunctionScope)
and isinstance(node.parent, ast.Call)):
# we are doing locals() call in current scope
self.scope.usesLocals = True
elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
self.handleNodeStore(node)
elif isinstance(node.ctx, ast.Del):
self.handleNodeDelete(node)
else:
# must be a Param context -- this only happens for names in function
# arguments, but these aren't dispatched through here
raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
python类Load()的实例源码
def NAME(self, node):
"""
Handle occurrence of Name (which can be a load/store/delete access.)
"""
# Locate the name in locals / function / globals scopes.
if isinstance(node.ctx, (ast.Load, ast.AugLoad)):
self.handleNodeLoad(node)
if (node.id == 'locals' and isinstance(self.scope, FunctionScope)
and isinstance(node.parent, ast.Call)):
# we are doing locals() call in current scope
self.scope.usesLocals = True
elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
self.handleNodeStore(node)
elif isinstance(node.ctx, ast.Del):
self.handleNodeDelete(node)
else:
# must be a Param context -- this only happens for names in function
# arguments, but these aren't dispatched through here
raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
def make_const(arg, lineno=0, col_offset=0):
kw = {'lineno':lineno, 'col_offset':col_offset}
if isinstance(arg, str):
const = _ast.Str(s=arg, **kw)
elif isinstance(arg, (int, float, complex)):
const = _ast.Num(n=arg, **kw)
elif arg is None:
const = _ast.Name(id='None', ctx=_ast.Load(), **kw)
elif isinstance(arg, tuple):
elts = []
for item in arg:
elts.append(make_const(item, **kw))
const = _ast.Tuple(elts=elts, ctx=_ast.Load(), **kw)
else:
const = arg
return const
def decompile_func(func):
'''
Decompile a function into ast.FunctionDef node.
:param func: python function (can not be a built-in)
:return: ast.FunctionDef instance.
'''
if hasattr(func, 'func_code'):
code = func.func_code
else:
code = func.__code__
# For python 3
# defaults = func.func_defaults if sys.version_info.major < 3 else func.__defaults__
# if defaults:
# default_names = code.co_varnames[:code.co_argcount][-len(defaults):]
# else:
# default_names = []
# defaults = [_ast.Name(id='%s_default' % name, ctx=_ast.Load() , lineno=0, col_offset=0) for name in default_names]
ast_node = make_function(code, defaults=[], lineno=code.co_firstlineno)
return ast_node
def visitName(self, node):
if isinstance(node.ctx, _ast.Store):
self.modified.add(node.id)
elif isinstance(node.ctx, _ast.Load):
self.used.update(node.id)
if not self.graph.has_node(node.id):
self.graph.add_node(node.id)
if isinstance(node.ctx, _ast.Load):
self.undefined.add(node.id)
for ctx_var in self.context_names:
if not self.graph.has_edge(node.id, ctx_var):
self.graph.add_edge(node.id, ctx_var)
return {node.id}
def NAME(self, node):
"""
Handle occurrence of Name (which can be a load/store/delete access.)
"""
# Locate the name in locals / function / globals scopes.
if isinstance(node.ctx, (ast.Load, ast.AugLoad)):
self.handleNodeLoad(node)
if (node.id == 'locals' and isinstance(self.scope, FunctionScope)
and isinstance(node.parent, ast.Call)):
# we are doing locals() call in current scope
self.scope.usesLocals = True
elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
self.handleNodeStore(node)
elif isinstance(node.ctx, ast.Del):
self.handleNodeDelete(node)
else:
# must be a Param context -- this only happens for names in function
# arguments, but these aren't dispatched through here
raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
def RequestReport(self, path):
try:
execInfo = self.ExecutionClient.service.LoadReport(path, None)
return execInfo
except BaseException as e:
msg = "Could not Load the Report: %s" % e.fault.faultstring
log.error(msg)
if self.verbose:
print(msg)
return
def isNone(node):
if node is None:
return True
elif isinstance(node, _ast.Name) and (node.id == 'None') and isinstance(node.ctx, _ast.Load):
return True
return False
def LOAD_NAME(self, instr):
name = _ast.Name(id=instr.arg, ctx=_ast.Load(), lineno=instr.lineno, col_offset=0)
self.ast_stack.append(name)
def LOAD_DEREF(self, instr):
name = _ast.Name(id=instr.arg, ctx=_ast.Load(), lineno=instr.lineno, col_offset=0)
self.ast_stack.append(name)
def LOAD_FAST(self, instr):
name = _ast.Name(id=instr.arg, ctx=_ast.Load(), lineno=instr.lineno, col_offset=0)
self.ast_stack.append(name)
def LOAD_ATTR(self, instr):
name = self.ast_stack.pop()
attr = instr.arg
get_attr = _ast.Attribute(value=name, attr=attr, ctx=_ast.Load(), lineno=instr.lineno, col_offset=0)
self.ast_stack.append(get_attr)
def ROT_TWO(self, instr):
one = self.ast_stack.pop()
two = self.ast_stack.pop()
if self.ilst[0].opname == 'STORE_NAME':
kw = dict(lineno=instr.lineno, col_offset=0)
stores = []
while self.ilst[0].opname == 'STORE_NAME':
stores.append(self.ilst.pop(0))
assert len(stores) <= 3, stores
elts_load = [one, two]
if len(stores) == 3:
elts_load.insert(0, self.ast_stack.pop())
tup_load = _ast.Tuple(elts=elts_load[::-1], ctx=_ast.Load(), **kw)
elts_store = [_ast.Name(id=store.arg, ctx=_ast.Store(), **kw) for store in stores]
tup_store = _ast.Tuple(elts=elts_store, ctx=_ast.Store(), **kw)
assgn = _ast.Assign(value=tup_load, targets=[tup_store], **kw)
self.ast_stack.append(assgn)
# self.ast_stack.append(tup_store)
else:
self.ast_stack.append(one)
self.ast_stack.append(two)
def BUILD_LIST(self, instr):
nitems = instr.oparg
nodes = []
list_ = _ast.List(elts=nodes, ctx=_ast.Load(), lineno=instr.lineno, col_offset=0)
for i in range(nitems):
nodes.insert(0, self.ast_stack.pop())
self.ast_stack.append(list_)
def BUILD_TUPLE(self, instr):
nitems = instr.oparg
nodes = []
list_ = _ast.Tuple(elts=nodes, ctx=_ast.Load(), lineno=instr.lineno, col_offset=0)
for i in range(nitems):
nodes.insert(0, self.ast_stack.pop())
if any([item == 'CLOSURE' for item in nodes]):
assert all([item == 'CLOSURE' for item in nodes])
return
self.ast_stack.append(list_)
def BUILD_SET(self, instr):
nitems = instr.oparg
nodes = []
list_ = _ast.Set(elts=nodes, ctx=_ast.Load(), lineno=instr.lineno, col_offset=0)
for i in range(nitems):
nodes.insert(0, self.ast_stack.pop())
self.ast_stack.append(list_)
def SLICE_0(self, instr):
'obj[:]'
value = self.ast_stack.pop()
kw = dict(lineno=instr.lineno, col_offset=0)
slice = _ast.Slice(lower=None, step=None, upper=None, **kw)
subscr = _ast.Subscript(value=value, slice=slice, ctx=_ast.Load(), **kw)
self.ast_stack.append(subscr)
def SLICE_1(self, instr):
'obj[lower:]'
lower = self.ast_stack.pop()
value = self.ast_stack.pop()
kw = dict(lineno=instr.lineno, col_offset=0)
slice = _ast.Slice(lower=lower, step=None, upper=None, **kw)
subscr = _ast.Subscript(value=value, slice=slice, ctx=_ast.Load(), **kw)
self.ast_stack.append(subscr)
def SLICE_2(self, instr):
'obj[:stop]'
upper = self.ast_stack.pop()
value = self.ast_stack.pop()
kw = dict(lineno=instr.lineno, col_offset=0)
slice = _ast.Slice(lower=None, step=None, upper=upper, **kw)
subscr = _ast.Subscript(value=value, slice=slice, ctx=_ast.Load(), **kw)
self.ast_stack.append(subscr)
def SLICE_3(self, instr):
'obj[lower:upper]'
upper = self.ast_stack.pop()
lower = self.ast_stack.pop()
value = self.ast_stack.pop()
kw = dict(lineno=instr.lineno, col_offset=0)
slice = _ast.Slice(lower=lower, step=None, upper=upper, **kw)
subscr = _ast.Subscript(value=value, slice=slice, ctx=_ast.Load(), **kw)
self.ast_stack.append(subscr)
def visitSubscript(self, node):
if isinstance(node.ctx, _ast.Load):
return collect_(self, node)
else:
sources = self.visit(node.slice)
targets = self.visit(node.value)
self.modified.update(targets)
add_edges(self.graph, targets, sources)
return targets
def handle_generators(self, generators):
defined = set()
required = set()
for generator in generators:
get_symbols(generator, _ast.Load)
required.update(get_symbols(generator, _ast.Load) - defined)
defined.update(get_symbols(generator, _ast.Store))
return defined, required
def visitListComp(self, node):
defined, required = self.handle_generators(node.generators)
required.update(get_symbols(node.elt, _ast.Load) - defined)
for symbol in required:
if not self.graph.has_node(symbol):
self.graph.add_node(symbol)
self.undefined.add(symbol)
return required
def visitSetComp(self, node):
defined, required = self.handle_generators(node.generators)
required.update(get_symbols(node.elt, _ast.Load) - defined)
for symbol in required:
if not self.graph.has_node(symbol):
self.graph.add_node(symbol)
self.undefined.add(symbol)
return required
def _native_repr_tree(self, node, indent, _done=None):
"""recursive method for the native tree representation"""
from _ast import Load as _Load, Store as _Store, Del as _Del
from _ast import AST as Node
if _done is None:
_done = set()
if node in _done:
self._string += '\nloop in tree: %r (%s)' % (
node, getattr(node, 'lineno', None))
return
_done.add(node)
self._string += '\n' + indent + '<%s>' % node.__class__.__name__
indent += self.indent
if not hasattr(node, '__dict__'):
self._string += '\n' + self.indent + " ** node has no __dict__ " + str(node)
return
node_dict = node.__dict__
if hasattr(node, '_attributes'):
for a in node._attributes:
attr = node_dict[a]
if attr is None:
continue
if a in ("lineno", "col_offset") and not self.lineno:
continue
self._string += '\n' + indent + a + " = " + repr(attr)
for field in node._fields or ():
attr = node_dict[field]
if attr is None:
continue
if isinstance(attr, list):
if not attr:
continue
self._string += '\n' + indent + field + ' = ['
for elt in attr:
self._native_repr_tree(elt, indent, _done)
self._string += '\n' + indent + ']'
continue
if isinstance(attr, (_Load, _Store, _Del)):
continue
if isinstance(attr, Node):
self._string += '\n' + indent + field + " = "
self._native_repr_tree(attr, indent, _done)
else:
self._string += '\n' + indent + field + " = " + repr(attr)
def _native_repr_tree(self, node, indent, _done=None):
"""recursive method for the native tree representation"""
from _ast import Load as _Load, Store as _Store, Del as _Del
from _ast import AST as Node
if _done is None:
_done = set()
if node in _done:
self._string += '\nloop in tree: %r (%s)' % (
node, getattr(node, 'lineno', None))
return
_done.add(node)
self._string += '\n' + indent + '<%s>' % node.__class__.__name__
indent += self.indent
if not hasattr(node, '__dict__'):
self._string += '\n' + self.indent + " ** node has no __dict__ " + str(node)
return
node_dict = node.__dict__
if hasattr(node, '_attributes'):
for a in node._attributes:
attr = node_dict[a]
if attr is None:
continue
if a in ("lineno", "col_offset") and not self.lineno:
continue
self._string += '\n' + indent + a + " = " + repr(attr)
for field in node._fields or ():
attr = node_dict[field]
if attr is None:
continue
if isinstance(attr, list):
if not attr:
continue
self._string += '\n' + indent + field + ' = ['
for elt in attr:
self._native_repr_tree(elt, indent, _done)
self._string += '\n' + indent + ']'
continue
if isinstance(attr, (_Load, _Store, _Del)):
continue
if isinstance(attr, Node):
self._string += '\n' + indent + field + " = "
self._native_repr_tree(attr, indent, _done)
else:
self._string += '\n' + indent + field + " = " + repr(attr)
def _native_repr_tree(self, node, indent, _done=None):
"""recursive method for the native tree representation"""
from _ast import Load as _Load, Store as _Store, Del as _Del
from _ast import AST as Node
if _done is None:
_done = set()
if node in _done:
self._string += '\nloop in tree: %r (%s)' % (
node, getattr(node, 'lineno', None))
return
_done.add(node)
self._string += '\n' + indent + '<%s>' % node.__class__.__name__
indent += self.indent
if not hasattr(node, '__dict__'):
self._string += '\n' + self.indent + " ** node has no __dict__ " + str(node)
return
node_dict = node.__dict__
if hasattr(node, '_attributes'):
for a in node._attributes:
attr = node_dict[a]
if attr is None:
continue
if a in ("lineno", "col_offset") and not self.lineno:
continue
self._string += '\n' + indent + a + " = " + repr(attr)
for field in node._fields or ():
attr = node_dict[field]
if attr is None:
continue
if isinstance(attr, list):
if not attr:
continue
self._string += '\n' + indent + field + ' = ['
for elt in attr:
self._native_repr_tree(elt, indent, _done)
self._string += '\n' + indent + ']'
continue
if isinstance(attr, (_Load, _Store, _Del)):
continue
if isinstance(attr, Node):
self._string += '\n' + indent + field + " = "
self._native_repr_tree(attr, indent, _done)
else:
self._string += '\n' + indent + field + " = " + repr(attr)
def _native_repr_tree(self, node, indent, _done=None):
"""recursive method for the native tree representation"""
from _ast import Load as _Load, Store as _Store, Del as _Del
from _ast import AST as Node
if _done is None:
_done = set()
if node in _done:
self._string += '\nloop in tree: %r (%s)' % (
node, getattr(node, 'lineno', None))
return
_done.add(node)
self._string += '\n' + indent + '<%s>' % node.__class__.__name__
indent += self.indent
if not hasattr(node, '__dict__'):
self._string += '\n' + self.indent + " ** node has no __dict__ " + str(node)
return
node_dict = node.__dict__
if hasattr(node, '_attributes'):
for a in node._attributes:
attr = node_dict[a]
if attr is None:
continue
if a in ("lineno", "col_offset") and not self.lineno:
continue
self._string += '\n' + indent + a + " = " + repr(attr)
for field in node._fields or ():
attr = node_dict[field]
if attr is None:
continue
if isinstance(attr, list):
if not attr:
continue
self._string += '\n' + indent + field + ' = ['
for elt in attr:
self._native_repr_tree(elt, indent, _done)
self._string += '\n' + indent + ']'
continue
if isinstance(attr, (_Load, _Store, _Del)):
continue
if isinstance(attr, Node):
self._string += '\n' + indent + field + " = "
self._native_repr_tree(attr, indent, _done)
else:
self._string += '\n' + indent + field + " = " + repr(attr)