def __init__(self, expr, context):
self.expr = expr
self.context = context
self.expr_table = {
LLLnode: self.get_expr,
ast.Num: self.number,
ast.Str: self.string,
ast.NameConstant: self.constants,
ast.Name: self.variables,
ast.Attribute: self.attribute,
ast.Subscript: self.subscript,
ast.BinOp: self.arithmetic,
ast.Compare: self.compare,
ast.BoolOp: self.boolean_operations,
ast.UnaryOp: self.unary_operations,
ast.Call: self.call,
ast.List: self.list_literals,
ast.Dict: self.struct_literals,
ast.Tuple: self.tuple_literals,
}
expr_type = self.expr.__class__
if expr_type in self.expr_table:
self.lll_node = self.expr_table[expr_type]()
else:
raise Exception("Unsupported operator: %r" % ast.dump(self.expr))
python类Compare()的实例源码
def simplify_multicomp(a):
if type(a) == ast.Compare and len(a.ops) > 1:
# Only do one comparator at a time. If we don't do this, things get messy!
comps = [a.left] + a.comparators
values = [ ]
# Compare each of the pairs
for i in range(len(a.ops)):
if i > 0:
# Label all nodes as middle parts so we can recognize them later
assignPropertyToAll(comps[i], "multiCompMiddle")
values.append(ast.Compare(comps[i], [a.ops[i]], [deepcopy(comps[i+1])], multiCompPart=True))
# Combine comparisons with and operators
boolOp = ast.And(multiCompOp=True)
boolopVal = ast.BoolOp(boolOp, values, multiComp=True, global_id=a.global_id)
return boolopVal
return a
def visit_If(self, node):
"""
If(expr test, stmt* body, stmt* orelse)
"""
if isinstance(node.test, (ast.NameConstant, ast.Compare)):
self.write("if %s" % self.visit(node.test))
else:
self.write("if is_bool(%s)" % self.visit(node.test))
self.indent()
for stmt in node.body:
self.visit(stmt)
self.dedent()
if node.orelse:
self.write("else")
self.indent()
for stmt in node.orelse:
self.visit(stmt)
self.dedent()
self.write("end")
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
expr.py 文件源码
项目:PyDataLondon29-EmbarrassinglyParallelDAWithAWSLambda
作者: SignalMedia
项目源码
文件源码
阅读 40
收藏 0
点赞 0
评论 0
def visit_Compare(self, node, **kwargs):
ops = node.ops
comps = node.comparators
# base case: we have something like a CMP b
if len(comps) == 1:
op = self.translate_In(ops[0])
binop = ast.BinOp(op=op, left=node.left, right=comps[0])
return self.visit(binop)
# recursive case: we have a chained comparison, a CMP b CMP c, etc.
left = node.left
values = []
for op, comp in zip(ops, comps):
new_node = self.visit(ast.Compare(comparators=[comp], left=left,
ops=[self.translate_In(op)]))
left = comp
values.append(new_node)
return self.visit(ast.BoolOp(op=ast.And(), values=values))
def make_op_name_dict(self):
'''
Make a dict whose keys are operators ('+', '+=', etc),
and whose values are lists of values of ast.Node.__class__.__name__.
'''
d = {
'.': ['Attr',],
'(*)': ['Call', 'Tuple',],
'[*]': ['List', 'Subscript',],
'{*}': ['???',],
### 'and': 'BoolOp',
### 'or': 'BoolOp',
}
for op in (
'+', '-', '*', '/', '%', '**', '<<',
'>>', '|', '^', '&', '//',
):
d[op] = ['BinOp',]
for op in (
'==', '!=', '<', '<=', '>', '>=',
'is', 'is not', 'in', 'not in',
):
d[op] = ['Compare',]
return d
def make_switch_group(if_node, parent_case):
cases_ast = u.if_and_or_else_blocks(if_node)
switch_group = SwitchGroup(None, parent_case.num_switch_groups())
switch_group.set_parent_case(parent_case)
switch_group.var_name = None
for if_node in cases_ast:
compare_node = u.cast(if_node.test, ast.Compare)
var_name, val = u.parse_compare(compare_node)
if switch_group.var_name is None:
switch_group.var_name = var_name
else:
assert var_name == switch_group.var_name, "if blocks must switch on same var"
case_node = make_case_node(if_node.body, var_name, val)
switch_group.add_case(val, case_node)
return switch_group
def normalize_compare(node):
"""Rewrites a compare expression to a `and` expression
1 < 2 < 3 > 0
1 < 2 and 2 < 3 and 3 > 0"""
and_values = []
left = node.left
for (op, val) in zip(node.ops, node.comparators):
comp = ast.Compare(ops=[op],
left=left,
comparators=[val],
lineno=node.lineno,
col_offset=node.col_offset)
and_values.append(comp)
left = val
return ast.BoolOp(op=ast.And(),
values=and_values,
lineno=node.lineno,
col_offset=node.col_offset)
def translate_pat_Call_constructor(self, ctx, pat, scrutinee_trans):
lbl = pat.func.id
tag_loc = ast.Subscript(
value=scrutinee_trans,
slice=ast.Index(value=ast.Num(n=0)))
lbl_condition = ast.Compare(
left=tag_loc,
ops=[ast.Eq()],
comparators=[ast.Str(s=lbl)])
arg = pat.args[0]
arg_scrutinee = ast.Subscript(
value=scrutinee_trans,
slice=ast.Index(value=ast.Num(n=1)))
arg_condition, binding_translations = ctx.translate_pat(arg, arg_scrutinee)
condition = ast.BoolOp(
op=ast.And(),
values=[lbl_condition, arg_condition])
return condition, binding_translations
def visit_Name(self, name):
# Display the repr of the name if it's a local variable or
# _should_repr_global_name() thinks it's acceptable.
locs = ast_Call(self.builtin("locals"), [], [])
inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs])
dorepr = self.helper("should_repr_global_name", name)
test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
expr = ast.IfExp(test, self.display(name), ast.Str(name.id))
return name, self.explanation_param(expr)
def visit_Compare(self, comp):
self.push_format_context()
left_res, left_expl = self.visit(comp.left)
if isinstance(comp.left, (_ast.Compare, _ast.BoolOp)):
left_expl = "({0})".format(left_expl)
res_variables = [self.variable() for i in range(len(comp.ops))]
load_names = [ast.Name(v, ast.Load()) for v in res_variables]
store_names = [ast.Name(v, ast.Store()) for v in res_variables]
it = zip(range(len(comp.ops)), comp.ops, comp.comparators)
expls = []
syms = []
results = [left_res]
for i, op, next_operand in it:
next_res, next_expl = self.visit(next_operand)
if isinstance(next_operand, (_ast.Compare, _ast.BoolOp)):
next_expl = "({0})".format(next_expl)
results.append(next_res)
sym = binop_map[op.__class__]
syms.append(ast.Str(sym))
expl = "%s %s %s" % (left_expl, sym, next_expl)
expls.append(ast.Str(expl))
res_expr = ast.Compare(left_res, [op], [next_res])
self.statements.append(ast.Assign([store_names[i]], res_expr))
left_res, left_expl = next_res, next_expl
# Use pytest.assertion.util._reprcompare if that's available.
expl_call = self.helper("call_reprcompare",
ast.Tuple(syms, ast.Load()),
ast.Tuple(load_names, ast.Load()),
ast.Tuple(expls, ast.Load()),
ast.Tuple(results, ast.Load()))
if len(comp.ops) > 1:
res = ast.BoolOp(ast.And(), load_names)
else:
res = load_names[0]
return res, self.explanation_param(self.pop_format_context(expl_call))
def cleanupEquals(a):
"""Gets rid of silly blah == True statements that students make"""
if not isinstance(a, ast.AST):
return a
if type(a) == ast.Call:
a.func = cleanupEquals(a.func)
for i in range(len(a.args)):
# But test expressions don't carry through to function arguments
a.args[i] = cleanupEquals(a.args[i])
return a
elif type(a) == ast.Compare and type(a.ops[0]) in [ast.Eq, ast.NotEq]:
l = a.left = cleanupEquals(a.left)
r = cleanupEquals(a.comparators[0])
a.comparators = [r]
if type(l) == ast.NameConstant and l.value in [True, False]:
(l,r) = (r,l)
# If we have (boolean expression) == True
if type(r) == ast.NameConstant and r.value in [True, False] and (eventualType(l) == bool):
# Matching types
if (type(a.ops[0]) == ast.Eq and r.value == True) or \
(type(a.ops[0]) == ast.NotEq and r.value == False):
transferMetaData(a, l) # make sure to keep the original location
return l
else:
tmp = ast.UnaryOp(ast.Not(addedNotOp=True), l)
transferMetaData(a, tmp)
return tmp
else:
return a
else:
return applyToChildren(a, cleanupEquals)
def visit_IfExp(self, node):
"""
IfExp(expr test, expr body, expr orelse)
"""
body = self.visit(node.body)
or_else = self.visit(node.orelse)
if isinstance(node.test, (ast.NameConstant, ast.Compare)):
return "(%s) ? %s : %s" % (self.visit(node.test), body, or_else)
else:
return "is_bool(%s) ? %s : %s" % (self.visit(node.test), body, or_else)
def visit_Compare(self, node):
"""
Compare(expr left, cmpop* ops, expr* comparators)
"""
assert len(node.ops) == len(node.comparators)
def compare_pair(left, comp, op):
if (left == '__name__') and (comp == '"__main__"') or \
(left == '"__main__"') and (comp == '__name__'):
""" <Python> __name__ == '__main__':
<Ruby> __FILE__ == $0 """
left = '__FILE__'
comp = '$0'
if isinstance(op, ast.In):
return "%s.include?(%s)" % (comp, left)
elif isinstance(op, ast.NotIn):
return "!%s.include?(%s)" % (comp, left)
elif isinstance(op, ast.Eq):
return "%s == %s" % (left, comp)
elif isinstance(op, ast.NotEq):
return "%s != %s" % (left, comp)
elif isinstance(op, ast.IsNot):
return "!%s.equal?(%s)" % (left, comp)
else:
return "%s %s %s" % (left, self.get_comparison_op(op), comp)
compare_list = []
for i in range(len(node.ops)):
if i == 0:
left = self.visit(node.left)
else:
left = comp
comp = self.visit(node.comparators[i])
op = node.ops[i]
pair = compare_pair(left, comp, op)
if len(node.ops) == 1:
return pair
compare_list.append('(' + pair + ')')
return ' and '.join(compare_list)
# python 3
def _binop(self, other, *, _opnode=opnode, _sym=sym):
othername, other, constants = _normalize_arg(
other,
self._constants,
)
return __class__(
'%s %s %s' % (self._pname, _sym, othername),
ast.Compare(
left=self._tree,
ops=[_opnode()],
comparators=[other],
),
merge(constants, getattr(other, '_constants', {})),
)
def visit_Assert(self, node):
if isinstance(node.test, ast.Compare) and \
len(node.test.ops) == 1 and \
isinstance(node.test.ops[0], ast.Eq):
call = ast.Call(func=ast.Name(id='assert_equal', ctx=ast.Load()),
args=[node.test.left, node.test.comparators[0]],
keywords=[])
# Wrap the call in an Expr node, because the return value isn't used.
newnode = ast.Expr(value=call)
ast.copy_location(newnode, node)
ast.fix_missing_locations(newnode)
return newnode
# Return the original node if we don't want to change it.
return node
def visit_Name(self, name):
# Display the repr of the name if it's a local variable or
# _should_repr_global_name() thinks it's acceptable.
locs = ast_Call(self.builtin("locals"), [], [])
inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs])
dorepr = self.helper("should_repr_global_name", name)
test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
expr = ast.IfExp(test, self.display(name), ast.Str(name.id))
return name, self.explanation_param(expr)
def visit_Compare(self, comp):
self.push_format_context()
left_res, left_expl = self.visit(comp.left)
if isinstance(comp.left, (_ast.Compare, _ast.BoolOp)):
left_expl = "({0})".format(left_expl)
res_variables = [self.variable() for i in range(len(comp.ops))]
load_names = [ast.Name(v, ast.Load()) for v in res_variables]
store_names = [ast.Name(v, ast.Store()) for v in res_variables]
it = zip(range(len(comp.ops)), comp.ops, comp.comparators)
expls = []
syms = []
results = [left_res]
for i, op, next_operand in it:
next_res, next_expl = self.visit(next_operand)
if isinstance(next_operand, (_ast.Compare, _ast.BoolOp)):
next_expl = "({0})".format(next_expl)
results.append(next_res)
sym = binop_map[op.__class__]
syms.append(ast.Str(sym))
expl = "%s %s %s" % (left_expl, sym, next_expl)
expls.append(ast.Str(expl))
res_expr = ast.Compare(left_res, [op], [next_res])
self.statements.append(ast.Assign([store_names[i]], res_expr))
left_res, left_expl = next_res, next_expl
# Use pytest.assertion.util._reprcompare if that's available.
expl_call = self.helper("call_reprcompare",
ast.Tuple(syms, ast.Load()),
ast.Tuple(load_names, ast.Load()),
ast.Tuple(expls, ast.Load()),
ast.Tuple(results, ast.Load()))
if len(comp.ops) > 1:
res = ast.BoolOp(ast.And(), load_names)
else:
res = load_names[0]
return res, self.explanation_param(self.pop_format_context(expl_call))
def test_compare(self):
left = ast.Name("x", ast.Load())
comp = ast.Compare(left, [ast.In()], [])
self.expr(comp, "no comparators")
comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
self.expr(comp, "different number of comparators and operands")
comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
self.expr(comp, "non-numeric", exc=TypeError)
comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
self.expr(comp, "non-numeric", exc=TypeError)
def visit_Name(self, name):
# Display the repr of the name if it's a local variable or
# _should_repr_global_name() thinks it's acceptable.
locs = ast_Call(self.builtin("locals"), [], [])
inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs])
dorepr = self.helper("should_repr_global_name", name)
test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
expr = ast.IfExp(test, self.display(name), ast.Str(name.id))
return name, self.explanation_param(expr)
def visit_Compare(self, comp):
self.push_format_context()
left_res, left_expl = self.visit(comp.left)
if isinstance(comp.left, (_ast.Compare, _ast.BoolOp)):
left_expl = "({0})".format(left_expl)
res_variables = [self.variable() for i in range(len(comp.ops))]
load_names = [ast.Name(v, ast.Load()) for v in res_variables]
store_names = [ast.Name(v, ast.Store()) for v in res_variables]
it = zip(range(len(comp.ops)), comp.ops, comp.comparators)
expls = []
syms = []
results = [left_res]
for i, op, next_operand in it:
next_res, next_expl = self.visit(next_operand)
if isinstance(next_operand, (_ast.Compare, _ast.BoolOp)):
next_expl = "({0})".format(next_expl)
results.append(next_res)
sym = binop_map[op.__class__]
syms.append(ast.Str(sym))
expl = "%s %s %s" % (left_expl, sym, next_expl)
expls.append(ast.Str(expl))
res_expr = ast.Compare(left_res, [op], [next_res])
self.statements.append(ast.Assign([store_names[i]], res_expr))
left_res, left_expl = next_res, next_expl
# Use pytest.assertion.util._reprcompare if that's available.
expl_call = self.helper("call_reprcompare",
ast.Tuple(syms, ast.Load()),
ast.Tuple(load_names, ast.Load()),
ast.Tuple(expls, ast.Load()),
ast.Tuple(results, ast.Load()))
if len(comp.ops) > 1:
res = ast.BoolOp(ast.And(), load_names)
else:
res = load_names[0]
return res, self.explanation_param(self.pop_format_context(expl_call))
def visit_Name(self, name):
# Display the repr of the name if it's a local variable or
# _should_repr_global_name() thinks it's acceptable.
locs = ast_Call(self.builtin("locals"), [], [])
inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs])
dorepr = self.helper("should_repr_global_name", name)
test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
expr = ast.IfExp(test, self.display(name), ast.Str(name.id))
return name, self.explanation_param(expr)
def visit_Compare(self, comp):
self.push_format_context()
left_res, left_expl = self.visit(comp.left)
if isinstance(comp.left, (_ast.Compare, _ast.BoolOp)):
left_expl = "({0})".format(left_expl)
res_variables = [self.variable() for i in range(len(comp.ops))]
load_names = [ast.Name(v, ast.Load()) for v in res_variables]
store_names = [ast.Name(v, ast.Store()) for v in res_variables]
it = zip(range(len(comp.ops)), comp.ops, comp.comparators)
expls = []
syms = []
results = [left_res]
for i, op, next_operand in it:
next_res, next_expl = self.visit(next_operand)
if isinstance(next_operand, (_ast.Compare, _ast.BoolOp)):
next_expl = "({0})".format(next_expl)
results.append(next_res)
sym = binop_map[op.__class__]
syms.append(ast.Str(sym))
expl = "%s %s %s" % (left_expl, sym, next_expl)
expls.append(ast.Str(expl))
res_expr = ast.Compare(left_res, [op], [next_res])
self.statements.append(ast.Assign([store_names[i]], res_expr))
left_res, left_expl = next_res, next_expl
# Use pytest.assertion.util._reprcompare if that's available.
expl_call = self.helper("call_reprcompare",
ast.Tuple(syms, ast.Load()),
ast.Tuple(load_names, ast.Load()),
ast.Tuple(expls, ast.Load()),
ast.Tuple(results, ast.Load()))
if len(comp.ops) > 1:
res = ast.BoolOp(ast.And(), load_names)
else:
res = load_names[0]
return res, self.explanation_param(self.pop_format_context(expl_call))
def test_contains_to_const(self):
# list => tuple
self.check_optimize_func("x in [1, 2]", "x in (1, 2)")
# set => frozenset
const = ast.Constant(value=frozenset({1, 2}))
node = ast.Compare(left=ast.Name(id='x', ctx=ast.Load()),
ops=[ast.In()],
comparators=[const])
self.check_optimize_func("x in {1, 2}", node)
# [] is not a constant: don't optimize
self.check_dont_optimize_func("x in [1, [], 2]")
self.check_dont_optimize_func("x in {1, [], 2}")
def not_compare(self, node):
compare = node.operand
if len(compare.ops) != 1:
# FIXME: optimize: 'not a <= b <= c' to 'a > b or b > c'
return
op = compare.ops[0]
try:
op = NOT_COMPARE[op.__class__]()
except KeyError:
return
new_cmp = ast.Compare(left=compare.left, ops=[op],
comparators=compare.comparators)
copy_lineno(compare, new_cmp)
return new_cmp
pytables.py 文件源码
项目:PyDataLondon29-EmbarrassinglyParallelDAWithAWSLambda
作者: SignalMedia
项目源码
文件源码
阅读 29
收藏 0
点赞 0
评论 0
def visit_Assign(self, node, **kwargs):
cmpr = ast.Compare(ops=[ast.Eq()], left=node.targets[0],
comparators=[node.value])
return self.visit(cmpr)
def do_keyword(self, node):
# node.arg is a string.
value = self.visit(node.value)
# This is a keyword *arg*, not a Python keyword!
return '%s=%s' % (node.arg, value)
# Compare(expr left, cmpop* ops, expr* comparators)
def do_Compare(self, node):
'''
StubFormatter ast.Compare visitor for these ops:
'==', '!=', '<', '<=', '>', '>=', 'is', 'is not', 'in', 'not in',
'''
s = 'bool' # Correct regardless of arguments.
ops = ','.join([self.op_name(z) for z in node.ops])
self.trace_visitor(node, ops, s)
return s
# If(expr test, stmt* body, stmt* orelse)
def get_condition_rhs_num(if_node):
assert isinstance(if_node, ast.If)
assert isinstance(if_node.test, ast.Compare)
assert isinstance(if_node.test.comparators[0], ast.Num)
return if_node.test.comparators[0].n
def get_condition_lhs(if_node):
assert isinstance(if_node, ast.If)
assert isinstance(if_node.test, ast.Compare)
return unparse(if_node.test.left).strip()