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类If()的实例源码
def load_module(self, name):
# If there is an existing module object named 'fullname' in
# sys.modules, the loader must use that existing module. (Otherwise,
# the reload() builtin will not work correctly.)
if name in sys.modules:
return sys.modules[name]
co, pyc = self.modules.pop(name)
# I wish I could just call imp.load_compiled here, but __file__ has to
# be set properly. In Python 3.2+, this all would be handled correctly
# by load_compiled.
mod = sys.modules[name] = imp.new_module(name)
try:
mod.__file__ = co.co_filename
# Normally, this attribute is 3.2+.
mod.__cached__ = pyc
mod.__loader__ = self
py.builtin.exec_(co, mod.__dict__)
except:
del sys.modules[name]
raise
return sys.modules[name]
def basicTypeSpecialFunction(cv):
"""If you're in a number or string (which has no metadata), move up to the AST to make the special functions work."""
if isinstance(cv, SwapVector) or isinstance(cv, MoveVector):
return cv
if (cv.path[0] in [('n', 'Number'), ('s', 'String'), ('id', 'Name'), ('arg', 'Argument'),
('value', 'Name Constant'), ('s', 'Bytes'), ('name', 'Alias')]):
cvCopy = cv.deepcopy()
cv.oldSubtree = deepcopy(cvCopy.traverseTree(cv.start))
if cv.path[0] == ('n', 'Number'):
cv.newSubtree = ast.Num(cv.newSubtree)
elif cv.path[0] == ('s', 'String'):
cv.newSubtree = ast.Str(cv.newSubtree)
elif cv.path[0] == ('id', 'Name'):
cv.newSubtree = ast.Name(cv.newSubtree, cv.oldSubtree.ctx)
elif cv.path[0] == ('arg', 'Argument'):
cv.newSubtree = ast.arg(cv.newSubtree, cv.oldSubtree.annotation)
elif cv.path[0] == ('value', 'Name Constant'):
cv.newSubtree = ast.NameConstant(cv.newSubtree)
elif cv.path[0] == ('s', 'Bytes'):
cv.newSubtree = ast.Bytes(cv.newSubtree)
elif cv.path[0] == ('name', 'Alias'):
cv.newSubtree = ast.alias(cv.newSubtree, cv.oldSubtree.asname)
cv.path = cv.path[1:]
return cv
def combineConditionals(a):
"""When possible, combine conditional branches"""
if not isinstance(a, ast.AST):
return a
elif type(a) == ast.If:
for i in range(len(a.body)):
a.body[i] = combineConditionals(a.body[i])
for i in range(len(a.orelse)):
a.orelse[i] = combineConditionals(a.orelse[i])
# if a: if b: x can be - if a and b: x
if (len(a.orelse) == 0) and (len(a.body) == 1) and \
(type(a.body[0]) == ast.If) and (len(a.body[0].orelse) == 0):
a.test = ast.BoolOp(ast.And(combinedConditionalOp=True), [a.test, a.body[0].test], combinedConditional=True)
a.body = a.body[0].body
# if a: x elif b: x can be - if a or b: x
elif (len(a.orelse) == 1) and \
(type(a.orelse[0]) == ast.If) and (len(a.orelse[0].orelse) == 0):
if compareASTs(a.body, a.orelse[0].body, checkEquality=True) == 0:
a.test = ast.BoolOp(ast.Or(combinedConditionalOp=True), [a.test, a.orelse[0].test], combinedConditional=True)
a.orelse = []
return a
else:
return applyToChildren(a, combineConditionals)
def occursIn(sub, super):
"""Does the first AST occur as a subtree of the second?"""
superStatementTypes = [ ast.Module, ast.Interactive, ast.Suite,
ast.FunctionDef, ast.ClassDef, ast.For,
ast.While, ast.If, ast.With, ast.Try,
ast.ExceptHandler ]
if (not isinstance(super, ast.AST)):
return False
if type(sub) == type(super) and compareASTs(sub, super, checkEquality=True) == 0:
return True
# we know that a statement can never occur in an expression
# (or in a non-statement-holding statement), so cut the search off now to save time.
if isStatement(sub) and type(super) not in superStatementTypes:
return False
for child in ast.iter_child_nodes(super):
if occursIn(sub, child):
return True
return False
def _translate_if(self, test, orelse, body, location, base=True):
test_node = self._testable(self._translate_node(test))
block = self._translate_node(body)
#block [self._translate_node(child) for child in body]
if orelse and len(orelse) == 1 and isinstance(orelse[0], ast.If):
otherwise = self._translate_if(orelse[0].test, orelse[0].orelse, orelse[0].body, location, False)
elif orelse:
otherwise = {
'type': 'else_statement',
'block': self._translate_node(orelse),
#block [self._translate_node(node) for node in orelse],
'pseudo_type': 'Void'
}
else:
otherwise = None
return {
'type': 'if_statement' if base else 'elseif_statement',
'test': test_node,
'block': block,
'pseudo_type': 'Void',
'otherwise': otherwise
}
def remove_id_assignment(self, JOIN, cfg_node):
lvars = list()
if isinstance(cfg_node, BBorBInode):
lvars.append(cfg_node.left_hand_side)
else:
try:
for expr in cfg_node.ast_node.targets:
vv = VarsVisitor()
vv.visit(expr)
lvars.extend(vv.result)
except AttributeError: # If it is AugAssign
vv = VarsVisitor()
vv.visit(cfg_node.ast_node.target)
lvars.extend(vv.result)
for var in lvars:
if var in self.lattice.get_elements(JOIN):
# Remove var from JOIN
JOIN = JOIN ^ self.lattice.el2bv[var]
return JOIN
def add_vars_conditional(self, JOIN, cfg_node):
varse = None
if isinstance(cfg_node.ast_node, ast.While):
vv = VarsVisitor()
vv.visit(cfg_node.ast_node.test)
varse = vv.result
elif self.is_output(cfg_node):
vv = VarsVisitor()
vv.visit(cfg_node.ast_node)
varse = vv.result
elif isinstance(cfg_node.ast_node, ast.If):
vv = VarsVisitor()
vv.visit(cfg_node.ast_node.test)
varse = vv.result
for var in varse:
JOIN = JOIN | self.lattice.el2bv[var]
return JOIN
def get_con_configuration():
"""
Returns a tuple containing the currently active connection configuration.
The method uses the configuration name stored in the attribute
'current_server' to retrieve the configuration values from the
dictionary 'server_configuration'.
Returns
-------
tup : tuple or None
If there is a configuration for the currently selected server,
the method returns the tuple (db_host, db_port, db_name,
db_password). If no configuration is available, the method
returns None.
"""
if cfg.current_server in cfg.server_configuration:
d = cfg.server_configuration[cfg.current_server]
if d["type"] == SQL_MYSQL:
return (d["host"], d["port"], d["type"], d["user"], d["password"])
elif d["type"] == SQL_SQLITE:
return (None, None, SQL_SQLITE, None, None)
else:
return None
def get_resource(name, connection=None):
"""
Return a tuple containing the Resource, Corpus, and Lexicon of the
corpus module specified by 'name'.
Arguments
---------
name : str
The name of the corpus module
connection : str or None
The name of the database connection. If None, the current connection
is used.
Returns
-------
res : tuple
A tuple consisting of the Resource class, Corpus class, and Lexicon
class defined in the corpus module
"""
if not connection:
connection = cfg.current_server
Resource, Corpus, Lexicon, _ = get_available_resources(connection)[name]
return Resource, Corpus, Lexicon
def _If(self, t):
self.fill("if ")
self.dispatch(t.test)
self.enter()
self.dispatch(t.body)
self.leave()
# collapse nested ifs into equivalent elifs.
while (t.orelse and len(t.orelse) == 1 and
isinstance(t.orelse[0], ast.If)):
t = t.orelse[0]
self.fill("elif ")
self.dispatch(t.test)
self.enter()
self.dispatch(t.body)
self.leave()
# final else
if t.orelse:
self.fill("else")
self.enter()
self.dispatch(t.orelse)
self.leave()
def _UnaryOp(self, t):
self.write("(")
self.write(self.unop[t.op.__class__.__name__])
self.write(" ")
# If we're applying unary minus to a number, parenthesize the number.
# This is necessary: -2147483648 is different from -(2147483648) on
# a 32-bit machine (the first is an int, the second a long), and
# -7j is different from -(7j). (The first has real part 0.0, the second
# has real part -0.0.)
if isinstance(t.op, ast.USub) and isinstance(t.operand, ast.Num):
self.write("(")
self.dispatch(t.operand)
self.write(")")
else:
self.dispatch(t.operand)
self.write(")")
def load_module(self, name):
# If there is an existing module object named 'fullname' in
# sys.modules, the loader must use that existing module. (Otherwise,
# the reload() builtin will not work correctly.)
if name in sys.modules:
return sys.modules[name]
co, pyc = self.modules.pop(name)
# I wish I could just call imp.load_compiled here, but __file__ has to
# be set properly. In Python 3.2+, this all would be handled correctly
# by load_compiled.
mod = sys.modules[name] = imp.new_module(name)
try:
mod.__file__ = co.co_filename
# Normally, this attribute is 3.2+.
mod.__cached__ = pyc
mod.__loader__ = self
py.builtin.exec_(co, mod.__dict__)
except:
del sys.modules[name]
raise
return sys.modules[name]
def load_module(self, name):
# If there is an existing module object named 'fullname' in
# sys.modules, the loader must use that existing module. (Otherwise,
# the reload() builtin will not work correctly.)
if name in sys.modules:
return sys.modules[name]
co, pyc = self.modules.pop(name)
# I wish I could just call imp.load_compiled here, but __file__ has to
# be set properly. In Python 3.2+, this all would be handled correctly
# by load_compiled.
mod = sys.modules[name] = imp.new_module(name)
try:
mod.__file__ = co.co_filename
# Normally, this attribute is 3.2+.
mod.__cached__ = pyc
mod.__loader__ = self
py.builtin.exec_(co, mod.__dict__)
except:
del sys.modules[name]
raise
return sys.modules[name]
def load_module(self, name):
# If there is an existing module object named 'fullname' in
# sys.modules, the loader must use that existing module. (Otherwise,
# the reload() builtin will not work correctly.)
if name in sys.modules:
return sys.modules[name]
co, pyc = self.modules.pop(name)
# I wish I could just call imp.load_compiled here, but __file__ has to
# be set properly. In Python 3.2+, this all would be handled correctly
# by load_compiled.
mod = sys.modules[name] = imp.new_module(name)
try:
mod.__file__ = co.co_filename
# Normally, this attribute is 3.2+.
mod.__cached__ = pyc
mod.__loader__ = self
py.builtin.exec_(co, mod.__dict__)
except:
del sys.modules[name]
raise
return sys.modules[name]
def visit_If(self, node):
new_node = self._visit_if_while(node)
if new_node is not None:
return new_node
if node.orelse and is_empty_body(node.orelse):
self.log_node_removal("Remove dead code (empty else block of if)",
node.orelse)
new_node = copy_node(node)
del new_node.orelse[:]
node = new_node
if is_empty_body(node.body) and not is_empty_body(node.orelse):
self.log_node_removal("Remove dead code (empty if block)",
node.body)
new_node = copy_node(node)
not_test = ast.UnaryOp(op=ast.Not(), operand=node.test)
copy_lineno(node.test, not_test)
new_node = ast.If(test=not_test, body=new_node.orelse, orelse=[])
copy_lineno(node, new_node)
return new_node
return node
def _If(self, t):
self.fill("if ")
self.dispatch(t.test)
self.enter()
self.dispatch(t.body)
self.leave()
# collapse nested ifs into equivalent elifs.
while (t.orelse and len(t.orelse) == 1 and
(isinstance(t.orelse[0], ast.If) or isinstance(t.orelse[0], typed_ast.ast3.If))):
t = t.orelse[0]
self.fill("elif ")
self.dispatch(t.test)
self.enter()
self.dispatch(t.body)
self.leave()
# final else
if t.orelse:
self.fill("else")
self.enter()
self.dispatch(t.orelse)
self.leave()
def vars_defined_in_all_cases(self, node):
if isinstance(node, ast.If):
vars_defined = None
for if_node in u.ifs_in_elif_block(node):
cur_vars_defined = self.vars_defined_in_all_cases(if_node.body)
if vars_defined is None:
vars_defined = cur_vars_defined
else:
vars_defined = vars_defined & cur_vars_defined
elif isinstance(node, list):
vars_defined = set()
for stmt_node in node:
vars_defined = vars_defined | self.vars_defined_in_all_cases(stmt_node)
elif isinstance(node, ast.AST):
vars_defined = set()
if u.is_set_to(node):
vars_defined.add(node.value.func.value.id)
return vars_defined
def visit_If(self, ifstmt, is_nested=False):
if is_nested:
s = "} else if (%s) {\n" % (self.visit(ifstmt.test))
else:
s = "if (%s) {\n" % (self.visit(ifstmt.test))
s += self.visit_block(ifstmt.body)
if len(ifstmt.orelse) == 0:
s += "}\n"
else:
if len(ifstmt.orelse) == 1 and isinstance(ifstmt.orelse[0], ast.If):
s += self.visit_If(ifstmt.orelse[0], is_nested=True)
else:
s += "} else {\n"
s += self.visit_block(ifstmt.orelse)
s += "}\n"
return s
def get_compound_bodies(node):
"""Returns a list of bodies of a compound statement node.
Args:
node: AST node.
Returns:
A list of bodies of the node. If the given node does not represent
a compound statement, an empty list is returned.
"""
if isinstance(node, (ast.Module, ast.FunctionDef, ast.ClassDef, ast.With)):
return [node.body]
elif isinstance(node, (ast.If, ast.While, ast.For)):
return [node.body, node.orelse]
elif PY2 and isinstance(node, ast.TryFinally):
return [node.body, node.finalbody]
elif PY2 and isinstance(node, ast.TryExcept):
return [node.body, node.orelse] + [h.body for h in node.handlers]
elif PY3 and isinstance(node, ast.Try):
return ([node.body, node.orelse, node.finalbody]
+ [h.body for h in node.handlers])
end
return []
def runTest(self):
"""Makes a simple test of the output"""
body = ast.parse(self.candidate_code, self.file_name, 'exec')
code = compile(self.candidate_code, self.file_name, 'exec', optimize=0)
exec(code)
if_statements = [
node
for node in ast.walk(body)
if isinstance(node, ast.If)
]
self.assertGreater(len(if_statements),
0,
"Should have at least on if statement")
self.assertMultiLineEqual(self.correct_output,
self.__mockstdout.getvalue(),
"Output should be correct")
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 load_module(self, name):
# If there is an existing module object named 'fullname' in
# sys.modules, the loader must use that existing module. (Otherwise,
# the reload() builtin will not work correctly.)
if name in sys.modules:
return sys.modules[name]
co, pyc = self.modules.pop(name)
# I wish I could just call imp.load_compiled here, but __file__ has to
# be set properly. In Python 3.2+, this all would be handled correctly
# by load_compiled.
mod = sys.modules[name] = imp.new_module(name)
try:
mod.__file__ = co.co_filename
# Normally, this attribute is 3.2+.
mod.__cached__ = pyc
mod.__loader__ = self
py.builtin.exec_(co, mod.__dict__)
except:
del sys.modules[name]
raise
return sys.modules[name]
def visit_If(self, node, start=True):
if start:
self.startline('if (')
else:
self.write('if (')
self.visit(node.test)
self.write(') {\n')
self.visit_body(node.body)
self.startline()
self.endline('}')
# Treat the else or else if clauses
if node.orelse:
if len(node.orelse) == 1 and isinstance(node.orelse[0], ast.If):
self.startline('else ')
self.visit_If(node.orelse[0], False)
else:
self.startline('else {\n')
self.visit_body(node.orelse)
self.startline()
self.endline('}')
#
# Expressions
#
def _build_node_cfg(node):
handlers = {
ast.If: _build_if_cfg,
ast.For: _build_loop_cfg,
ast.While: _build_loop_cfg,
ast.With: _build_with_cfg,
ast.Break: _build_break_cfg,
ast.Continue: _build_continue_cfg,
ast.Return: _build_return_cfg,
ast.Try: _build_try_cfg,
}
if type(node) in handlers:
handler = handlers[type(node)]
else:
handler = _build_statement_cfg
return handler(node)
def test_block_autofix():
# This transformer removes If nodes from statement blocks,
# but it has no way to check whether the resulting body still has some nodes or not.
# That's why the walker adds a Pass node automatically if after all the transformations
# a statement block turns out to be empty.
@ast_transformer
def delete_ifs(node, **kwds):
if isinstance(node, ast.If):
return None
else:
return node
node = get_ast(dummy_if)
new_node = delete_ifs(node)
assert_ast_equal(new_node, get_ast(
"""
def dummy_if():
pass
"""))
def translate(self, ctx):
translation = []
scrutinee = ast.Name(id="__typy_with_scrutinee__")
translation.extend(
self.body_block.translate_assign(
ctx, scrutinee))
pat = self.pat
ctx_update = pat.ctx_update
condition, binding_translations = ctx.translate_pat(pat, scrutinee)
if astx.cond_vacuously_true(condition):
for (id, trans) in binding_translations.iteritems():
translation.append(ast.Assign(
targets=[ast.Name(id=ctx_update[id][0])],
value=trans))
else:
translation.append(ast.If(
test=condition,
body=list(_yield_binding_translation_assignments(
binding_translations, ctx_update)),
orelse=astx.expr_Raise_Exception_string("Match failure.")))
return translation
def make_if(kwd, test, then, *rest):
# (This'd be simpler with a different form of the grammar.)
test = test(ast.Load())
if not rest: else_ = []
elif len(rest) == 1: else_ = rest[0]
else: else_ = [make_if(*rest)]
return ast.If(test, then, else_,
lineno=kwd.start[0],
col_offset=kwd.start[1])
def visit_Assert(self, t):
return ast.If(t.test,
[],
[ast.Raise(Call(ast.Name('AssertionError', load),
[] if t.msg is None else [t.msg]),
None)])