Python ast 模块,Eq() 实例源码
我们从Python开源项目中,提取了以下32个代码示例,用于说明如何使用ast.Eq()。
def doCompare(op, left, right):
"""Perform the given AST comparison on the values"""
top = type(op)
if top == ast.Eq:
return left == right
elif top == ast.NotEq:
return left != right
elif top == ast.Lt:
return left < right
elif top == ast.LtE:
return left <= right
elif top == ast.Gt:
return left > right
elif top == ast.GtE:
return left >= right
elif top == ast.Is:
return left is right
elif top == ast.IsNot:
return left is not right
elif top == ast.In:
return left in right
elif top == ast.notin:
return left not in right
def cmpop_str(op: ast.AST) -> str:
if isinstance(op, ast.Eq):
return '=='
if isinstance(op, ast.NotEq):
return '!='
if isinstance(op, ast.Lt):
return '<'
if isinstance(op, ast.LtE):
return '<='
if isinstance(op, ast.Gt):
return '>'
if isinstance(op, ast.GtE):
return '>='
error(loc(op), "Invalid compare operator encountered: {0}:{1}. Check supported intrisics.".format(op.lineno, op.col_offset))
return 'INVALID_CMPOP'
# Parsers
# ------------------------------------------------------------------------------
def compare(self):
left = Expr.parse_value_expr(self.expr.left, self.context)
right = Expr.parse_value_expr(self.expr.comparators[0], self.context)
if isinstance(self.expr.ops[0], ast.In) and \
isinstance(right.typ, ListType):
if not are_units_compatible(left.typ, right.typ.subtype) and not are_units_compatible(right.typ.subtype, left.typ):
raise TypeMismatchException("Can't use IN comparison with different types!", self.expr)
return self.build_in_comparator()
else:
if not are_units_compatible(left.typ, right.typ) and not are_units_compatible(right.typ, left.typ):
raise TypeMismatchException("Can't compare values with different units!", self.expr)
if len(self.expr.ops) != 1:
raise StructureException("Cannot have a comparison with more than two elements", self.expr)
if isinstance(self.expr.ops[0], ast.Gt):
op = 'sgt'
elif isinstance(self.expr.ops[0], ast.GtE):
op = 'sge'
elif isinstance(self.expr.ops[0], ast.LtE):
op = 'sle'
elif isinstance(self.expr.ops[0], ast.Lt):
op = 'slt'
elif isinstance(self.expr.ops[0], ast.Eq):
op = 'eq'
elif isinstance(self.expr.ops[0], ast.NotEq):
op = 'ne'
else:
raise Exception("Unsupported comparison operator")
if not is_numeric_type(left.typ) or not is_numeric_type(right.typ):
if op not in ('eq', 'ne'):
raise TypeMismatchException("Invalid type for comparison op", self.expr)
ltyp, rtyp = left.typ.typ, right.typ.typ
if ltyp == rtyp:
return LLLnode.from_list([op, right], typ='bool', pos=getpos(self.expr))
elif ltyp == 'decimal' and rtyp == 'num':
return LLLnode.from_list([op, ['mul', right, DECIMAL_DIVISOR]], pos=getpos(self.expr))
elif ltyp == 'num' and rtyp == 'decimal':
return LLLnode.from_list([op, DECIMAL_DIVISOR], pos=getpos(self.expr))
else:
raise TypeMismatchException("Unsupported types for comparison: %r %r" % (ltyp, rtyp), self.expr)
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_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, ast.Eq):
return "%s == %s" % (left, comp)
elif isinstance(op, ast.NotEq):
return "%s != %s" % (left, 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, op)
if len(node.ops) == 1:
return pair
compare_list.append('(' + pair + ')')
return ' and '.join(compare_list)
# python 3
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 compare_cst(self, node):
node_op = node.ops[0].__class__
eval_op = EVAL_COMPARE.get(node_op)
if eval_op is None:
return
if node_op in (ast.In, ast.notin):
left_hashable = True
right_types = IteraBLE_TYPES
else:
left_hashable = False
right_types = None
if left_hashable:
left = get_constant(node.left)
else:
left = get_literal(node.left)
if left is UNSET:
return
right = get_literal(node.comparators[0], types=right_types)
if right is UNSET:
return
if (node_op in (ast.Eq, ast.NotEq)
and ((isinstance(left, str) and isinstance(right, bytes))
or (isinstance(left, bytes) and isinstance(right, str)))):
# comparison between bytes and str can raise BytesWarning depending
# on runtime option
return
try:
result = eval_op(left, right)
except TypeError:
return
return self.new_constant(node, result)
def translate_In(self, op):
return ast.Eq() if isinstance(op, ast.In) else op
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 parse_compare(compare_node):
assert len(compare_node.ops) == 1, "multiple comparison ops?" + ast.dump(compare_node)
assert isinstance(compare_node.ops[0], ast.Eq), "comparison should be ==" + \
ast.dump(compare_node.ops[0])
lhs = compare_node.left
rhs = compare_node.comparators[0]
if isinstance(lhs, ast.Name) and isinstance(rhs, ast.Num):
var_name = lhs.id
val = rhs.n
elif isinstance(rhs, ast.Name) and isinstance(lhs, ast.Num):
var_name = rhs.id
val = lhs.n
elif isinstance(rhs, ast.Name):
# try to apply macro
if is_int_constant(rhs):
var_name = lhs.id
val = rhs.id
elif is_int_constant(lhs):
var_name = rhs.id
val = lhs.id
else:
assert False, "Unable to apply macro to fix comparator " + ast.dump(compare_node)
else:
assert False, "unexpected comparator" + ast.dump(compare_node)
return var_name, val
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 flatten_compare(self, node):
if len(node.comparators) != 1:
raise ValueError("hatlog supports only 1 comparator")
if isinstance(node.ops[0], ast.Eq):
op = 'z_eq'
else:
op = 'z_cmp'
a = self.flatten(node.left)
b = self.flatten(node.comparators[0])
node_type = self.new_type()
self.nodes.append((op, [a, b], node_type))
return node_type
def Eq(self, key, right):
c = criteria_class.instance(Const.Eq, right)
self._push(c)
return self
def pythonast(self, args, tonative=False):
return ast.Compare(args[0], [ast.Eq()], [args[1]])
def pythonast(self, tonative=False):
arg, = args
return ast.IfExp(ast.Compare(arg, [ast.Num(1)]), ast.Num(inf), ast.IfExp(ast.Compare(arg, [ast.Num(-1)]), ast.Num(-inf), ast.Call(ast.Attribute(ast.Name("$math", ast.Load()), "atanh", [], None, None)))
def syn_Compare(self, ctx, e):
left, ops, comparators = e.left, e.ops, e.comparators
for op in ops:
if not isinstance(op, (ast.Eq, ast.NotEq, ast.IsNot)):
raise _errors.TyError("Type bool does not support this operator.", op)
for e_ in _util.tpl_cons(left, comparators):
if hasattr(e_, 'match'):
continue # already synthesized
ctx.ana(e_, self)
return self
def syn_Compare(self, ast.IsNot, ast.notin)):
raise _errors.TyError("Invalid comparison operator on strings.", e)
for e_ in _util.tpl_cons(left, self)
return _boolean.boolean
def syn_Compare(self, e.comparators
for op in ops:
if isinstance(op, ast.NotEq)):
if not len(self.idx) == 0:
raise _errors.TyError("Can only compare unit values for equality.", e)
elif not isinstance(op, (ast.Is, ast.IsNot)):
raise _errors.TyError("Invalid comparison operator.", op)
for e_ in _util.tpl_cons(left, "match"):
continue # already synthesized
ctx.ana(e_, self)
return _boolean.boolean
def translate_pat_Name_constructor(self, scrutinee_trans):
lbl = pat.id
condition = ast.Compare(
left=scrutinee_trans,
comparators=[ast.Str(s=lbl)])
return condition, _util.odict()
def translate_pat_Name_constructor(cls, scrutinee_trans):
id = pat.id
if id == "NaN":
condition = astx.method_call(
astx.import_expr('math'),
'isnan',
[scrutinee_trans])
else:
condition = ast.Compare(
left=scrutinee_trans,
ops=[ast.Eq()],
comparators=[
astx.builtin_call("float", [ast.Str(s=id)])]
)
return (condition, _util.odict())
def translate_pat_Unary_Name_constructor(self, scrutinee_trans):
if isinstance(pat.op, ast.USub):
s = "-Inf"
else:
s = "Inf"
condition = ast.Compare(
left=scrutinee_trans,
comparators=[
astx.builtin_call("float", [ast.Str(s=s)])]
)
return (condition, scrutinee_trans):
scrutinee_trans_copy = astx.copy_node(scrutinee_trans)
comparator = astx.copy_node(pat)
n = pat.n
if not isinstance(n, complex):
comparator.n = complex(n)
condition = ast.Compare(
left=scrutinee_trans_copy, _util.odict())
def aredisjoint(a, b):
"""Are the sets of values that satisfy these two boolean constraints disjoint?"""
# The easiest way to be disjoint is to have comparisons that cover different areas
if type(a) == type(b) == ast.Compare:
aop = a.ops[0]
bop = b.ops[0]
aLeft = a.left
aRight = a.comparators[0]
bLeft = b.left
bRight = b.comparators[0]
alblComp = compareASTs(aLeft, bLeft, checkEquality=True)
albrComp = compareASTs(aLeft, bRight, checkEquality=True)
arblComp = compareASTs(aRight, checkEquality=True)
arbrComp = compareASTs(aRight, checkEquality=True)
altype = type(aLeft) in [ast.Num, ast.Str]
artype = type(aRight) in [ast.Num, ast.Str]
bltype = type(bLeft) in [ast.Num, ast.Str]
brtype = type(bRight) in [ast.Num, ast.Str]
if (type(aop) == ast.Eq and type(bop) == ast.NotEq) or \
(type(bop) == ast.Eq and type(aop) == ast.NotEq):
# x == y,x != y
if (alblComp == 0 and arbrComp == 0) or (albrComp == 0 and arblComp == 0):
return True
elif type(aop) == type(bop) == ast.Eq:
if (alblComp == 0 and arbrComp == 0) or (albrComp == 0 and arblComp == 0):
return False
# x = num1,x = num2
elif alblComp == 0 and artype and brtype:
return True
elif albrComp == 0 and artype and bltype:
return True
elif arblComp == 0 and altype and brtype:
return True
elif arbrComp == 0 and altype and bltype:
return True
elif (type(aop) == ast.Lt and type(bop) == ast.GtE) or \
(type(aop) == ast.Gt and type(bop) == ast.LtE) or \
(type(aop) == ast.LtE and type(bop) == ast.Gt) or \
(type(aop) == ast.GtE and type(bop) == ast.Lt) or \
(type(aop) == ast.Is and type(bop) == ast.IsNot) or \
(type(aop) == ast.IsNot and type(bop) == ast.Is) or \
(type(aop) == ast.In and type(bop) == ast.notin) or \
(type(aop) == ast.notin and type(bop) == ast.In):
if alblComp == 0 and arbrComp == 0:
return True
elif (type(aop) == ast.Lt and type(bop) == ast.LtE) or \
(type(aop) == ast.Gt and type(bop) == ast.GtE) or \
(type(aop) == ast.LtE and type(bop) == ast.Lt) or \
(type(aop) == ast.GtE and type(bop) == ast.Gt):
if albrComp == 0 and arblComp == 0:
return True
elif type(a) == type(b) == ast.BoolOp:
return False # for Now- Todo: when is this not true?
elif type(a) == ast.UnaryOp and type(a.op) == ast.Not:
if compareASTs(a.operand, b, checkEquality=True) == 0:
return True
elif type(b) == ast.UnaryOp and type(b.op) == ast.Not:
if compareASTs(b.operand, a, checkEquality=True) == 0:
return True
return False
def negate(op):
"""Return the negation of the provided operator"""
if op == None:
return None
top = type(op)
neg = not op.negated if hasattr(op, "negated") else True
if top == ast.And:
newOp = ast.Or()
elif top == ast.Or:
newOp = ast.And()
elif top == ast.Eq:
newOp = ast.NotEq()
elif top == ast.NotEq:
newOp = ast.Eq()
elif top == ast.Lt:
newOp = ast.GtE()
elif top == ast.GtE:
newOp = ast.Lt()
elif top == ast.Gt:
newOp = ast.LtE()
elif top == ast.LtE:
newOp = ast.Gt()
elif top == ast.Is:
newOp = ast.IsNot()
elif top == ast.IsNot:
newOp = ast.Is()
elif top == ast.In:
newOp = ast.notin()
elif top == ast.notin:
newOp = ast.In()
elif top == ast.NameConstant and op.value in [True, False]:
op.value = not op.value
op.negated = neg
return op
elif top == ast.Compare:
if len(op.ops) == 1:
op.ops[0] = negate(op.ops[0])
op.negated = neg
return op
else:
values = []
allOperands = [op.left] + op.comparators
for i in range(len(op.ops)):
values.append(ast.Compare(allOperands[i], [negate(op.ops[i])],
[allOperands[i+1]], multiCompPart=True))
newOp = ast.BoolOp(ast.Or(multiCompOp=True), values, multiComp=True)
elif top == ast.UnaryOp and type(op.op) == ast.Not and \
eventualType(op.operand) == bool: # this can mess things up type-wise
return op.operand
else:
# this is a normal value,so put a not around it
newOp = ast.UnaryOp(ast.Not(addednot=True), op)
transferMetaData(op, newOp)
newOp.negated = neg
return newOp
def _visit_compare(self, op, right):
swap = False
if not isinstance(left, ast.Attribute):
left, right = right, left
swap = True
if not isinstance(left, ast.Attribute):
return
hardcoded_errno = (
left.attr == 'errno' and
op in astaux.equality_ops and
isinstance(right, ast.Num) and
isinstance(right.n, int) and
right.n in errno_constants
)
if hardcoded_errno:
yield self.tag(right, '*hardcoded-errno-value', right.n)
sys_attr_comparison = (
isinstance(left.value, ast.Name) and
left.value.id == 'sys'
)
if sys_attr_comparison:
if left.attr == 'version':
tpl = None
if isinstance(right, ast.Str):
if op in astaux.inequality_ops:
try:
tpl = sysversion.version_to_tuple(right.s)
except (TypeError, ValueError):
pass
elif swap and (op in astaux.in_ops):
if right.s == 'PyPy':
tpl = False
op = ast.Eq if isinstance(op, ast.In) else ast.NotEq
yield self.tag(left, 'sys.version-comparison',
format_cmp('platform.python_implementation()', repr('PyPy'))
)
if tpl is False:
pass
elif tpl is None:
yield self.tag(left, 'sys.version-comparison')
else:
yield self.tag(left,
format_cmp('sys.version_info', tpl, swap=swap)
)
elif left.attr == 'hexversion':
tpl = None
if isinstance(right, ast.Num) and (op in astaux.numeric_cmp_ops):
try:
tpl = sysversion.hexversion_to_tuple(right.n)
except (TypeError, ValueError):
pass
if tpl is None:
yield self.tag(left, 'sys.hexversion-comparison')
else:
yield self.tag(left, 'sys.hexversion-comparison', swap=swap)
)