def visit_Compare(self, node): if len(node.ops) > 1: return self.visit(ast.copy_location( ast.BoolOp( op=ast.And(), values=[ ast.Compare(left=left, ops=[op], comparators=[right]) for left, op, right in zip([node.left] + node.comparators, node.ops, node.comparators) ] ), node )) else: func = ast.Attribute(value=self.visit(node.left), attr=compare_op_map[type(node.ops[0])], ctx=ast.Load()) call = ast.Call(func=func, args=[self.visit(node.comparators[0])], keywords=[]) return ast.copy_location(call, node)
def visitExpr(self, ctx:cmmParser.ExprContext): left = self.visit(ctx.left) if ctx.right: # >, <, >=, <=, ==, != right = self.visit(ctx.right) op_map = {'<' : ast.Lt, '>' : ast.Gt, '>=': ast.LtE, '<=': ast.GtE, '==': ast.Eq, '!=': ast.NotEq} op = op_map[ctx.op.text]() return ast.Compare(left=left, ops=[op], comparators=[right]) else: # higher priority expsetion return left
def visit_Compare(self, node): left = self.visit(node.left) ops = [self.visit(op) for op in node.ops] comparators = [self.visit(cmp) for cmp in node.comparators] right = comparators[0] if isinstance(right, ast.List): tmp = ast.Name(id=self._get_temp(), lineno=node.lineno) comparators[0] = tmp return create_ast_block( body=[ ast.Assign(targets=[tmp], value=right, lineno=node.lineno), ast.Compare(left, ops, comparators, lineno=node.lineno), ], at_node=node, ) return node
def expression(expr): if expr['type'] == "Identifier": n = ast.Name(lineno=1, col_offset=0) n.id = str(expr['name']) n.ctx = ast.Load() c = ast.Call(lineno=1, col_offset=0) c.func = n c.args = [] c.keywords = [] c.starargs = None c.kwargs = None return c if expr['type'] == "VariableExpression": n = ast.Name(lineno=1, col_offset=0) n.id = str(expr['id']['name']) n.ctx = ast.Load() return n if expr['type'] == "String": s = ast.Str(lineno=1, col_offset=0) s.s = expr['content'] return s if expr['type'] == "Number": n = ast.Num(lineno=1, col_offset=0) n.n = expr['value'] return n if expr['type'] == "ConditionalExpression": i = ast.IfExp(lineno=1, col_offset=0) i.test = expression(expr['test']) i.body = expression(expr['consequent']) i.orelse = expression(expr['alternate']) return i if expr['type'] == "BinaryExpression": # L20n binary expr transpile into Python's BinOp or Compare if expr['operator']['token'] in ('==', ): c = ast.Compare(lineno=1, col_offset=0) c.left = expression(expr['left']) c.ops = [ast.Eq()] c.comparators = [expression(expr['right'])] return c if expr['operator']['token'] in ('+', ): b = ast.BinOp(lineno=1, col_offset=0) b.left = expression(expr['left']) b.op = ast.Add() b.right = expression(expr['right']) return b
def visit_Compare(self, cp): left = cp.left ops = cp.ops cmps = cp.comparators if isinstance(left, ast.Attribute) and \ isinstance(left.value, ast.Name) and \ left.value.id == 'shape' and \ left.attr == 'type': call = ast.Call( ast.Name('ST_GeometryType', ast.Load()), [ast.Name('shape', ast.Load())], [], None, None) left = ast.copy_location(call, left) renamer = GeomNameTransformer() cmps = map(renamer.visit, cmps) return ast.copy_location(ast.Compare(left, ops, cmps), cp)
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 visit_Compare(self, node): self.generic_visit(node) ret = None comparators = [node.left] + node.comparators for i in range(len(node.comparators)): new_cmp = ast.Compare(left=comparators[i], ops=[node.ops[i]], comparators=[comparators[i + 1]]) ast.copy_location(new_cmp, node) if ret is None: ret = new_cmp else: ret = ast.BoolOp(op=ast.And(), values=[ret, new_cmp]) ret = self.visit_BoolOp(ret) ast.copy_location(ret, node) self.generic_visit(ret) return ret
def _arr_expr_to_ast(expr): """Build a Python expression AST from an array expression built by RewriteArrayExprs. """ if isinstance(expr, tuple): op, arr_expr_args = expr ast_args = [] env = {} for arg in arr_expr_args: ast_arg, child_env = _arr_expr_to_ast(arg) ast_args.append(ast_arg) env.update(child_env) if op in npydecl.supported_array_operators: if len(ast_args) == 2: if op in _binops: return ast.BinOp(ast_args[0], _binops[op](), ast_args[1]), env if op in _cmpops: return ast.Compare(ast_args[0], [_cmpops[op]()], [ast_args[1]]), env else: assert op in _unaryops return ast.UnaryOp(_unaryops[op](), ast_args[0]), env elif _is_ufunc(op): fn_name = "__ufunc_or_dufunc_{0}".format( hex(hash(op)).replace("-", "_")) fn_ast_name = ast.Name(fn_name, ast.Load()) env[fn_name] = op # Stash the ufunc or DUFunc in the environment ast_call = ast.Call(fn_ast_name, ast_args, []) return ast_call, env elif isinstance(expr, ir.Var): return ( ast.Name( expr.name, ast.Load(), lineno=expr.loc.line, col_offset=expr.loc.col if expr.loc.col else 0, ), {}, ) elif isinstance(expr, ir.Const): return ast.Num(expr.value), {} raise NotImplementedError( "Don't know how to translate array expression '%r'" % (expr, ))
def _visit_Assign(self, assign_node, dummy=None): def search_ids(node): ids = [] for elt in node.elts: if isinstance(elt, ast.Name): ids.append(elt.id) else: ids.extend(search_ids(elt)) return ids nodes = [] for idx, target in enumerate(assign_node.targets): target_ids = [] if not isinstance(target, ast.Name): target_ids.append(search_ids(target)) else: target_ids.append([target.id]) compares = [] for ids in target_ids: target_compares = [] for _id in ids: compare = ast.Compare( left=ast.Str(s=_id), ops=[ast.NotIn()], comparators=[ ast.Call(func=ast.Name(id="globals", ctx=ast.Load()), args=[], keywords=[]) ]) target_compares.append(compare) compares.append(target_compares) for target_compares in compares: if len(target_compares) == 1: test = target_compares[0] new_target = [assign_node.targets[0]] else: test = ast.BoolOp(op=ast.Or(), values=target_compares) new_target = [assign_node.targets[idx]] new_assign = ast.Assign(targets=new_target, value=assign_node.value) nodes.append(ast.If(test=test, body=[new_assign], orelse=[])) return nodes
def create_match_check(self, pattern: Pattern, data): """Given an ADT match pattern and a (Python) expression pointing to an ADT value, this generates a Python expression that checks if the ADT value matches the given pattern (returning True or False).""" # wildcard or var match everything if isinstance(pattern, (relay.PatternWildcard, relay.PatternVar)): return NameConstant(True) conds = [] if isinstance(pattern, relay.PatternConstructor): # constructor patterns check whether the constructors match # and also the matches of any nested patterns # equiv: (arg.tag == patern_constructor.tag) conds.append( ast.Compare( ast.Attribute(data, "tag", Load()), [ast.Eq()], [ast.Num(pattern.constructor.tag)], ) ) assert isinstance(pattern, (relay.PatternConstructor, relay.PatternTuple)) # now check for any nested patterns for i in range(len(pattern.patterns)): nested_pat = pattern.patterns[i] # can safely skip var or wildcard patterns: they will # never cause a check to fail if not isinstance(nested_pat, relay.PatternConstructor): continue # index into the value corresponding to the subpattern field_index = ast.Subscript( ast.Attribute(data, "fields", Load()), ast.Index(Num(i)), Load() ) conds.append(self.create_match_check(nested_pat, field_index)) # if we do not need to check nested pattern, just return the single check if len(conds) == 1: return conds[0] # otherwise AND together any nested checks return ast.BoolOp(ast.And(), conds)
def generateSplit(varId: int, margin: float, les: ast.stmt, gret: ast.stmt, defaultLeft: bool, useSigmoids: bool) -> ast.If: """Creates AST nodes corresponding to tree splits""" el = ast.Subscript(value=vector, slice=ast.Index(value=astNum(n=varId))) if not useSigmoids: check = ast.Compare(left=el, comparators=[astNum(margin)], ops=[ast.Lt()]) check = missingCheck(check, el, defaultLeft) return ast.If( #return ast.Expr(value=ast.IfExp( test=check, body=[les], orelse=[gret], ) else: return ast.Call(func=ast.Name(id=sigmoidSplitFuncName), args=[el, astNum(margin), les, gret, globalInvTemp], keywords=[])
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_Compare(self, node): """Compare nodes occur for all sequences of comparison (`in`, gt, lt, etc.) operators. We only want to match `___ in instanceof(dict)` here, so we restrict this to Compare ops with a single operator which is `In` or `NotIn`. """ node = self.generic_visit(node) if len(node.ops) == 1 and isinstance(node.ops[0], (ast.In, ast.NotIn)): cmps = node.comparators if len(cmps) == 1 and isinstance(cmps[0], _resolved): rslvd = cmps[0] if isinstance(rslvd.value, dict): node = ast.Compare(node.left, node.ops, [ _resolved(rslvd.representation + ".keys()", sorted(rslvd.value.keys())) ]) return node
def visit_Compare(self, node): "Reduce cascaded comparisons into single comparisons" # Process children self.generic_visit(node) compare_nodes = [] comparators = [nodes.CloneableNode(c) for c in node.comparators] if len(node.comparators) > 1: if node.type.is_array: raise error.NumbaError( node, "Cannot determine truth value of boolean array " "(use any or all)") # Build comparison nodes left = node.left for op, right in zip(node.ops, comparators): node = ast.Compare(left=left, ops=[op], comparators=[right]) # Set result type of comparison: # bool array of array comparison # bool otherwise if left.type.is_array or right.type.is_array: # array < x -> Array(bool_, array.ndim) result_type = self.env.crnt.typesystem.promote( left.type, right.type) else: result_type = bool_ nodes.typednode(node, result_type) # Handle comparisons specially based on their types node = self.single_compare(node) compare_nodes.append(node) left = right.clone # AND the comparisons together node = reduce(build_boolop, reversed(compare_nodes)) return node
def warn_about_none_ast(self, node, module_path, lineno): """ Returns an AST issuing a warning if the value of node is `None`. This is used to warn the user when asserting a function that asserts internally already. See issue #3191 for more details. """ val_is_none = ast.Compare(node, [ast.Is()], [ast.NameConstant(None)]) send_warning = ast.parse("""\ from _pytest.warning_types import PytestAssertRewriteWarning from warnings import warn_explicit warn_explicit( PytestAssertRewriteWarning('asserting the value None, please use "assert is None"'), category=None, filename={filename!r}, lineno={lineno}, ) """.format(filename=module_path, lineno=lineno)).body return ast.If(val_is_none, send_warning, [])
def __build_conditional_arg_check(self, argname, argtype): target_value = ast.Subscript(value=ast.Name(id='kwargs', ctx=ast.Load()), slice=ast.Index(ast.Str(s=argname)), ctx=ast.Load()) presence_check = ast.Call(func=ast.Name(id='isinstance', ctx=ast.Load()), args=[target_value, argtype], keywords=[], lineno=self.__get_line()) # Assumes that argtype is a ast.Tuple of ast.Name items types = [t.id for t in argtype.elts] check_message = ast.BinOp(left=ast.Str( s='Optional argument \'{}\' must be of type \'{}\'. Received type: \'%s\'' .format(argname, types)), op=ast.Mod(), right=ast.Call(func=ast.Name(id='type', ctx=ast.Load()), args=[target_value], keywords=[]), lineno=self.__get_line()) assert_check = ast.Assert(test=presence_check, msg=check_message, lineno=self.__get_line()) check_body = [assert_check] check = ast.Compare( left=ast.Str(s=argname, ctx=ast.Load()), ops=[ast.In()], comparators=[ast.Name(id='kwargs', ctx=ast.Load())]) new_ret = ast.If(test=check, body=check_body, orelse=[], lineno=self.__get_line()) return new_ret
def wrap_with_if(self, stmt_iter, candidates): """ Wraps statements in an `if` statement so that they only execute if no interrupts have triggered. Returns the `if` statement and a set of interrupts that might trigger inside the body. """ ifbody, additional_interrupts, _ = self.process_body(stmt_iter) if ifbody: comparison = ast.Compare(left=mk_name(self.flag_id), ops=[ast.Eq()], comparators=[mk_str(self.NONE)]) ifstmt = ast.If(test=comparison, body=ifbody, orelse=[]) return [ifstmt], additional_interrupts, set() else: # there are no statements, so we don't have to put an `if` around them. return [], additional_interrupts, set()
def visit_Compare(self, node): left = self.visit(node.left) ops = [self.visit(op) for op in node.ops] comparators = [self.visit(cmp) for cmp in node.comparators] right = comparators[0] if isinstance(right, ast.List): tmp = ast.Name(id=self._get_temp(), lineno=node.lineno) comparators[0] = tmp return ast.If( test=ast.Constant(value=True), body=[ ast.Assign(targets=[tmp], value=right, lineno=node.lineno), ast.Compare(left, ops, comparators, lineno=node.lineno), ], orelse=[], lineno=node.lineno, ) return node
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 check(left, ops, rights): self.start_frame() op = ops.pop(0) right = self.make_primitive(rights.pop(0)) if ops: body = check(right, ops, rights) else: body = [mk_assign(target, mk_name("True"))] test = self.id_factory("test") self.execute( mk_assign( test, ast.Compare(left=left, ops=[op], comparators=[right]))) self.execute(ast.If(test=mk_name(test), body=body, orelse=[])) return self.end_frame()
def to_ast(self): call_func = ast_mod.Attribute(value=ast_mod.Name(id=self.module, ctx=ast_mod.Load()), attr=self.funcdef.name, ctx=ast_mod.Load()) call = ast_mod.Call(func=call_func, args=self.args, keywords=[]) if self.return_result is None: ops = [ast_mod.IsNot()] comparators = [ast_mod.Constant(value=None)] elif isinstance(self.return_result, nodes.NameConstant): ops = [ast_mod.Is()] comparators = [ast_mod.Constant(value=self.return_result.value)] else: ops = [ast_mod.Eq()] comparators = [self.return_result.to_ast()] return ast_mod.Assert(test=ast_mod.Compare(left=call, ops=ops, comparators=comparators), msg=None)
def visit_Assign(self, node: ast.Assign): if not isinstance(node.value, ast.Call): return self.generic_visit(node) if len(node.targets) != 1: return self.generic_visit(node) target = node.targets[0] if isinstance(target, ast.Subscript): target = target.value if not isinstance(target, ast.Name): return self.generic_visit(node) tname: str = target.id callnode: ast.Call = node.value fname = astunparse.unparse(callnode.func)[:-1] if fname not in ('min', 'max'): return self.generic_visit(node) if len(callnode.args) != 2: raise NotImplementedError('Arguments to min/max (%d) != 2' % len(callnode.args)) result = [] names = [] for i, arg in enumerate(callnode.args): newname = '__dace_%s%d_%s' % (fname, i, tname) names.append(newname) result.append(ast.Assign(targets=[ast.Name(id=newname)], value=arg)) result.append( ast.Assign( targets=node.targets, value=ast.IfExp( test=ast.Compare(left=ast.Name(id=names[0]), ops=[ast.Lt()], comparators=[ast.Name(id=names[1])]), body=ast.Name(id=names[0]) if fname == 'min' else ast.Name( id=names[1]), orelse=ast.Name(id=names[1]) if fname == 'min' else ast.Name(id=names[0])))) self.count += 1 return result
def visit_Compare(self, node): node = self.generic_visit(node) if len(node.ops) > 1: # in case we have more than one compare operator # we generate an auxillary function # that lazily evaluates the needed parameters imported_ids = self.passmanager.gather(ImportedIds, node, self.ctx) imported_ids = sorted(imported_ids) binded_args = [ast.Name(i, ast.Load()) for i in imported_ids] # name of the new function forged_name = "{0}_compare{1}".format(self.prefix, len(self.compare_functions)) # call site call = ast.Call(ast.Name(forged_name, ast.Load()), binded_args, [], None, None) # new function arg_names = [ast.Name(i, ast.Param()) for i in imported_ids] args = ast.arguments(arg_names, None, None, []) body = [] # iteratively fill the body (yeah, feel your body!) body.append(ast.Assign([ast.Name('$0', ast.Store())], node.left)) for i, exp in enumerate(node.comparators): body.append(ast.Assign([ast.Name('${}'.format(i+1), ast.Store())], exp)) cond = ast.Compare(ast.Name('${}'.format(i), ast.Load()), [node.ops[i]], [ast.Name('${}'.format(i+1), ast.Load())]) body.append(ast.If(cond, [ast.Pass()], [ast.Return(ast.Num(0))])) body.append(ast.Return(ast.Num(1))) forged_fdef = ast.FunctionDef(forged_name, args, body, []) self.compare_functions.append(forged_fdef) return call else: return node
def genAlternative( o: ast.Name, fieldName: str, processerFunc: ast.Attribute ) -> typing.Iterator[typing.Union[ast.Assign, ast.If]]: fe = ast.Name(id=fieldName, ctx=ast.Load()) yield ast.Assign( targets=[ast.Name(id=fieldName, ctx=ast.Store())], value=unifiedGetAttr(o, fieldName), type_comment=None, ) yield ast.If( test=ast.Compare(left=fe, ops=[ast.IsNot()], comparators=[ASTNone]), body=[ ast.Return(value=ast.Call( func=processerFunc, args=[fe], keywords=[], )) ], orelse=[], )
def visit_Compare(self, node): if len(node.ops) == 1: if isinstance(node.ops[0], ast.In): node = ast.Call( func=ast.Name("np.isin"), args=[node.left, node.comparators[0]], keywords=[], ) elif len(node.ops) >= 2: # from pandas/core/computation/expr.py left = node.left values = [] for op, comp in zip(node.ops, node.comparators): new_node = self.visit( ast.Compare(comparators=[comp], left=left, ops=[op])) left = comp values.append(new_node) return self.visit(ast.BoolOp(op=ast.And(), values=values)) self.generic_visit(node) return node
def invert(node): """ Invert the operation in an ast node object (get its negation). Args: node: An ast node object. Returns: An ast node object containing the inverse (negation) of the input node. """ inverse = { ast.Eq: ast.NotEq, ast.NotEq: ast.Eq, ast.Lt: ast.GtE, ast.LtE: ast.Gt, ast.Gt: ast.LtE, ast.GtE: ast.Lt, ast.Is: ast.IsNot, ast.IsNot: ast.Is, ast.In: ast.NotIn, ast.NotIn: ast.In } # how to invert expression like 1 < b < 2?, it seems like the follow code only invert the first operand if type(node) == ast.Compare: op = type(node.ops[0]) inverse_node = ast.Compare(left=node.left, ops=[inverse[op]()], comparators=node.comparators) # is the following three lines necessary? elif isinstance(node, ast.BinOp) and type(node.op) in inverse: op = type(node.op) inverse_node = ast.BinOp(node.left, inverse[op](), node.right) elif type(node) == ast.NameConstant and node.value in [True, False]: inverse_node = ast.NameConstant(value=not node.value) else: inverse_node = ast.UnaryOp(op=ast.Not(), operand=node) return inverse_node
def rename_variables(astnode, env): if isinstance(astnode, ast.BoolOp): fn = 'z3.And' if isinstance(astnode.op, ast.And) else 'z3.Or' return ast.Call(ast.Name(fn, None), [rename_variables(i, env) for i in astnode.values], []) elif isinstance(astnode, ast.BinOp): return ast.BinOp(rename_variables(astnode.left, env), astnode.op, rename_variables(astnode.right, env)) elif isinstance(astnode, ast.UnaryOp): if isinstance(astnode.op, ast.Not): return ast.Call(ast.Name('z3.Not', None), [rename_variables(astnode.operand, env)], []) else: return ast.UnaryOp(astnode.op, rename_variables(astnode.operand, env)) elif isinstance(astnode, ast.Call): return ast.Call(astnode.func, [rename_variables(i, env) for i in astnode.args], astnode.keywords) elif isinstance(astnode, ast.Compare): return ast.Compare( rename_variables(astnode.left, env), astnode.ops, [rename_variables(i, env) for i in astnode.comparators]) elif isinstance(astnode, ast.Name): if astnode.id not in env: env[astnode.id] = 0 num = env[astnode.id] return ast.Name('_%s_%d' % (astnode.id, num), astnode.ctx) # fixed elif isinstance(astnode, ast.Subscript): identifier = to_src(astnode) name = identifier[:-3] + '_' + identifier[-2] if name not in env: env[name] = 0 num = env[name] return ast.Name('_%s_%d' % (name, num), astnode.ctx) elif isinstance(astnode, ast.Return): return ast.Return(rename_variables(astnode.value, env)) else: return astnode
def p_expr_cmp(self, p): '''expr : expr EQ expr | expr NE expr | expr LT expr | expr LE expr | expr GT expr | expr GE expr''' p[0] = ast.Call(func=ast.Name(id='int', ctx=ast.Load(), lineno=p.lineno(1), col_offset=p.lexpos(1)), args=[ ast.Compare(left=p[1], ops=[self.binop[p[2]]()], comparators=[p[3]], lineno=p.lineno(1), col_offset=p.lexpos(1)) ], keywords=[], lineno=p.lineno(1), col_offset=p.lexpos(1))
def branch_dist_boolop(op, values, args): if len(values) == 1: return branch_dist(values[0], args) else: return ast.Call(func=ast.Lambda( args=ast.arguments( args=[ast.arg(arg=args.lambda_arg, annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=ast.IfExp(test=ast.Compare( left=ast.Name(id=args.lambda_arg), ops=[ast.Gt() if isinstance(op, ast.And) else ast.LtE()], comparators=[ast.Num(n=0)]), body=ast.Name(id=args.lambda_arg), orelse=branch_dist_boolop(op, values[1:], args))), args=[branch_dist(values[0], args)], keywords=[])
def python_ast(self): os = self.operator op = getattr(ast, binary_operators_methods[os])(lineno=self.line, col_offset=self.column) if os == '+' or os == '-' or os == '/' or os == '*' or os == '%': return ast.BinOp(self.left.python_ast(), op, self.right.python_ast(), lineno=self.line, col_offset=self.column) elif os == 'a': return ast.BoolOP(self.left.python_ast(), op, self.right.python_ast(), lineno=self.line, col_offset=self.column) else: return ast.Compare(self.left.python_ast(), [op], [self.right.python_ast()], lineno=self.line, col_offset=self.column)