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
python类Not()的实例源码
def visit_UnaryOp(self, node):
if not self.config.constant_folding:
return
eval_unaryop = EVAL_UNARYOP.get(node.op.__class__)
if eval_unaryop is None:
return
if isinstance(node.op, ast.Invert):
types = int
else:
types = COMPLEX_TYPES
value = get_constant(node.operand, types=types)
if value is not UNSET:
result = eval_unaryop(value)
return self.new_constant(node, result)
if (isinstance(node.op, ast.Not)
and isinstance(node.operand, ast.Compare)):
new_node = self.not_compare(node)
if new_node is not None:
return new_node
def infer_unary_operation(node, context, solver):
"""Infer the type for unary operations
Examples: -5, not 1, ~2
"""
unary_type = infer(node.operand, context, solver)
if isinstance(node.op, ast.Not): # (not expr) always gives bool type
return solver.z3_types.bool
if isinstance(node.op, ast.Invert):
solver.add(axioms.unary_invert(unary_type, solver.z3_types),
fail_message="Invert operation in line {}".format(node.lineno))
return solver.z3_types.int
else:
result_type = solver.new_z3_const("unary_result")
solver.add(axioms.unary_other(unary_type, result_type, solver.z3_types),
fail_message="Unary operation in line {}".format(node.lineno))
return result_type
def __init__(self):
super().__init__()
# add support for bitwise operators
if ast.LShift not in self.MATH_OPERATORS: # '<<'
self.MATH_OPERATORS[ast.LShift] = simpleeval.op.lshift
if ast.RShift not in self.MATH_OPERATORS: # '>>'
self.MATH_OPERATORS[ast.RShift] = simpleeval.op.rshift
if ast.BitOr not in self.MATH_OPERATORS: # '|'
self.MATH_OPERATORS[ast.BitOr] = simpleeval.op.or_
if ast.BitXor not in self.MATH_OPERATORS: # '^'
self.MATH_OPERATORS[ast.BitXor] = simpleeval.op.xor
if ast.BitAnd not in self.MATH_OPERATORS: # '&'
self.MATH_OPERATORS[ast.BitAnd] = simpleeval.op.and_
# add support for extra operators
#if ast.Not not in self.MATH_OPERATORS: # not ('not')
# self.MATH_OPERATORS[ast.Not] = simpleeval.op.not_
if ast.FloorDiv not in self.MATH_OPERATORS: # floordiv ('//')
self.MATH_OPERATORS[ast.FloorDiv] = simpleeval.op.floordiv
def check_identifier(self, name):
assert isinstance(name, str), "An identifier must be a string: %r" % (name,)
# Not a private, mangled name:
# XXX also make sure there's no '.' inside (the compiler will add some sometimes)
assert len(name) <= 2 or not name.startswith('__') or name.endswith('__'), \
"Mangled private names are not supported: %r" % (name,)
def unary_operations(self):
operand = Expr.parse_value_expr(self.expr.operand, self.context)
if isinstance(self.expr.op, ast.Not):
# Note that in the case of bool, num, address, decimal, num256 AND bytes32,
# a zero entry represents false, all others represent true
return LLLnode.from_list(["iszero", operand], typ='bool', pos=getpos(self.expr))
elif isinstance(self.expr.op, ast.USub):
if not is_numeric_type(operand.typ):
raise TypeMismatchException("Unsupported type for negation: %r" % operand.typ, operand)
return LLLnode.from_list(["sub", 0, operand], typ=operand.typ, pos=getpos(self.expr))
else:
raise StructureException("Only the 'not' unary operator is supported")
# Function calls
def visit_BoolOp(self, boolop):
res_var = self.variable()
expl_list = self.assign(ast.List([], ast.Load()))
app = ast.Attribute(expl_list, "append", ast.Load())
is_or = int(isinstance(boolop.op, ast.Or))
body = save = self.statements
fail_save = self.on_failure
levels = len(boolop.values) - 1
self.push_format_context()
# Process each operand, short-circuting if needed.
for i, v in enumerate(boolop.values):
if i:
fail_inner = []
# cond is set in a prior loop iteration below
self.on_failure.append(ast.If(cond, fail_inner, [])) # noqa
self.on_failure = fail_inner
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
expl_format = self.pop_format_context(ast.Str(expl))
call = ast_Call(app, [expl_format], [])
self.on_failure.append(ast.Expr(call))
if i < levels:
cond = res
if is_or:
cond = ast.UnaryOp(ast.Not(), cond)
inner = []
self.statements.append(ast.If(cond, inner, []))
self.statements = body = inner
self.statements = save
self.on_failure = fail_save
expl_template = self.helper("format_boolop", expl_list, ast.Num(is_or))
expl = self.pop_format_context(expl_template)
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
def visit_If(self, node):
node = self.generic_visit(node)
if (node.orelse
and len(node.orelse) == 1
and isinstance(node.orelse[0], ast.Pass)
):
node.orelse = []
if (len(node.body) == 1
and isinstance(node.body[0], ast.Pass)
):
if node.orelse:
node_test = ast.UnaryOp(op=ast.Not(), operand=node.test)
if (len(node.orelse) == 1
and isinstance(node.orelse[0], ast.If)
):
node_test = ast.BoolOp\
( op = ast.And()
, values = [node_test, node.orelse[0].test]
)
node.test = ast.copy_location(node_test, node.orelse[0].test)
node.body = node.orelse[0].body
node.orelse = node.orelse[0].orelse
else:
node.test = ast.copy_location(node_test, node.test)
node.body = node.orelse
node.orelse = []
else:
node = None
return node
def diffLists(x, y, ignoreVariables=False):
mapSet = matchLists(x, y)
changeVectors = []
# First, get all the added and deleted lines
deletedLines = mapSet[-1] if -1 in mapSet else []
for line in sorted(deletedLines):
changeVectors.append(DeleteVector([line], x[line], None))
addedLines = list(filter(lambda tmp : mapSet[tmp] == -1, mapSet.keys()))
addedOffset = 0 # Because added lines don't start in the list, we need
# to offset their positions for each new one that's added
for line in sorted(addedLines):
changeVectors.append(AddVector([line - addedOffset], None, y[line]))
addedOffset += 1
# Now, find all the required moves
changeVectors += findMoveVectors(mapSet, x, y, addedLines, deletedLines)
# Finally, for each pair of lines (which have already been moved appropriately,
# find if they need a normal ChangeVector
for j in mapSet:
i = mapSet[j]
# Not a delete or an add
if j != -1 and i != -1:
tempVectors = diffAsts(x[i], y[j], ignoreVariables=ignoreVariables)
for change in tempVectors:
change.path.append(i)
changeVectors += tempVectors
return changeVectors
def isNegation(a, b):
"""Is a the negation of b?"""
return compareASTs(deMorganize(ast.UnaryOp(ast.Not(), deepcopy(a))), b, checkEquality=True) == 0
def doUnaryOp(op, val):
"""Perform the given AST unary operation on the value"""
top = type(op)
if top == ast.Invert:
return ~ val
elif top == ast.Not:
return not val
elif top == ast.UAdd:
return val
elif top == ast.USub:
return -val
def _translate_unaryop(self, operand, op, location):
value = operand
if isinstance(op, ast.USub):
value_node = self._translate_node(value)
if value_node['pseudo_type'] != 'Int' and value_node['pseudo_type'] != 'Float':
raise type_check_error('- expects Int or Float',
location, self.lines[location[0]],
wrong_type=value_node['pseudo_type'])
if value_node['type'] == 'int':
return {
'type': 'int',
'value': -value_node['value'],
'pseudo_type': 'Int'
}
else:
return {
'type': 'unary_op',
'op': '-',
'value': value_node,
'pseudo_type': value_node['pseudo_type']
}
elif isinstance(op, ast.Not):
value_node = self._testable(self._translate_node(value))
if value_node['type'] == 'standard_method_call' and value_node['message'] == 'present?':
value_node['message'] = 'empty?'
return value_node
else:
return {
'type': 'unary_op',
'op': 'not',
'value': value_node,
'pseudo_type': 'Boolean'
}
else:
raise translation_error('no support for %s as an unary op' % type(op).__name__,
location, self.lines[location[0]],
suggestions='not and - are supported')
def generate_unaryop(self, node, ext_info):
if isinstance(node.op, ast.Not):
return '! ' + self.dispatch(node.operand, ext_info)
else:
SyntaxNotSupportError("%s is not support yet" % node.op.__class__.__name__)
def visit_BoolOp(self, boolop):
res_var = self.variable()
expl_list = self.assign(ast.List([], ast.Load()))
app = ast.Attribute(expl_list, "append", ast.Load())
is_or = int(isinstance(boolop.op, ast.Or))
body = save = self.statements
fail_save = self.on_failure
levels = len(boolop.values) - 1
self.push_format_context()
# Process each operand, short-circuting if needed.
for i, v in enumerate(boolop.values):
if i:
fail_inner = []
# cond is set in a prior loop iteration below
self.on_failure.append(ast.If(cond, fail_inner, [])) # noqa
self.on_failure = fail_inner
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
expl_format = self.pop_format_context(ast.Str(expl))
call = ast_Call(app, [expl_format], [])
self.on_failure.append(ast.Expr(call))
if i < levels:
cond = res
if is_or:
cond = ast.UnaryOp(ast.Not(), cond)
inner = []
self.statements.append(ast.If(cond, inner, []))
self.statements = body = inner
self.statements = save
self.on_failure = fail_save
expl_template = self.helper("format_boolop", expl_list, ast.Num(is_or))
expl = self.pop_format_context(expl_template)
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
def _safe_eval(node, default):
"""
Safely evaluate the Boolean expression under the given AST node.
Substitute `default` for all sub-expressions that cannot be
evaluated (because variables or functions are undefined).
We could use eval() to evaluate more sub-expressions. However, this
function is not safe for arbitrary Python code. Even after
overwriting the "__builtins__" dictionary, the original dictionary
can be restored
(https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html).
"""
if isinstance(node, ast.BoolOp):
results = [_safe_eval(value, default) for value in node.values]
if isinstance(node.op, ast.And):
return all(results)
else:
return any(results)
elif isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.Not):
return not _safe_eval(node.operand, not default)
else:
try:
return ast.literal_eval(node)
except ValueError:
return default
def visit_BoolOp(self, boolop):
res_var = self.variable()
expl_list = self.assign(ast.List([], ast.Load()))
app = ast.Attribute(expl_list, "append", ast.Load())
is_or = int(isinstance(boolop.op, ast.Or))
body = save = self.statements
fail_save = self.on_failure
levels = len(boolop.values) - 1
self.push_format_context()
# Process each operand, short-circuting if needed.
for i, v in enumerate(boolop.values):
if i:
fail_inner = []
# cond is set in a prior loop iteration below
self.on_failure.append(ast.If(cond, fail_inner, [])) # noqa
self.on_failure = fail_inner
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
expl_format = self.pop_format_context(ast.Str(expl))
call = ast_Call(app, [expl_format], [])
self.on_failure.append(ast.Expr(call))
if i < levels:
cond = res
if is_or:
cond = ast.UnaryOp(ast.Not(), cond)
inner = []
self.statements.append(ast.If(cond, inner, []))
self.statements = body = inner
self.statements = save
self.on_failure = fail_save
expl_template = self.helper("format_boolop", expl_list, ast.Num(is_or))
expl = self.pop_format_context(expl_template)
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
def visit_BoolOp(self, boolop):
res_var = self.variable()
expl_list = self.assign(ast.List([], ast.Load()))
app = ast.Attribute(expl_list, "append", ast.Load())
is_or = int(isinstance(boolop.op, ast.Or))
body = save = self.statements
fail_save = self.on_failure
levels = len(boolop.values) - 1
self.push_format_context()
# Process each operand, short-circuting if needed.
for i, v in enumerate(boolop.values):
if i:
fail_inner = []
# cond is set in a prior loop iteration below
self.on_failure.append(ast.If(cond, fail_inner, [])) # noqa
self.on_failure = fail_inner
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
expl_format = self.pop_format_context(ast.Str(expl))
call = ast_Call(app, [expl_format], [])
self.on_failure.append(ast.Expr(call))
if i < levels:
cond = res
if is_or:
cond = ast.UnaryOp(ast.Not(), cond)
inner = []
self.statements.append(ast.If(cond, inner, []))
self.statements = body = inner
self.statements = save
self.on_failure = fail_save
expl_template = self.helper("format_boolop", expl_list, ast.Num(is_or))
expl = self.pop_format_context(expl_template)
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
pytables.py 文件源码
项目:PyDataLondon29-EmbarrassinglyParallelDAWithAWSLambda
作者: SignalMedia
项目源码
文件源码
阅读 35
收藏 0
点赞 0
评论 0
def visit_UnaryOp(self, node, **kwargs):
if isinstance(node.op, (ast.Not, ast.Invert)):
return UnaryOp('~', self.visit(node.operand))
elif isinstance(node.op, ast.USub):
return self.const_type(-self.visit(node.operand).value, self.env)
elif isinstance(node.op, ast.UAdd):
raise NotImplementedError('Unary addition not supported')
def rewrite_expr_z3(r, is_py_ast=True):
# Rewrites py_ast expression to a str expression that could be used in z3
# Return (z3_expr_str, z3_varnames)
z3_expr_str = (py_ast.dump_ast(r) if is_py_ast else r).strip()
z3_expr_str = z3_expr_str.replace('.', '_').replace('[', '_').replace(']', '_')
rp = py_ast.get_ast(z3_expr_str).body[0].value
for node in py_ast.find_all(rp, ast.UnaryOp):
if isinstance(node.op, ast.Not):
if rp == node:
rp = py_ast.get_ast('z3.Not(' + py_ast.dump_ast(node.operand) + ')').body[0].value
else:
py_ast.replace_node(rp, node, py_ast.get_ast('z3.Not(' + py_ast.dump_ast(node.operand) + ')').body[0].value)
for node in py_ast.find_all(rp, ast.BoolOp):
if isinstance(node.op, ast.And):
if rp == node:
rp = py_ast.get_ast('z3.And(' + py_ast.dump_ast(node.values[0]) + ',' + py_ast.dump_ast(node.values[1]) + ')')
else:
py_ast.replace_node(rp, node, py_ast.get_ast('z3.And(' + py_ast.dump_ast(node.values[0]) + ',' + py_ast.dump_ast(node.values[1]) + ')'))
elif isinstance(node.op, ast.Or):
if rp == node:
rp = py_ast.get_ast('z3.Or(' + py_ast.dump_ast(node.values[0]) + ',' + py_ast.dump_ast(node.values[1]) + ')')
else:
py_ast.replace_node(rp, node, py_ast.get_ast('z3.Or(' + py_ast.dump_ast(node.values[0]) + ',' + py_ast.dump_ast(node.values[1]) + ')'))
z3_expr_str = py_ast.dump_ast(rp)
z3_vars = set()
for node in py_ast.find_all(rp, ast.Name):
z3_vars.add(node.id)
return (z3_expr_str, z3_vars)
def unop_str(op: ast.AST) -> str:
if isinstance(op, ast.UAdd):
return '+'
if isinstance(op, ast.USub):
return '-'
if isinstance(op, ast.Not):
return '!'
if isinstance(op, ast.Invert):
return '~'
error(loc(op), "Invalid unary operator encountered: {0}:{1}. Check supported intrinsics.".format(op.lineno, op.col_offset))
return 'INVALID_UNOP'
def visit_UnaryOp(self, node):
term = self.visit(node.operand)
if self.__is_bool(term):
if isinstance(node.op, ast.Not):
return Not(term)
elif isinstance(node.op, ast.Invert):
return Not(term)
else:
raise Exception("Unsupported bool unary operation %s" % unparse(node))
if DATA_TYPE == "int":
if isinstance(node.op, ast.USub):
return -term
elif isinstance(node.op, ast.Not):
if is_is_int(term):
term = term == IntVal(1)
return Not(term)
else:
raise Exception("Unsupported integer unary operation %s" % unparse(node))
elif DATA_TYPE.startswith("bit_"):
if isinstance(node.op, ast.Not):
return ~term
elif isinstance(node.op, ast.Invert):
return ~term
else:
raise Exception("Unsupported bitvector unary operation %s" % unparse(node))
else:
raise Exception("Unsupported unary operation %s" % unparse(node))
def visit_Compare(self, node):
left_term = self.visit(node.left)
if len(node.comparators) > 1:
raise Exception("Cannot handle 'foo > bar > baz' comparison in %s"
% unparse(node))
right_term = self.visit(node.comparators[0])
op = node.ops[0]
if isinstance(op, ast.Eq):
if self.__is_bool(left_term) and self.__is_bool(right_term):
if left_term == True:
return right_term
elif right_term == True:
return left_term
elif left_term == False:
return Not(right_term)
elif right_term == False:
return Not(left_term)
return left_term == right_term
elif isinstance(op, ast.Lt):
return left_term < right_term
elif isinstance(op, ast.LtE):
return left_term <= right_term
elif isinstance(op, ast.Gt):
return left_term > right_term
elif isinstance(op, ast.GtE):
return left_term >= right_term
else:
raise Exception("Unhandled operators '%s' in %s"
% (unparse(op), unparse(node)))
def visit_If(self, if_node):
exprVisitor = ToZ3ExprVisitor(env=self.__env)
test_term = exprVisitor.visit(if_node.test)
then_constraints = list(itertools.chain.from_iterable([
self.visit(stmt) for stmt in if_node.body]))
else_constraints = list(itertools.chain.from_iterable([
self.visit(stmt) for stmt in if_node.orelse]))
then_constraint = then_constraints[0] if len(then_constraints) == 1 else And(then_constraints)
else_constraint = else_constraints[0] if len(else_constraints) == 1 else And(else_constraints)
if len(else_constraints) == 0:
return [Implies(test_term, then_constraint)]
else:
return [Implies(test_term, then_constraint),
Implies(Not(test_term), else_constraint)]
def Not(self):
c = criteria_class.instance(Const.Not, self._pop())
self._push(c)
return self
def __init__(self, one):
if not isinstance(one, Criteria):
raise TypeError("%s is not supported" % type(one))
super(Not, self).__init__(stack=False)
self._one = one
def visit_UnaryOp(self, node):
if type(node.op) not in (ast.Not,):
raise SyntaxError("%s is not supported" % type(node.op))
self.visit(node.operand)
obj = self.data.pop()
criteria = obj if isinstance(obj, Criteria) else criteria_class.instance(Const.Bool, obj)
cls = criteria_class.lookup(ast_op_to_criteria.lookup(type(node.op)))
criteria = cls(criteria)
self.data.append(criteria)
def negate_test(self, node):
not_node = ast.UnaryOp(op=ast.Not(), operand=node.test)
node.test = not_node
return node
def visit_BoolOp(self, boolop):
res_var = self.variable()
expl_list = self.assign(ast.List([], ast.Load()))
app = ast.Attribute(expl_list, "append", ast.Load())
is_or = int(isinstance(boolop.op, ast.Or))
body = save = self.statements
fail_save = self.on_failure
levels = len(boolop.values) - 1
self.push_format_context()
# Process each operand, short-circuting if needed.
for i, v in enumerate(boolop.values):
if i:
fail_inner = []
# cond is set in a prior loop iteration below
self.on_failure.append(ast.If(cond, fail_inner, [])) # noqa
self.on_failure = fail_inner
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
expl_format = self.pop_format_context(ast.Str(expl))
call = ast_Call(app, [expl_format], [])
self.on_failure.append(ast.Expr(call))
if i < levels:
cond = res
if is_or:
cond = ast.UnaryOp(ast.Not(), cond)
inner = []
self.statements.append(ast.If(cond, inner, []))
self.statements = body = inner
self.statements = save
self.on_failure = fail_save
expl_template = self.helper("format_boolop", expl_list, ast.Num(is_or))
expl = self.pop_format_context(expl_template)
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
def syn_UnaryOp(self, ctx, e):
if isinstance(e.op, ast.Not):
return self
else:
raise _errors.TyError(
"""Type bool does not support this unary operator.""",
e)
def translate_pat_Name_constructor(self, ctx, pat, scrutinee):
id = pat.id
if id == "True":
return (scrutinee, typy.odict())
elif id == "False":
return (ast.UnaryOp(op=ast.Not(), operand=scrutinee), typy.odict())