def __init__(self, stmt, context):
self.stmt = stmt
self.context = context
self.stmt_table = {
ast.Expr: self.expr,
ast.Pass: self.parse_pass,
ast.AnnAssign: self.ann_assign,
ast.Assign: self.assign,
ast.If: self.parse_if,
ast.Call: self.call,
ast.Assert: self.parse_assert,
ast.For: self.parse_for,
ast.AugAssign: self.aug_assign,
ast.Break: self.parse_break,
ast.Return: self.parse_return,
}
stmt_type = self.stmt.__class__
if stmt_type in self.stmt_table:
self.lll_node = self.stmt_table[stmt_type]()
elif isinstance(stmt, ast.Name) and stmt.id == "throw":
self.lll_node = LLLnode.from_list(['assert', 0], typ=None, pos=getpos(stmt))
else:
raise StructureException("Unsupported statement type", stmt)
python类Assign()的实例源码
def assign_tuple_target(self, node, right_hand_side_variables):
new_assignment_nodes = list()
for i, target in enumerate(node.targets[0].elts):
value = node.value.elts[i]
label = LabelVisitor()
label.visit(target)
if isinstance(value, ast.Call):
new_ast_node = ast.Assign(target, value)
new_ast_node.lineno = node.lineno
new_assignment_nodes.append( self.assignment_call_node(label.result, new_ast_node))
else:
label.result += ' = '
label.visit(value)
new_assignment_nodes.append(self.append_node(AssignmentNode(label.result, self.extract_left_hand_side(target), ast.Assign(target, value), right_hand_side_variables, line_number = node.lineno, path=self.filenames[-1])))
self.connect_nodes(new_assignment_nodes)
return ControlFlowNode(new_assignment_nodes[0], [new_assignment_nodes[-1]], []) # return the last added node
def pop_format_context(self, expl_expr):
"""Format the %-formatted string with current format context.
The expl_expr should be an ast.Str instance constructed from
the %-placeholders created by .explanation_param(). This will
add the required code to format said string to .on_failure and
return the ast.Name instance of the formatted string.
"""
current = self.stack.pop()
if self.stack:
self.explanation_specifiers = self.stack[-1]
keys = [ast.Str(key) for key in current.keys()]
format_dict = ast.Dict(keys, list(current.values()))
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
name = "@py_format" + str(next(self.variable_counter))
self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
return ast.Name(name, ast.Load())
def visit_Module(self, node):
for expr in node.body:
if not isinstance(expr, ast.Assign):
continue
if not isinstance(expr.value, (ast.Num, ast.Str)):
continue
if len(expr.targets) != 1:
continue
name = expr.targets[0]
if not isinstance(name, ast.Name):
continue
name = name.id
if not self.is_const_name(name):
continue
if name in self._constants:
self._constants[name] = None
else:
self._constants[name] = expr.value
return self.generic_visit(node)
def mapVariable(a, varId, assn):
"""Map the variable assignment into the function, if it's needed"""
if type(a) != ast.FunctionDef:
return a
for arg in a.args.args:
if arg.arg == varId:
return a # overriden by local variable
for i in range(len(a.body)):
line = a.body[i]
if type(line) == ast.Assign:
for target in line.targets:
if type(target) == ast.Name and target.id == varId:
break
elif type(target) in [ast.Tuple, ast.List]:
for elt in target.elts:
if type(elt) == ast.Name and elt.id == varId:
break
if countVariables(line, varId) > 0:
a.body[i:i+1] = [deepcopy(assn), line]
break
return a
def getAllGlobalNames(a):
# Finds all names that can be accessed at the global level in the AST
if type(a) != ast.Module:
return []
names = []
for obj in a.body:
if type(obj) in [ast.FunctionDef, ast.ClassDef]:
names.append(obj.name)
elif type(obj) in [ast.Assign, ast.AugAssign]:
targets = obj.targets if type(obj) == ast.Assign else [obj.target]
for target in obj.targets:
if type(target) == ast.Name:
names.append(target.id)
elif type(target) in [ast.Tuple, ast.List]:
for elt in target.elts:
if type(elt) == ast.Name:
names.append(elt.id)
elif type(obj) in [ast.Import, ast.ImportFrom]:
for module in obj.names:
names.append(module.asname if module.asname != None else module.name)
return names
def get_version():
with open(os.path.join('settei', 'version.py')) as f:
tree = ast.parse(f.read(), f.name)
for node in ast.walk(tree):
if not (isinstance(node, ast.Assign) and len(node.targets) == 1):
continue
target, = node.targets
value = node.value
if not (isinstance(target, ast.Name) and
target.id == 'VERSION_INFO' and
isinstance(value, ast.Tuple)):
continue
elts = value.elts
if any(not isinstance(elt, ast.Num) for elt in elts):
continue
return '.'.join(str(elt.n) for elt in elts)
def visit_AugAssign(self, node):
"""
AugAssign(expr target, operator op, expr value)
"""
# TODO: Make sure that all the logic in Assign also works in AugAssign
target = self.visit(node.target)
value = self.visit(node.value)
if isinstance(node.op, ast.Pow):
self.write("%s = %s ** %s" % (target, target, value))
#elif isinstance(node.op, ast.FloorDiv):
# #self.write("%s = Math.floor((%s)/(%s));" % (target, target, value))
# self.write("%s = (%s/%s)" % (target, target, value))
elif isinstance(node.op, ast.Div):
if re.search(r"Numo::", target) or re.search(r"Numo::", value):
self.write("%s = (%s)/(%s)" % (target, target, value))
else:
self.write("%s = (%s)/(%s).to_f" % (target, target, value))
else:
self.write("%s %s= %s" % (target, self.get_binary_op(node), value))
def assign_tuple_target(self, node, right_hand_side_variables):
new_assignment_nodes = list()
for i, target in enumerate(node.targets[0].elts):
value = node.value.elts[i]
label = LabelVisitor()
label.visit(target)
if isinstance(value, ast.Call):
new_ast_node = ast.Assign(target, value)
new_ast_node.lineno = node.lineno
new_assignment_nodes.append(self.assignment_call_node(label.result, new_ast_node))
else:
label.result += ' = '
label.visit(value)
new_assignment_nodes.append(self.append_node(AssignmentNode(label.result, self.extract_left_hand_side(target), ast.Assign(target, value), right_hand_side_variables, line_number=node.lineno, path=self.filenames[-1])))
self.connect_nodes(new_assignment_nodes)
return ControlFlowNode(new_assignment_nodes[0], [new_assignment_nodes[-1]], []) # return the last added node
def get_sink_args(cfg_node):
if isinstance(cfg_node.ast_node, ast.Call):
rhs_visitor = RHSVisitor()
rhs_visitor.visit(cfg_node.ast_node)
return rhs_visitor.result
elif isinstance(cfg_node.ast_node, ast.Assign):
return cfg_node.right_hand_side_variables
vv = VarsVisitor()
other_results = list()
if isinstance(cfg_node, BBorBInode):
other_results = cfg_node.args
else:
vv.visit(cfg_node.ast_node)
return vv.result + other_results
def match_type(self, typ, node):
if typ == 'class':
return isinstance(node, ast.ClassDef)
if typ == 'def':
return isinstance(node, ast.FunctionDef)
if typ == 'import':
return isinstance(node, (ast.Import, ast.ImportFrom))
if typ == 'assign':
return isinstance(node, ast.Assign)
if typ == 'attr':
return isinstance(node, ast.Attribute)
if typ == 'call':
if isinstance(node, ast.Call):
return True
# Python 2.x compatibility
return hasattr(ast, 'Print') and isinstance(node, ast.Print)
def run(self):
tree = self.tree
if self.filename == 'stdin':
lines = stdin_utils.stdin_get_value()
tree = ast.parse(lines)
for statement in ast.walk(tree):
for child in ast.iter_child_nodes(statement):
child.__flake8_builtins_parent = statement
for statement in ast.walk(tree):
value = None
if isinstance(statement, ast.Assign):
value = self.check_assignment(statement)
elif isinstance(statement, ast.FunctionDef):
value = self.check_function_definition(statement)
if value:
for line, offset, msg, rtype in value:
yield line, offset, msg, rtype
def _fine_property_definition(self, property_name):
"""Find the lines in the source code that contain this property's name and definition.
This function can find both attribute assignments as well as methods/functions.
Args:
property_name (str): the name of the property to look up in the template definition
Returns:
tuple: line numbers for the start and end of the attribute definition
"""
for node in ast.walk(ast.parse(self._source)):
if isinstance(node, ast.Assign) and node.targets[0].id == property_name:
return node.targets[0].lineno - 1, self._get_node_line_end(node)
elif isinstance(node, ast.FunctionDef) and node.name == property_name:
return node.lineno - 1, self._get_node_line_end(node)
raise ValueError('The requested node could not be found.')
def visit_Assign(self, node):
# type: (ast.Assign) -> None
# The LHS gets the inferred type of the RHS.
# We do this post-traversal to let the type inference
# run on the children first.
self.generic_visit(node)
rhs_inferred_type = self._get_inferred_type_for_node(node.value)
if rhs_inferred_type is None:
# Special casing assignment to a string literal.
if isinstance(node.value, ast.Str):
rhs_inferred_type = StringLiteral(node.value.s)
self._set_inferred_type_for_node(node.value, rhs_inferred_type)
for t in node.targets:
if isinstance(t, ast.Name):
self._symbol_table.set_inferred_type(t.id, rhs_inferred_type)
self._set_inferred_type_for_node(node, rhs_inferred_type)
def get_version():
module_path = os.path.join(os.path.dirname(__file__), 'logging_spinner.py')
module_file = open(module_path)
try:
module_code = module_file.read()
finally:
module_file.close()
tree = ast.parse(module_code, module_path)
for node in ast.iter_child_nodes(tree):
if not isinstance(node, ast.Assign) or len(node.targets) != 1:
continue
target, = node.targets
if isinstance(target, ast.Name) and target.id == '__version__':
value = node.value
if isinstance(value, ast.Str):
return value.s
raise ValueError('__version__ is not defined as a string literal')
raise ValueError('could not find __version__')
def pop_format_context(self, expl_expr):
"""Format the %-formatted string with current format context.
The expl_expr should be an ast.Str instance constructed from
the %-placeholders created by .explanation_param(). This will
add the required code to format said string to .on_failure and
return the ast.Name instance of the formatted string.
"""
current = self.stack.pop()
if self.stack:
self.explanation_specifiers = self.stack[-1]
keys = [ast.Str(key) for key in current.keys()]
format_dict = ast.Dict(keys, list(current.values()))
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
name = "@py_format" + str(next(self.variable_counter))
self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
return ast.Name(name, ast.Load())
def get_version():
module_path = os.path.join(os.path.dirname(__file__),
'wikidata', '__init__.py')
module_file = open(module_path)
try:
module_code = module_file.read()
finally:
module_file.close()
tree = ast.parse(module_code, module_path)
for node in ast.iter_child_nodes(tree):
if not isinstance(node, ast.Assign) or len(node.targets) != 1:
continue
target, = node.targets
if isinstance(target, ast.Name) and target.id == '__version__':
value = node.value
if isinstance(value, ast.Str):
return value.s
raise ValueError('__version__ is not defined as a string literal')
raise ValueError('could not find __version__')
def pop_format_context(self, expl_expr):
"""Format the %-formatted string with current format context.
The expl_expr should be an ast.Str instance constructed from
the %-placeholders created by .explanation_param(). This will
add the required code to format said string to .on_failure and
return the ast.Name instance of the formatted string.
"""
current = self.stack.pop()
if self.stack:
self.explanation_specifiers = self.stack[-1]
keys = [ast.Str(key) for key in current.keys()]
format_dict = ast.Dict(keys, list(current.values()))
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
name = "@py_format" + str(next(self.variable_counter))
self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
return ast.Name(name, ast.Load())
def pop_format_context(self, expl_expr):
"""Format the %-formatted string with current format context.
The expl_expr should be an ast.Str instance constructed from
the %-placeholders created by .explanation_param(). This will
add the required code to format said string to .on_failure and
return the ast.Name instance of the formatted string.
"""
current = self.stack.pop()
if self.stack:
self.explanation_specifiers = self.stack[-1]
keys = [ast.Str(key) for key in current.keys()]
format_dict = ast.Dict(keys, list(current.values()))
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
name = "@py_format" + str(next(self.variable_counter))
self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
return ast.Name(name, ast.Load())
def replace_scalar_assign(defnode, namenode):
"""
search in defnode to see if namenode assigned as scalar before
if it's true, return the assigned str
"""
potential_assignnodes = py_ast.find_all(defnode, ast.Assign)
assignnodes = []
for potential_assignnode in potential_assignnodes:
try:
if len(potential_assignnode.targets) == 1:
if isinstance(potential_assignnode.targets[0], ast.Name):
if potential_assignnode.targets[0].id == namenode.id:
if is_before(potential_assignnode, namenode):
assignnodes.append(potential_assignnode)
except:
pass
if len(assignnodes) == 1:
return py_ast.dump_ast(assignnodes[0].value)
else:
raise ValueError
def get_info(filename):
info = {}
with open(filename) as _file:
data = ast.parse(_file.read())
for node in data.body:
if type(node) != ast.Assign:
continue
if type(node.value) not in [ast.Str, ast.Num]:
continue
name = None
for target in node.targets:
name = target.id
if type(node.value) == ast.Str:
info[name] = node.value.s
elif type(node.value) == ast.Num:
info[name] = node.value.n
return info
def get_coverable_nodes(cls):
return {
ast.Assert,
ast.Assign,
ast.AugAssign,
ast.Break,
ast.Continue,
ast.Delete,
ast.Expr,
ast.Global,
ast.Import,
ast.ImportFrom,
ast.Nonlocal,
ast.Pass,
ast.Raise,
ast.Return,
ast.FunctionDef,
ast.ClassDef,
ast.TryExcept,
ast.TryFinally,
ast.ExceptHandler,
ast.If,
ast.For,
ast.While,
}
def get_coverable_nodes(cls):
return {
ast.Assert,
ast.Assign,
ast.AugAssign,
ast.Break,
ast.Continue,
ast.Delete,
ast.Expr,
ast.Global,
ast.Import,
ast.ImportFrom,
ast.Nonlocal,
ast.Pass,
ast.Raise,
ast.Return,
ast.ClassDef,
ast.FunctionDef,
ast.Try,
ast.ExceptHandler,
ast.If,
ast.For,
ast.While,
}
def pop_format_context(self, expl_expr):
"""Format the %-formatted string with current format context.
The expl_expr should be an ast.Str instance constructed from
the %-placeholders created by .explanation_param(). This will
add the required code to format said string to .on_failure and
return the ast.Name instance of the formatted string.
"""
current = self.stack.pop()
if self.stack:
self.explanation_specifiers = self.stack[-1]
keys = [ast.Str(key) for key in current.keys()]
format_dict = ast.Dict(keys, list(current.values()))
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
name = "@py_format" + str(next(self.variable_counter))
self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
return ast.Name(name, ast.Load())
def get_init(self, filename="__init__.py"):
""" Get various info from the package without importing them
"""
import ast
with open(filename) as init_file:
module = ast.parse(init_file.read())
itr = lambda x: (ast.literal_eval(node.value) for node in ast.walk(module) \
if isinstance(node, ast.Assign) and node.targets[0].id == x)
try:
return next(itr("__author__")), \
next(itr("__email__")), \
next(itr("__license__")), \
next(itr("__version__"))
except StopIteration:
raise ValueError("One of author, email, license, or version"
" cannot be found in {}".format(filename))
def version():
path = 'pypika/__init__.py'
with open(path, 'rU') as file:
t = compile(file.read(), path, 'exec', ast.PyCF_ONLY_AST)
for node in (n for n in t.body if isinstance(n, ast.Assign)):
if len(node.targets) == 1:
name = node.targets[0]
if isinstance(name, ast.Name) and \
name.id in ('__version__', '__version_info__', 'VERSION'):
v = node.value
if isinstance(v, ast.Str):
return v.s
if isinstance(v, ast.Tuple):
r = []
for e in v.elts:
if isinstance(e, ast.Str):
r.append(e.s)
elif isinstance(e, ast.Num):
r.append(str(e.n))
return '.'.join(r)
def handle_Return(state, node, ctx, **_):
state_update = dict(returns_ctr=state.returns_ctr + 1)
new_nodes = [
ast.Assign(
targets=[ast.Name(id=ctx.return_var, ctx=ast.Store())],
value=node.value)]
if state.loop_nesting_ctr > 0:
new_nodes.append(
ast.Assign(
targets=[ast.Name(id=ctx.return_flag_var, ctx=ast.Store())],
value=TRUE_NODE))
state_update.update(return_inside_a_loop=True, returns_in_loops=True)
new_nodes.append(ast.Break())
return state.update(state_update), new_nodes
def remove_simple_assignments(node):
"""
Remove one assigment of the form `<variable> = <variable>` at a time,
touching only the top level statements of the block.
"""
remaining_nodes = list(node.body)
new_nodes = []
while len(remaining_nodes) > 0:
cur_node = remaining_nodes.pop(0)
if type(cur_node) == ast.Assign:
can_remove, dest_name, src_name = _can_remove_assignment(cur_node, remaining_nodes)
if can_remove:
remaining_nodes = replace_name(
remaining_nodes, ctx=dict(dest_name=dest_name, src_name=src_name))
else:
new_nodes.append(cur_node)
else:
new_nodes.append(cur_node)
if len(new_nodes) == len(node.body):
return node
return replace_fields(node, body=new_nodes)
def test_add_statement():
@ast_transformer
def add_statement(node, **kwds):
if isinstance(node, ast.Assign):
return [node, ast.parse("b = 2").body[0]]
else:
return node
node = get_ast(dummy)
new_node = check_mutation(node, add_statement)
assert_ast_equal(new_node, get_ast("""
def dummy(x, y):
c = 4
b = 2
a = 1
b = 2
"""))
def test_list_element():
"""
Tests the removal of an AST node that is an element of a list
referenced by a field of the parent node.
"""
@ast_transformer
def remove_list_element(node, **kwds):
if isinstance(node, ast.Assign) and node.targets[0].id == 'a':
return None
else:
return node
node = get_ast(dummy)
new_node = check_mutation(node, remove_list_element)
assert_ast_equal(new_node, get_ast("""
def dummy(x, y):
c = 4
"""))