Python ast 模块,Eq() 实例源码

我们从Python开源项目中,提取了以下32个代码示例,用于说明如何使用ast.Eq()

项目:ITAP-django    作者:krivers    | 项目源码 | 文件源码
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
项目:PYSL    作者:sparkon    | 项目源码 | 文件源码
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
# ------------------------------------------------------------------------------
项目:viper    作者:ethereum    | 项目源码 | 文件源码
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, left, right], typ='bool', pos=getpos(self.expr))
        elif ltyp == 'decimal' and rtyp == 'num':
            return LLLnode.from_list([op, left, ['mul', right, DECIMAL_DIVISOR]], typ='bool', pos=getpos(self.expr))
        elif ltyp == 'num' and rtyp == 'decimal':
            return LLLnode.from_list([op, ['mul', left, DECIMAL_DIVISOR], right], typ='bool', pos=getpos(self.expr))
        else:
            raise TypeMismatchException("Unsupported types for comparison: %r %r" % (ltyp, rtyp), self.expr)
项目:ITAP-django    作者:krivers    | 项目源码 | 文件源码
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)
项目:py2rb    作者:naitoh    | 项目源码 | 文件源码
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
项目:ml-utils    作者:LinxiFan    | 项目源码 | 文件源码
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
项目:fatoptimizer    作者:vstinner    | 项目源码 | 文件源码
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)
项目:PyDataLondon29-EmbarrassinglyParallelDAWithAWSLambda    作者:SignalMedia    | 项目源码 | 文件源码
def visit_Assign(self, node, **kwargs):
        cmpr = ast.Compare(ops=[ast.Eq()], left=node.targets[0],
                           comparators=[node.value])
        return self.visit(cmpr)
项目:PyDataLondon29-EmbarrassinglyParallelDAWithAWSLambda    作者:SignalMedia    | 项目源码 | 文件源码
def translate_In(self, op):
        return ast.Eq() if isinstance(op, ast.In) else op
项目:TerpreT    作者:51alg    | 项目源码 | 文件源码
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)))
项目:TerpreT    作者:51alg    | 项目源码 | 文件源码
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) and isinstance(lhs, 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
项目:redbiom    作者:biocore    | 项目源码 | 文件源码
def Eq():
    return functools.partial(_compare, operator.eq)
项目:redbiom    作者:biocore    | 项目源码 | 文件源码
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
项目:hatlog    作者:alehander42    | 项目源码 | 文件源码
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
项目:beval    作者:hyw208    | 项目源码 | 文件源码
def Eq(self, key, right):
        c = criteria_class.instance(Const.Eq, key, right)
        self._push(c)
        return self
项目:beval    作者:hyw208    | 项目源码 | 文件源码
def __init__(self, key, right, op=operator.eq):
        super(Eq, self).__init__(stack=False)
        self._op = op
        self._key = types_supported_as_key(self, key)
        self._right = right
项目:mutpy    作者:mutpy    | 项目源码 | 文件源码
def mutate_NotEq(self, node):
        return ast.Eq()
项目:femtocode    作者:diana-hep    | 项目源码 | 文件源码
def pythonast(self, args, tonative=False):
        return ast.Compare(args[0], [ast.Eq()], [args[1]])
项目:femtocode    作者:diana-hep    | 项目源码 | 文件源码
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)))
项目:tidy    作者:cyrus-    | 项目源码 | 文件源码
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.Is, 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
项目:tidy    作者:cyrus-    | 项目源码 | 文件源码
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())
项目:tidy    作者:cyrus-    | 项目源码 | 文件源码
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.Is, ast.IsNot, ast.In, ast.NotIn)):
                raise _errors.TyError("Invalid comparison operator on strings.", e)
        for e_ in _util.tpl_cons(left, comparators):
            if hasattr(e_, 'match'): 
                continue # already synthesized
            ctx.ana(e_, self)
        return _boolean.boolean
项目:tidy    作者:cyrus-    | 项目源码 | 文件源码
def syn_Compare(self, ctx, e):
        left, ops, comparators = e.left, e.ops, e.comparators
        for op in ops:
            if isinstance(op, (ast.Eq, 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, comparators):
            if hasattr(e_, "match"): 
                continue # already synthesized
            ctx.ana(e_, self)

        return _boolean.boolean
项目:tidy    作者:cyrus-    | 项目源码 | 文件源码
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()
项目:tidy    作者:cyrus-    | 项目源码 | 文件源码
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())
项目:tidy    作者:cyrus-    | 项目源码 | 文件源码
def translate_pat_Num(self, ctx, pat, scrutinee_trans):
        n = pat.n
        comparator = astx.copy_node(pat)
        comparator.n = float(n)
        condition = ast.Compare(
            left=scrutinee_trans,
            ops=[ast.Eq()],
            comparators=[comparator])
        return (condition, _util.odict())
项目:tidy    作者:cyrus-    | 项目源码 | 文件源码
def translate_pat_Name_constructor(cls, ctx, pat, 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())
项目:tidy    作者:cyrus-    | 项目源码 | 文件源码
def translate_pat_Unary_Name_constructor(self, ctx, pat, scrutinee_trans):
        if isinstance(pat.op, ast.USub):
            s = "-Inf"
        else:
            s = "Inf"
        condition = ast.Compare(
            left=scrutinee_trans,
            ops=[ast.Eq()],
            comparators=[
                astx.builtin_call("float", [ast.Str(s=s)])]
        )
        return (condition, _util.odict())
项目:tidy    作者:cyrus-    | 项目源码 | 文件源码
def translate_pat_Num(self, ctx, pat, 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,
            ops=[ast.Eq()],
            comparators=[comparator])
        return (condition, _util.odict())
项目:ITAP-django    作者:krivers    | 项目源码 | 文件源码
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, bLeft, checkEquality=True)
        arbrComp = compareASTs(aRight, bRight, 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
项目:ITAP-django    作者:krivers    | 项目源码 | 文件源码
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
项目:pydiatra    作者:jwilk    | 项目源码 | 文件源码
def _visit_compare(self, left, 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()', op, repr('PyPy'))
                            )
                if tpl is False:
                    pass
                elif tpl is None:
                    yield self.tag(left, 'sys.version-comparison')
                else:
                    yield self.tag(left, 'sys.version-comparison',
                        format_cmp('sys.version_info', op, 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',
                        format_cmp('sys.version_info', op, tpl, swap=swap)
                    )