def visit(self, node):
# One change from ast.NodeVisitor.visit: do not fallback to generic_visit (we only care about top-level)
method = 'visit_' + node.__class__.__name__
visitor = getattr(self, method, None)
if visitor is not None:
visitor(node)
python类NodeVisitor()的实例源码
def generic_visit(self, node):
ast.NodeVisitor.generic_visit(self, node)
def visit_Attribute(self, node): # pylint: disable=invalid-name
"""Handle bare Attributes i.e. [tf.foo, tf.bar].
Args:
node: Node that is of type ast.Attribute
"""
full_name = self._get_attribute_full_path(node)
if full_name and full_name.startswith("tf."):
self._rename_functions(node, full_name)
if full_name in self._api_change_spec.change_to_function:
if not hasattr(node, "is_function_for_call"):
new_text = full_name + "()"
self._file_edit.add("Changed %r to %r"%(full_name, new_text),
node.lineno, node.col_offset, full_name, new_text)
ast.NodeVisitor.generic_visit(self, node)
def generic_visit(self, node):
ast.NodeVisitor.generic_visit(self, node)
def ast_uses_varset(root, varset):
class UsesVarsetVisitor(ast.NodeVisitor):
def __init__(self):
self.uses_varset = False
def visit_Name(self, node):
if node.id in varset:
self.uses_varset = True
vis = UsesVarsetVisitor()
vis.visit(root)
return vis.uses_varset
def get_method_by_name(module_node, name):
class Visitor(ast.NodeVisitor):
def visit_Module(self, node):
self.result = None
self.generic_visit(node)
def visit_FunctionDef(self, node):
if node.name == name:
assert self.result is None, "More than one result in module"
self.result = node
v = Visitor()
v.visit(module_node)
return v.result
def get_class_node(module_node):
class Visitor(ast.NodeVisitor):
def visit_Module(self, node):
self.result = None
self.generic_visit(node)
def visit_ClassDef(self, node):
assert self.result is None, "More than one class in module"
self.result = node
v = Visitor()
v.visit(module_node)
return v.result
def get_variables(root):
class Visitor(ast.NodeVisitor):
def __init__(self):
self.vars = set()
def visit_Name(self, node):
self.vars.add(node.id)
var_visitor = Visitor()
var_visitor.visit(root)
return var_visitor.vars
def split_params_from_model(self, root):
class CollectParamsVisitor(ast.NodeVisitor):
def visit_Module(self_c, node):
self_c.param_statements = []
self_c.param_dict = None
self_c.generic_visit(node)
def visit_Assign(self_c, node):
if u.is_param_declaration(node):
self_c.param_statements.append(node)
elif u.is_self_params_assignment(node):
self_c.param_dict = node
cpv = CollectParamsVisitor()
cpv.visit(root)
class RemoveParamsTransformer(self.MyTransformer):
def visit_FunctionDef(self_r, node):
""" Don't recurse into user defined functions """
return node
def visit_Assign(self_r, node):
if u.is_param_declaration(node):
return []
elif u.is_self_params_assignment(node):
return []
else:
return node
rpt = RemoveParamsTransformer()
root = rpt.visit(root)
return root, cpv.param_statements, cpv.param_dict
def scan_opcodes_cli(self, co):
import ast
with open(co.co_filename, 'rU') as f:
nodes = ast.parse(f.read(), co.co_filename)
items = []
class ModuleFinderVisitor(ast.NodeVisitor):
def visit_Assign(self, node):
for x in node.targets:
if isinstance(x, ast.Subscript):
if isinstance(x.value, ast.Name):
items.append(("store", (x.value.id, )))
elif isinstance(x.value, ast.Attribute):
items.append(("store", (x.value.attr, )))
else:
print 'Unknown in store: %s' % type(x.value).__name__
elif isinstance(x, ast.Name):
items.append(("store", (x.id, )))
def visit_Import(self, node):
items.extend([("import", (None, x.name)) for x in node.names])
def visit_ImportFrom(self, node):
if node.level == 1:
items.append(("relative_import", (node.level, [x.name for x in node.names], node.module)))
else:
items.extend([("import", ([x.name for x in node.names], node.module))])
v = ModuleFinderVisitor()
v.visit(nodes)
for what, args in items:
yield what, args
def _find_decorators(cls):
result = dict()
def visit_FunctionDef(node):
result[node.name] = [ast.dump(e) for e in node.decorator_list]
v = ast.NodeVisitor()
v.visit_FunctionDef = visit_FunctionDef
v.visit(compile(inspect.getsource(cls), '?', 'exec', ast.PyCF_ONLY_AST))
return result
def visit_Attribute(self, node):
ast.NodeVisitor.generic_visit(self, node)
self.ls.append(node.attr)
def visit_Call(self, node):
p = ParseCall()
p.visit(node.func)
ast.NodeVisitor.generic_visit(self, node)
if p.ls[-1] == 'simplefilter' or p.ls[-1] == 'filterwarnings':
if node.args[0].s == "ignore":
raise AssertionError(
"ignore filter should not be used; found in "
"{} on line {}".format(self.__filename, node.lineno))
if p.ls[-1] == 'warn' and (
len(p.ls) == 1 or p.ls[-2] == 'warnings'):
if "testing/tests/test_warnings.py" is self.__filename:
# This file
return
# See if stacklevel exists:
if len(node.args) == 3:
return
args = {kw.arg for kw in node.keywords}
if "stacklevel" in args:
return
raise AssertionError(
"warnings should have an appropriate stacklevel; found in "
"{} on line {}".format(self.__filename, node.lineno))
def __init__(self, fname, cache):
ast.NodeVisitor.__init__(self)
self.fname = fname
self.cache = cache
self.class_stack = []
def generic_visit(self, node):
ast.NodeVisitor.generic_visit(self, node)
def visit_node(self, node):
self.path.append(node.name)
node_name = ".".join(self.path)
if node_name in self.filters:
self.nodes[node_name] = node
ast.NodeVisitor.generic_visit(self, node)
self.path.pop()
self.ended_nodes.append(node)
def __init__(self, calculator):
super(NodeVisitor, self).__init__()
self._calculator = calculator
self._dependencies = []
##############################################
def dependencies(self):
return self._dependencies
##############################################
# def visit(self, node):
# print(node)
# super(NodeVisitor, self).visit(node)
##############################################
def _compile(self):
expression = self._expression
self._logger.info("expression '{}'".format(expression))
# Python don't accept identifier starting with @
# https://docs.python.org/3.5/reference/lexical_analysis.html#identifiers
if '@' in expression:
custom_measurements = []
start = 0
while True:
name, start = self._find_name('@', start)
if name is None:
break
else:
custom_measurements.append(name)
for measurement in custom_measurements:
expression = self.expression.replace(measurement, self._calculator.measurements[measurement].name)
functions = []
for function in (
'Angle1Spl_',
'Angle2Spl_',
'AngleLine_',
'CurrentLength',
'C1LengthSpl_',
'C2LengthSpl_',
'Line_',
'Spl_',
):
start = 0
while True:
name, start = self._find_name(function, start)
if name is None:
break
else:
functions.append(name)
# self._logger.info('Functions ' + str(functions))
for function_call in functions:
parts = function_call.split('_')
function = parts[0]
args = parts[1:]
pythonised_function = '__calculator__._function_' + function + '(' + ', '.join(["'{}'".format(x) for x in args]) + ')'
# self._logger.info('Function {} {} -> {}'.format(function, args, pythonised_function))
expression = expression.replace(function_call, pythonised_function)
self._logger.info("Pythonised expression '{}'".format(expression))
# Fixme: What is the (supported) grammar ?
# http://beltoforion.de/article.php?a=muparser
# http://beltoforion.de/article.php?a=muparserx
self._ast = ast.parse(expression, mode='eval')
node_visitor = NodeVisitor(self._calculator)
node_visitor.generic_visit(self._ast)
self._dependencies = node_visitor.dependencies
self._code = compile(self._ast, '<string>', mode='eval')
# print('AST', astunparse.dump(self._ast))
# print('AST -> Python', astunparse.unparse(self._ast))
## print('AST -> Python', astor.to_source(self._ast.body))
##############################################