def Compare(left, ops, comparators):
for op, comp in zip(ops, comparators):
left = op(left, comp)
return left
python类Compare()的实例源码
def whereeval(str_, get=None):
"""Evaluate a set operation string, where each Name is fetched"""
if get is None:
import redbiom
config = redbiom.get_config()
get = redbiom._requests.make_get(config)
# Load is subject to indirection to simplify testing
globals()['Load'] = make_Load(get)
formed = ast.parse(str_, mode='eval')
node_types = (ast.Compare, ast.In, ast.NotIn, ast.BoolOp, ast.And,
ast.Name, ast.Or, ast.Eq, ast.Lt, ast.LtE, ast.Gt, ast.GtE,
ast.NotEq, ast.Str, ast.Num, ast.Load, ast.Expression,
ast.Tuple, ast.Is, ast.IsNot)
for node in ast.walk(formed):
if not isinstance(node, node_types):
raise TypeError("Unsupported node type: %s" % ast.dump(node))
result = eval(ast.dump(formed))
# clean up
global Load
del Load
return result
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 __init__(self, operators=None, functions=None, names=None):
"""
Create the evaluator instance. Set up valid operators (+,-, etc)
functions (add, random, get_val, whatever) and names. """
if not operators:
operators = DEFAULT_OPERATORS
if not functions:
functions = DEFAULT_FUNCTIONS
if not names:
names = DEFAULT_NAMES
self.operators = operators
self.functions = functions
self.names = names
self.nodes = {
ast.Num: self._eval_num,
ast.Str: self._eval_str,
ast.Name: self._eval_name,
ast.UnaryOp: self._eval_unaryop,
ast.BinOp: self._eval_binop,
ast.BoolOp: self._eval_boolop,
ast.Compare: self._eval_compare,
ast.IfExp: self._eval_ifexp,
ast.Call: self._eval_call,
ast.keyword: self._eval_keyword,
ast.Subscript: self._eval_subscript,
ast.Attribute: self._eval_attribute,
ast.Index: self._eval_index,
ast.Slice: self._eval_slice,
}
# py3k stuff:
if hasattr(ast, 'NameConstant'):
self.nodes[ast.NameConstant] = self._eval_nameconstant
elif isinstance(self.names, dict) and "None" not in self.names:
self.names["None"] = None
def visit_Compare(self, node):
if len(node.ops) not in (1, 2,):
raise SyntaxError("ast.Compare with more than 2 ops: %s is not supported" % node)
(_, left), (_, ops), (_, comps) = ast.iter_fields(node)
self.visit(left)
left = self.data.pop()
comparators = list()
for comparator in comps:
self.visit(comparator)
comparators.append(self.data.pop())
if len(ops) == 1:
right = comparators[0]
cls = criteria_class.lookup(ast_op_to_criteria.lookup(type(ops[0])))
criteria = cls(left, *right) if type(right) in (list, tuple,) else cls(left, right)
self.data.append(criteria)
else:
lower = left
lower_op = ast_op_to_operator.lookup(type(ops[0]))
one = comparators[0]
upper_op = ast_op_to_operator.lookup(type(ops[1]))
upper = comparators[1]
criteria = criteria_class.instance(Const.Between, lower, one, upper, lower_op, upper_op)
self.data.append(criteria)
def normalize(node):
if isinstance(node, ast.Compare):
return normalize_compare(node)
for key in dir(node):
if key.startswith("_"):
continue
value = getattr(node, key)
if isinstance(value, ast.AST):
setattr(node, key, normalize(value))
elif isinstance(value, list):
setattr(node, key, [normalize(n) for n in value])
return node
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)
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)
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 pythonast(self, args, tonative=False):
return ast.Compare(args[0], [ast.Eq()], [args[1]])
def pythonast(self, args, tonative=False):
return ast.Compare(args[0], [ast.NotEq()], [args[1]])
def pythonast(self, args, tonative=False):
return ast.Compare(args[0], [ast.Lt()], [args[1]])
def pythonast(self, args, tonative=False):
return ast.Compare(args[0], [ast.LtE()], [args[1]])
def pythonast(self, args, tonative=False):
return ast.Compare(args[0], [ast.Gt()], [args[1]])
def pythonast(self, args, tonative=False):
arg, = args
justlog = ast.Call(ast.Attribute(ast.Name("$math", ast.Load()), "log", ast.Load()), [arg], [], None, None)
if self.base == math.e:
if tonative:
return justlog
else:
return ast.IfExp(ast.Compare(arg, [ast.Gt()], [ast.Num(0)]), justlog, ast.Num(-inf))
else:
scaled = ast.BinOp(justlog, ast.Div(), ast.Num(math.log(self.base)))
if tonative:
return scaled
else:
return ast.IfExp(ast.Compare(arg, [ast.Gt()], [ast.Num(0)]), scaled, ast.Num(-inf))
def pythonast(self, args, tonative=False):
arg, = args
return ast.IfExp(ast.Compare(arg, [ast.Eq()], [ast.Num(1)]), ast.Num(inf), ast.IfExp(ast.Compare(arg, [ast.Eq()], [ast.Num(-1)]), ast.Num(-inf), ast.Call(ast.Attribute(ast.Name("$math", ast.Load()), "atanh", ast.Load()), args, [], None, None)))
def peval_single_compare(state, ctx, op, left, right):
func = COMPARE_OPS[type(op)]
state, result = peval_call(state, ctx, func, args=[left, right])
if not is_known_value(result):
state = state.update(temp_bindings=state.temp_bindings.del_(result.func.id))
result = ast.Compare(left=result.args[0], ops=[op], comparators=[result.args[1]])
return state, result
def translate_pat_Str(self, ctx, pat, scrutinee_trans):
scrutinee_trans_copy = astx.copy_node(scrutinee_trans)
pat_copy = astx.copy_node(pat)
condition = ast.Compare(
left=scrutinee_trans_copy,
ops=[ast.Eq()],
comparators=[pat_copy])
return (condition, _util.odict())
def translate_pat_Name_constructor(self, ctx, pat, scrutinee_trans):
lbl = pat.id
condition = ast.Compare(
left=scrutinee_trans,
ops=[ast.Eq()],
comparators=[ast.Str(s=lbl)])
return condition, _util.odict()
def translate_pat_Num(self, ctx, pat, scrutinee_trans):
scrutinee_trans_copy = astx.copy_node(scrutinee_trans)
comparator = astx.copy_node(pat)
condition = ast.Compare(
left=scrutinee_trans_copy,
ops=[ast.Eq()],
comparators=[comparator])
return (condition, _util.odict())