def to_node(self): if len(self.operator) == 0: return self.left.to_node() else: right_nodes = [] comp_operator = [] for i in range(len(self.right)): right_nodes.append(self.right[i].to_node()) if self.operator[i] in ['<', 'is lower than']: comp_operator.append(ast.Lt()) elif self.operator[i] in ['<=', 'is lower or equal to']: comp_operator.append(ast.LtE()) elif self.operator[i] in ['>', 'is greater than']: comp_operator.append(ast.Gt()) elif self.operator[i] in ['>=', 'is greater or equal to']: comp_operator.append(ast.GtE()) elif self.operator[i] in ['==', 'is equal to']: comp_operator.append(ast.Eq()) elif self.operator[i] in ['!=', 'is different from', 'is not equal to']: comp_operator.append(ast.NotEq()) elif self.operator[i] == 'in': comp_operator.append(ast.In()) elif self.operator[i] == 'not in': comp_operator.append(ast.NotIn()) elif self.operator[i] == 'is': comp_operator.append(ast.Is()) elif self.operator[i] == 'is not': comp_operator.append(ast.IsNot()) else: raise Exception("Unrecognized argument in Comparison") return ast.Compare(left=self.left.to_node(), ops=comp_operator, comparators=right_nodes)
def compare_is(left, right, invert=False): return ast.Compare( left=ast.Name(id=left, ctx=ast.Load(), lineno=1, col_offset=0), ops=[ast.Is() if not invert else ast.IsNot()], comparators=[ast.Name(id=right, ctx=ast.Load(), lineno=1, col_offset=0)], lineno=1, col_offset=0)
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. """ # Using parse because it is different between py2 and py3. AST_NONE = ast.parse("None").body[0].value val_is_none = ast.Compare(node, [ast.Is()], [AST_NONE]) send_warning = ast.parse( """ from _pytest.warning_types import PytestWarning from warnings import warn_explicit warn_explicit( PytestWarning('asserting the value None, please use "assert is None"'), category=None, filename={filename!r}, lineno={lineno}, ) """.format( filename=module_path.strpath, lineno=lineno ) ).body return ast.If(val_is_none, send_warning, [])
def visit_primitive_assertion(self, assertion: pa.PrimitiveAssertion) -> None: """ Creates an assertion of form "assert var0 == value" or assert var0 is False, if the value is a bool. Args: assertion: the assertion that is visited. """ if isinstance(assertion.value, bool): self._nodes.append( self._create_constant_assert( assertion.source, ast.Is(), assertion.value ) ) elif isinstance(assertion.value, float): self._nodes.append( self._create_float_delta_assert(assertion.source, assertion.value) ) else: self._nodes.append( self._create_constant_assert( assertion.source, ast.Eq(), assertion.value ) )
def missingCheck(check: ast.Compare, el: ast.Subscript, default: bool) -> ast.BoolOp: """Creates AST nodes corresponding to check whether the `el` is None, if it is returns `default`""" return ast.BoolOp(op=(ast.Or() if default else ast.And()), values=[ ast.Compare( left=el, ops=[(ast.Is() if default else ast.IsNot())], comparators=[noneCnst]), check ])
def visit_Compare(self, node): # cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn print(" in MyTransformer.visit_Compare()") print(" node =", node) print(" op =", node.ops[0]) curr_op = node.ops[0] comp_negate = curr_op rand_num = random.randint(1, 10) if rand_num >= 7: print(" negating...") if isinstance(curr_op, ast.Eq): comp_negate = ast.NotEq() elif isinstance(curr_op, ast.NotEq): comp_negate = ast.Eq() elif isinstance(curr_op, ast.Lt): comp_negate = ast.GtE() elif isinstance(curr_op, ast.LtE): comp_negate = ast.Gt() elif isinstance(curr_op, ast.Gt): comp_negate = ast.LtE() elif isinstance(curr_op, ast.GtE): comp_negate = ast.Lt() elif isinstance(curr_op, ast.Is): comp_negate = ast.IsNot() elif isinstance(curr_op, ast.IsNot): comp_negate = ast.Is() elif isinstance(curr_op, ast.In): comp_negate = ast.NotIn() elif isinstance(curr_op, ast.NotIn): comp_negate = ast.In() else: comp_negate = ast.Eq() else: print(" mixing up...") if isinstance(curr_op, ast.Lt): comp_negate = ast.LtE() elif isinstance(curr_op, ast.LtE): comp_negate = ast.And() elif isinstance(curr_op, ast.Gt): comp_negate = ast.Or() elif isinstance(curr_op, ast.GtE): comp_negate = ast.Gt() elif isinstance(curr_op, ast.Is): comp_negate = ast.Gt() elif isinstance(curr_op, ast.IsNot): comp_negate = ast.Lt() elif isinstance(curr_op, ast.In): comp_negate = ast.In( ) #leave the same for for loops (for x in this) elif isinstance(curr_op, ast.NotIn): comp_negate = ast.Lt() else: comp_negate = ast.Eq() print(" new comparator =", comp_negate) # create negated node | Compare(expr left, cmpop* ops, expr* comparators) new_node = node new_node.ops = [comp_negate] ast.copy_location(new_node, node) ast.fix_missing_locations(new_node) return new_node
def visit_none_assertion(self, assertion: na.NoneAssertion) -> None: """ Creates an assertion of form "assert var0 is None" or "assert var0 is not None". Args: assertion: the assertion that is visited. """ self._nodes.append( self._create_constant_assert( assertion.source, ast.Is() if assertion.value else ast.IsNot(), None))
def visit_Compare(self, node): self.generic_visit(node) self.binop_count += 1 if (self.binop_count == self.count_of_node_to_mutate): new_node = copy.deepcopy(node) print('IN COMPARE') print('THIS IS THE PREVIOUS OP', node.ops) for (i, op) in enumerate(node.ops): if (isinstance(op, ast.Gt)): num = random.randint(0, 2) if num == 0: new_node.ops[i] = ast.GtE() if num == 1: new_node.ops[i] = ast.LtE() if num == 2: new_node.ops[i] = ast.Lt() if (isinstance(op, ast.GtE)): num = random.randint(0, 2) if num == 0: new_node.ops[i] = ast.Gt() if num == 1: new_node.ops[i] = ast.Lt() if num == 2: new_node.ops[i] = ast.LtE() if (isinstance(op, ast.Lt)): num = random.randint(0, 2) if num == 0: new_node.ops[i] = ast.LtE() if num == 1: new_node.ops[i] = ast.GtE() if num == 2: new_node.ops[i] = ast.Gt() if (isinstance(op, ast.LtE)): num = random.randint(0, 2) if num == 0: new_node.ops[i] = ast.Lt() if num == 1: new_node.ops[i] = ast.GtE() if num == 2: new_node.ops[i] = ast.Gt() if (isinstance(op, ast.Eq)): new_node.ops[i] = ast.NotEq() if (isinstance(op, ast.NotEq)): new_node.ops[i] = ast.Eq() if (isinstance(op, ast.Is)): new_node.ops[i] = ast.IsNot() if (isinstance(op, ast.IsNot)): new_node.ops[i] = ast.Is() print('THIS IS THE NEW OP', new_node.ops) print('I AM CREATING A NEW NODE HERE', self.binop_count) return new_node return node
def 比较(片段): 对照表 = { '>': ast.Gt(), '>=': ast.GtE(), '<': ast.Lt(), '<=': ast.LtE(), '==': ast.Eq(), '!=': ast.NotEq(), '===': ast.Is(), '!==': ast.IsNot() } return 语法树.比较(前项=片段[0], 操作符=对照表[片段[1].getstr()], 后项=片段[2], 片段=片段)
def p_comp_op(p): '''comp_op : ">" | "<" | OP_EQ | OP_GE | OP_LE | OP_NE | OP_NNE | TAG_IN | TAG_NOT TAG_IN | TAG_IS | TAG_IS TAG_NOT''' if len(p) == 2: if p.get_item(1).type == 'OP_EQ': p[0] = ast.Eq() elif p.get_item(1).type == '>': p[0] = ast.Gt() elif p.get_item(1).type == '<': p[0] = ast.Lt() elif p.get_item(1).type == 'OP_GE': p[0] = ast.GtE() elif p.get_item(1).type == 'OP_LE': p[0] = ast.LtE() elif p.get_item(1).type == 'OP_NE': p[0] = ast.NotEq() elif p.get_item(1).type == 'OP_NNE': p[0] = ast.NotEq() elif p[1] == 'is': p[0] = ast.Is() elif p[1] == 'in': p[0] = ast.In() elif len(p) == 3: if p[1] == 'is': p[0] = ast.IsNot() elif p[1] == 'not': p[0] = ast.NotIn() return
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 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 handle_body(self, body): """ :type body: list[ast.AST] :rtype: list[ast.AST] """ parts = [[]] for s in body: if isinstance(s, GotoLabel): parts += [s, []] else: parts[-1].append(s) r = [] for l in parts: if not l: continue if isinstance(l, GotoLabel): r += self.handle_goto_label(l) else: sr = [] for s in l: if isinstance(s, ast.If): assert not s.orelse assert len(s.body) == 1 assert isinstance(s.body[0], GotoStatement) sr += [ ast.If(test=s.test, orelse=[], body=self.handle_goto_stmnt(s.body[0])) ] elif isinstance(s, (ast.While, ast.For)): assert False, "not expected: %r" % s elif isinstance(s, GotoStatement): sr += self.handle_goto_stmnt(s) else: sr += [s] test_ast = ast.Compare() test_ast.ops = [ast.Is()] test_ast.left = ast.Name(id=self.gotoVarName, ctx=ast.Store()) test_ast.comparators = [ast.Name(id="None", ctx=ast.Load())] r += [ast.If(test=test_ast, body=sr, orelse=[])] return r
def visit_CmpOp(self, node: CmpOp, *args, **kwargs) -> C.cmpop: if node == CmpOp.Eq: return C.Eq() elif node == CmpOp.NotEq: return C.NotEq() elif node == CmpOp.Lt: return C.Lt() elif node == CmpOp.Lte: return C.Lte() elif node == CmpOp.Gt: return C.Gt() elif node == CmpOp.Gte: return C.Gte() elif node == CmpOp.Is: return C.Is() elif node == CmpOp.IsNot: return C.IsNot() elif node == CmpOp.In: return C.In() elif node == CmpOp.NotIn: return C.NotIn() else: raise Exception(f'unknown CmpOp {node!r}')
def comparison(self) -> ast.expr: left: ast.expr = self.bit_or() operators: list[ast.cmpop] = [] extra: list[ast.expr] = [] while self.match_(*TokenGroup.SINGLE_COMPARISON, TokenType.NOT): if self.previous().type == TokenType.IS: if self.match_(TokenType.NOT): operator = ast.IsNot() else: operator = ast.Is() elif self.previous().type == TokenType.NOT: self.consume(TokenType.IN, "'in' must follow 'not' in comparison.") operator = ast.NotIn() else: operator = COMPARISON_OPERATORS[self.previous().type]() right = self.bit_or() operators.append(operator) extra.append(right) if operators: return ast.Compare(left, operators, extra, **self.get_loc(left, extra[-1])) else: return left
def as_ast(dct): """See https://docs.python.org/2/library/ast.html""" if dct['ast_type'] == "Module": return ast.Module(dct["body"]) elif dct['ast_type'] == "Interactive": return ast.Interactive(dct["body"]) elif dct['ast_type'] == "Expression": return ast.Expression(dct["body"]) elif dct['ast_type'] == "Suite": return ast.Suite(dct["body"]) elif dct['ast_type'] == "FunctionDef": return ast.FunctionDef(dct["name"], dct["args"], dct["body"], dct["decorator_list"]) elif dct['ast_type'] == "ClassDef": return ast.ClassDef(dct["name"], dct["bases"], dct["body"], dct["decorator_list"]) elif dct['ast_type'] == "Return": return ast.Return(dct["value"]) elif dct['ast_type'] == "Delete": return ast.Delete(dct["targets"]) elif dct['ast_type'] == "Assign": return ast.Assign(dct["targets"], dct["value"]) elif dct['ast_type'] == "AugAssign": return ast.AugAssign(dct["target"], dct["op"], dct["value"]) elif dct['ast_type'] == "Print": return ast.Print(dct["dest"], dct["values"], dct["nl"]) elif dct['ast_type'] == "For": return ast.For(dct["target"], dct["iter"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "While": return ast.While(dct["test"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "If": return ast.If(dct["test"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "With": return ast.With(dct["context_expr"], dct["optional_vars"], dct["body"]) elif dct['ast_type'] == "Raise": return ast.Raise(dct["type"], dct["inst"], dct["tback"]) elif dct['ast_type'] == "TryExcept": return ast.TryExcept(dct["body"], dct["handlers"], dct["orelse"]) elif dct['ast_type'] == "TryFinally": return ast.TryFinally(dct["body"], dct["finalbody"]) elif dct['ast_type'] == "Assert": return ast.Assert(dct["test"], dct["msg"]) elif dct['ast_type'] == "Import": return ast.Import(dct["names"]) elif dct['ast_type'] == "ImportFrom": return ast.ImportFrom(dct["module"], dct["names"], dct["level"]) elif dct['ast_type'] == "Exec": return ast.Exec(dct["body"], dct["globals"], dct["locals"]) elif dct['ast_type'] == "Global": return ast.Global(dct["names"]) elif dct['ast_type'] == "Expr": return ast.Expr(dct["value"]) elif dct['ast_type'] == "Pass": return ast.Pass() elif dct['ast_type'] == "Break": return ast.Break() elif dct['ast_type'] == "Continue": return ast.Continue() elif dct['ast_type'] == "BoolOp": return ast.BoolOp(dct["op"], dct["values"]) elif dct['ast_type'] == "BinOp": return ast.BinOp(dct["left"], dct["op"], dct["right"]) elif dct['ast_type'] == "UnaryOp": return ast.UnaryOp(dct["op"], dct["operand"]) elif dct['ast_type'] == "Lambda": return ast.Lambda(dct["args"], dct["body"]) elif dct['ast_type'] == "IfExp": return ast.IfExp(dct["test"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "Dict": return ast.Dict(dct["keys"], dct["values"]) elif dct['ast_type'] == "Set": return ast.Set(dct["elts"]) elif dct['ast_type'] == "ListComp": return ast.ListComp(dct["elt"], dct["generators"]) elif dct['ast_type'] == "SetComp": return ast.SetComp(dct["elt"], dct["generators"]) elif dct['ast_type'] == "DictComp": return ast.DictComp(dct["key"], dct["value"], dct["generators"]) elif dct['ast_type'] == "GeneratorExp": return ast.GeneratorExp(dct["elt"], dct["generators"]) elif dct['ast_type'] == "Yield": return ast.Yield(dct["value"]) elif dct['ast_type'] == "Compare": return ast.Compare(dct["left"], dct["ops"], dct["comparators"]) elif dct['ast_type'] == "Call": return ast.Call(dct["func"], dct["args"], dct["keywords"], dct["starargs"], dct["kwargs"]) elif dct['ast_type'] == "Repr": return ast.Repr(dct["value"]) elif dct['ast_type'] == "Num": return ast.Num(dct["n"]) elif dct['ast_type'] == "Str": # Converting to ASCII return ast.Str(dct["s"].encode('ascii', 'ignore')) elif dct['ast_type'] == "Attribute": return ast.Attribute(dct["value"], dct["attr"], dct["ctx"]) elif dct['ast_type'] == "Subscript": return ast.Subscript(dct["value"], dct["slice"], dct["ctx"]) elif dct['ast_type'] == "Name": return ast.Name(dct["id"], dct["ctx"]) elif dct['ast_type'] == "List": return ast.List(dct["elts"], dct["ctx"]) elif dct['ast_type'] == "Tuple": return ast.Tuple(dct["elts"], dct["ctx"]) elif dct['ast_type'] == "Load": return ast.Load() elif dct['ast_type'] == "Store": return ast.Store() elif dct['ast_type'] == "Del": return ast.Del() elif dct['ast_type'] == "AugLoad": return ast.AugLoad() elif dct['ast_type'] == "AugStore": return ast.AugStore() elif dct['ast_type'] == "Param": return ast.Param() elif dct['ast_type'] == "Ellipsis": return ast.Ellipsis() elif dct['ast_type'] == "Slice": return ast.Slice(dct["lower"], dct["upper"], dct["step"]) elif dct['ast_type'] == "ExtSlice": return ast.ExtSlice(dct["dims"]) elif dct['ast_type'] == "Index": return ast.Index(dct["value"]) elif dct['ast_type'] == "And": return ast.And() elif dct['ast_type'] == "Or": return ast.Or() elif dct['ast_type'] == "Add": return ast.Add() elif dct['ast_type'] == "Sub": return ast.Sub() elif dct['ast_type'] == "Mult": return ast.Mult() elif dct['ast_type'] == "Div": return ast.Div() elif dct['ast_type'] == "Mod": return ast.Mod() elif dct['ast_type'] == "Pow": return ast.Pow() elif dct['ast_type'] == "LShift": return ast.LShift() elif dct['ast_type'] == "RShift": return ast.RShift() elif dct['ast_type'] == "BitOr": return ast.BitOr() elif dct['ast_type'] == "BitXor": return ast.BitXor() elif dct['ast_type'] == "BitAnd": return ast.BitAnd() elif dct['ast_type'] == "FloorDiv": return ast.FloorDiv() elif dct['ast_type'] == "Invert": return ast.Invert() elif dct['ast_type'] == "Not": return ast.Not() elif dct['ast_type'] == "UAdd": return ast.UAdd() elif dct['ast_type'] == "USub": return ast.USub() elif dct['ast_type'] == "Eq": return ast.Eq() elif dct['ast_type'] == "NotEq": return ast.NotEq() elif dct['ast_type'] == "Lt": return ast.Lt() elif dct['ast_type'] == "LtE": return ast.LtE() elif dct['ast_type'] == "Gt": return ast.Gt() elif dct['ast_type'] == "GtE": return ast.GtE() elif dct['ast_type'] == "Is": return ast.Is() elif dct['ast_type'] == "IsNot": return ast.IsNot() elif dct['ast_type'] == "In": return ast.In() elif dct['ast_type'] == "NotIn": return ast.NotIn() elif dct['ast_type'] == "comprehension": return ast.comprehension(dct["target"], dct["iter"], dct["ifs"]) elif dct['ast_type'] == "ExceptHandler": return ast.ExceptHandler(dct["type"], dct["name"], dct["body"]) elif dct['ast_type'] == "arguments": return ast.arguments(dct["args"], dct["vararg"], dct["kwarg"], dct["defaults"]) elif dct['ast_type'] == "keyword": return ast.keyword(dct["arg"], dct["value"]) elif dct['ast_type'] == "alias": return ast.alias(dct["name"], dct["asname"]) else: return dct
import unicodedata from hypothesis import assume from hypothesis._strategies import booleans from hypothesis.searchstrategy import SearchStrategy from hypothesis.strategies import integers, lists, binary, sampled_from, recursive, dictionaries from hypothesis.strategies import text, composite, one_of, floats, complex_numbers, characters, none comparison_operators = sampled_from([ ast.Eq(), ast.NotEq(), ast.Lt(), ast.LtE(), ast.Gt(), ast.GtE(), ast.Is(), ast.IsNot(), ast.In(), ast.NotIn() ]) # region: Literals @composite def Num(draw) -> ast.AST: def to_node(n) -> ast.AST: if isinstance(n, int): return ast.Num(n) if n >= 0 else ast.UnaryOp( ast.USub(), ast.Num(abs(n))) elif isinstance(n, float):
from _pytest._io.saferepr import saferepr from _pytest._version import version from _pytest.assertion import util from _pytest.assertion.util import ( # noqa: F401 format_explanation as _format_explanation, ) from _pytest.pathlib import fnmatch_ex from _pytest.pathlib import PurePath # pytest caches rewritten pycs in __pycache__. PYTEST_TAG = "{}-pytest-{}".format(sys.implementation.cache_tag, version) PYC_EXT = ".py" + (__debug__ and "c" or "o") PYC_TAIL = "." + PYTEST_TAG + PYC_EXT AST_IS = ast.Is() AST_NONE = ast.NameConstant(None) class AssertionRewritingHook: """PEP302/PEP451 import hook which rewrites asserts.""" def __init__(self, config): self.config = config try: self.fnpats = config.getini("python_files") except ValueError: self.fnpats = ["test_*.py", "*_test.py"] self.session = None self._rewritten_names = set() self._must_rewrite = set()
def __init__(self, str, lineno=0): self.value = str self.lineno = lineno op_ast_map = { '+': ast.Add(), '-': ast.Sub(), '*': ast.Mult(), '/': ast.Div(), '%': ast.Mod(), '**': ast.Pow(), '<<': ast.LShift(), '>>': ast.RShift(), '|': ast.BitOr(), '^^': ast.BitXor(), '&&': ast.BitAnd(), '//': ast.FloorDiv(), '==': ast.Eq(), '!=': ast.NotEq(), '<': ast.Lt(), '<=': ast.LtE(), '>': ast.Gt(), '>=': ast.GtE(), 'is': ast.Is(), 'is_not': ast.IsNot(), 'in': ast.In(), 'not_in': ast.NotIn(), 'and': ast.And(), 'or': ast.Or() }
def as_ast(self, ast_state): return ast.Compare(ast_column(ast_state, self.column), [ast.Is()], [ast.Name('None', ast.Load())])
def test_empty_init(self): # Jython 2.5.0 did not allow empty constructors for many ast node types # but CPython ast nodes do allow this. For the moment, I don't see a # reason to allow construction of the super types (like ast.AST and # ast.stmt) as well as the op types that are implemented as enums in # Jython (like boolop), but I've left them in but commented out for # now. We may need them in the future since CPython allows this, but # it may fall under implementation detail. #ast.AST() ast.Add() ast.And() ast.Assert() ast.Assign() ast.Attribute() ast.AugAssign() ast.AugLoad() ast.AugStore() ast.BinOp() ast.BitAnd() ast.BitOr() ast.BitXor() ast.BoolOp() ast.Break() ast.Call() ast.ClassDef() ast.Compare() ast.Continue() ast.Del() ast.Delete() ast.Dict() ast.Div() ast.Ellipsis() ast.Eq() ast.Exec() ast.Expr() ast.Expression() ast.ExtSlice() ast.FloorDiv() ast.For() ast.FunctionDef() ast.GeneratorExp() ast.Global() ast.Gt() ast.GtE() ast.If() ast.IfExp() ast.Import() ast.ImportFrom() ast.In() ast.Index() ast.Interactive() ast.Invert() ast.Is() ast.IsNot() ast.LShift() ast.Lambda() ast.List() ast.ListComp() ast.Load() ast.Lt() ast.LtE() ast.Mod() ast.Module() ast.Mult() ast.Name() ast.Not() ast.NotEq() ast.NotIn() ast.Num() ast.Or() ast.Param() ast.Pass() ast.Pow() ast.Print() ast.RShift() ast.Raise() ast.Repr() ast.Return() ast.Slice() ast.Store() ast.Str() ast.Sub() ast.Subscript() ast.Suite() ast.TryExcept() ast.TryFinally() ast.Tuple() ast.UAdd() ast.USub() ast.UnaryOp() ast.While() ast.With() ast.Yield() ast.alias() ast.arguments() #ast.boolop() #ast.cmpop() ast.comprehension() #ast.excepthandler() #ast.expr() #ast.expr_context() ast.keyword()
def translate(node, st=None, strings=None, funcName=False): if isinstance(node, oast.Add): left = translate(node.left, st, strings, funcName) right = translate(node.right, st, strings, funcName) return ast.Add(left, right) elif isinstance(node, oast.And): left = translate(node.nodes[0], st, strings, funcName) right = translate(node.nodes[1], st, strings, funcName) return ast.And(left, right) elif isinstance(node, oast.Assign): # Translate the right hand side first so it can use the older version # of the left hand side. exp = translate(node.expr, st, strings, funcName) var = node.nodes.pop() if isinstance(var, oast.AssAttr): string = strings.setdefault(var.attrname, ast.String(var.attrname)) var = translate(var.expr, st, strings, funcName) return ast.SetAttr(var, string, exp) else: var = translate(var, st, strings, funcName) return ast.Assign(var, exp) elif isinstance(node, oast.AssName): return st.getSymbol(node.name, True) elif isinstance(node, oast.CallFunc): name = translate(node.node, st, strings, True) args = [translate(a, st, strings) for a in node.args] return ast.FunctionCall(name, *args) elif isinstance(node, oast.Class): bases = [translate(base, st, strings, funcName) for base in node.bases] body = translate(node.code, st, strings, funcName) body = ast.BasicBlock(body) sym = st.getSymbol(node.name, True) name = st.getName(node.name, True) # This is here temporarily. It will be moved to the typify pass # later. sym['type'] = 'class' klass = ast.Class(name, bases, body) return ast.Assign(sym, klass) elif isinstance(node, oast.Compare): left = translate(node.expr, st, strings, funcName) op, right = node.ops[0] right = translate(right, st, strings, funcName) if op == '==': return ast.Eq(left, right) elif op == '!=': return ast.Ne(left, right) elif op == 'is': return ast.Is(left, right) elif isinstance(node, oast.Const): return ast.Integer(node.value) elif isinstance(node, oast.Dict): pairs = {} for pair in node.items: key, value = pair key = translate(key, st, strings, funcName) value = translate(value, st, strings, funcName) pairs[key] = value return ast.Dictionary(pairs) elif isinstance(node, oast.Discard): return translate(node.expr, st, strings, funcName) elif isinstance(node, oast.Div): left = translate(node.left, st, strings, funcName) right = translate(node.right, st, strings, funcName) return ast.Div(left, right) elif isinstance(node, oast.Function): sym = st.getSymbol(node.name, True) name = st.getName(node.name, True) sym['type'] = 'function' newST = SymbolTable(st) argSymbols = [ newST.getSymbol(argName, True) for argName in node.argnames ] body = translate(node.code, newST, strings, funcName) body = ast.BasicBlock(body) fun = ast.Function(name, argSymbols, body, newST) fun['simplified'] = False st.update(newST) return ast.Assign(sym, fun) elif isinstance(node, oast.Getattr): exp = translate(node.expr, st, strings, funcName) name = strings.setdefault(node.attrname, ast.String(node.attrname)) return ast.GetAttr(exp, name) elif isinstance(node, oast.If): tests = node.tests cond, then = tests.pop(0) # Translate the conditional expression. cond = translate(cond, st, strings) # Snapshot the SymbolTable st.snapshot() # Translate the 'then' clause. then = translate(then, st, strings, funcName) then = ast.BasicBlock(then) # Roll-back the SymbolTable for the 'else' clause. st.rollback() # Translate the 'else' clause. if len(tests) > 0: els = [translate(oast.If(tests, node.else_), st, funcName)] else: els = translate(node.else_, st, strings, funcName) els = ast.BasicBlock(els) return ast.If(cond, then, els, st) elif isinstance(node, oast.IfExp): cond = translate(node.test, st, strings, funcName) then = translate(node.then, st, strings, funcName) els = translate(node.else_, st, strings, funcName) return ast.IfExp(cond, then, els) elif isinstance(node, oast.Lambda): name = st.getName('lambda', True) newST = SymbolTable(st) argSymbols = map(lambda name: newST.getSymbol(name, True), node.argnames) code = ast.Return(translate(node.code, newST, strings, funcName)) block = ast.BasicBlock([code]) fun = ast.Function(name, argSymbols, block, newST) fun['simplified'] = False st.update(newST) return fun elif isinstance(node, oast.List): elements = [] for n in node.nodes: elements.append(translate(n, st, strings, funcName)) return ast.List(elements) elif isinstance(node, oast.Module): # Create a new SymbolTable for this module. st = SymbolTable() strings = {} children = translate(node.node, st, strings, funcName) block = ast.BasicBlock(children) fun = ast.Function(st.getBIF('main'), [], block, st) # Mark the main function as migrated so that it doesn't get moved # later. fun['simplified'] = True return ast.Module([fun], strings) elif isinstance(node, oast.Mul): left = translate(node.left, st, strings, funcName) right = translate(node.right, st, strings, funcName) return ast.Mul(left, right) elif isinstance(node, oast.Name): ret = 'input_int' if node.name == 'input' else node.name if ret == 'input_int': ret = st.getBIF(ret) else: if ret == 'True': ret = ast.Tru() elif ret == 'False': ret = ast.Fals() else: ret = st.getSymbol(ret) return ret elif isinstance(node, oast.Not): operand = translate(node.expr, st, strings, funcName) return ast.Not(operand) elif isinstance(node, oast.Or): left = translate(node.nodes[0], st, strings, funcName) right = translate(node.nodes[1], st, strings, funcName) return ast.Or(left, right) elif isinstance(node, oast.Printnl): children = [ translate(e, st, strings, funcName) for e in node.getChildNodes() ] children = util.flatten(children) return ast.FunctionCall(st.getBIF('print_any'), *children) elif isinstance(node, oast.Return): return ast.Return(translate(node.value, st, strings, funcName)) elif isinstance(node, oast.Stmt): stmts = [ translate(s, st, strings, funcName) for s in node.getChildNodes() ] return util.flatten(stmts) elif isinstance(node, oast.Sub): left = translate(node.left, st, strings, funcName) right = translate(node.right, st, strings, funcName) return ast.Sub(left, right) elif isinstance(node, oast.Subscript): sym = translate(node.expr, st, strings, funcName) sub = translate(node.subs[0], st, strings, funcName) return ast.Subscript(sym, sub) elif isinstance(node, oast.While): cond = translate(node.test, st, strings, funcName) body = translate(node.body, st, strings, funcName) body = ast.BasicBlock(body) return ast.While(cond, body, st) elif isinstance(node, oast.UnarySub): operand = translate(node.expr, st, strings, funcName) return ast.Negate(operand) else: raise Exception("Unsupported AST node encountered: {}".format( node.__class__.__name__))
def visit_ClassDef(self, node): if len(node.bases) > 1: raise Exception('Multiple inheritance not supported') self.visit(FunctionDef( node.name, arguments([], None, None, []), [ ast.If( ast.UnaryOp( ast.Not(), ast_call( ast_load('isinstance'), ast_load('this'), ast_load('arguments.callee'), ) ), [ ast.Return( ast_call( ast_load('new'), ast_load('arguments.callee'), ast_load('arguments'), ) ) ], [] ), ast.Assign( [ast_store('this.__class__')], ast_load('arguments.callee') ), ast.Expr( ast_call( ast_load('this.__bind__'), ast_load('this'), ), ), ast.If( ast.Compare( ast_call( ast_load('type'), ast_load('this.__init__'), ), [ast.IsNot()], [ast.Str('undefined')], ), [ ast.Expr( ast_call( ast_load('this.__init__.apply'), ast_load('this'), ast.Subscript( ast_load('arguments'), ast.Index(ast.Num(0)), ast.Load() ) ) ), ], [] ) ], [] )) self.push(ClassContext(self.stack[-1], node.name)) scope = self.stack[-1].scope if not node.bases: scope.prefix.pop() self.visit( ast.Assign( [ast_store('prototype')], ast.Dict( [ ast.Str('constructor'), ast.Str('__mro__') ], [ ast_load(node.name), ast.List([ast_load(node.name)], ast.Load()) ] ) ) ) scope.prefix.append('prototype') self.visit( ast.Assign( [ast_store('__bind__')], FunctionDef( '', arguments([ast_load('self')], None, None, []), [ ast.For( ast_store('i'), ast_load('this'), [ ast.If( ast.Compare( ast_call( ast_load('type'), ast.Subscript( ast_load('this'), ast.Index(ast_load('i')), ast.Load(), ) ), [ast.Is()], [ast.Str('function')] ), [ ast.Assign( [ast.Subscript( ast_load('this'), ast.Index(ast_load('i')), ast.Store(), )], ast_call( ast.Attribute( ast.Subscript( ast_load('this'), ast.Index(ast_load('i')), ast.Load(), ), 'bind', ast.Load(), ), ast_load('self'), ast_load('self'), ) ), ], [] ) ], [] ), ], [] ) ) ) else: base = node.bases[0] self.visit( ast.Assign( [ast_store(node.name, 'prototype')], ast_call( FunctionDef( '', arguments([], None, None, []), [ ast.Assign( [ast_store('tmp')], FunctionDef( '', arguments([], None, None, []), [], [] ) ), ast.Assign( [ast_store('tmp', 'prototype')], ast.Attribute(base, 'prototype', ast.Load()), ), ast.Return( ast_call( ast_load('new'), ast_load('tmp'), ) ) ], [] ), ) ) ) self.visit( ast.Assign( [ast_store(node.name, 'prototype.constructor')], ast_load(node.name) ) ) self.visit( ast.Assign( [ast_store(node.name, 'prototype.__base__')], base, ) ) self.visit( ast.Assign( [ast_store(node.name, 'prototype.__mro__')], ast_call( ast_load(node.name, 'prototype.__mro__.concat'), ast_load(node.name), ) ) ) for stmt in node.body: self.visit(stmt) self.pop() if node.decorator_list: arg = ast_load(node.name) for decorator in node.decorator_list: arg = ast_call(decorator, arg) self.visit( ast.Assign( [ast_store(node.name)], arg ) )
def visit_Compare(self, node): if isinstance(node.ops, ast.LtE): self.counter += 1 if self.counter == self.nodeToMutate: new_node = ast.Compare() new_node.left = node.left new_node.comparators = node.comparators new_node.ops = [ast.Gt()] print('changing lessThanEqual {} to greaterThan.'.format( self.counter)) return ast.copy_location(new_node, node) # helps debugging if isinstance(node.ops, ast.GtE): self.counter += 1 if self.counter == self.nodeToMutate: new_node = ast.Compare() new_node.left = node.left new_node.comparators = node.comparators new_node.op = [ast.Lt()] print('changing GTE {} to LT.'.format(self.counter)) return ast.copy_location(new_node, node) # helps debugging if isinstance(node.ops, ast.Gt): self.counter += 1 if self.counter == self.nodeToMutate: new_node = ast.Compare() new_node.left = node.left new_node.comparators = node.comparators new_node.ops = [ast.LtE()] print('changing GT {} to LtE.'.format(self.counter)) return ast.copy_location(new_node, node) # helps debugging if isinstance(node.ops, ast.Lt): self.counter += 1 if self.counter == self.nodeToMutate: new_node = ast.Compare() new_node.left = node.left new_node.comparators = node.comparators new_node.ops = [ast.GtE()] print('changing LT {} to GtE.'.format(self.counter)) return ast.copy_location(new_node, node) # helps debugging if isinstance(node.ops, ast.Eq): self.counter += 1 if self.counter == self.nodeToMutate: new_node = ast.Compare() new_node.left = node.left new_node.comparators = node.comparators new_node.ops = [ast.NotEq()] print('changing eq {} to neq.'.format(self.counter)) return ast.copy_location(new_node, node) # helps debugging if isinstance(node.ops, ast.NotEq): self.counter += 1 if self.counter == self.nodeToMutate: new_node = ast.Compare() new_node.left = node.left new_node.comparators = node.comparators new_node.ops = ast.Eq() print('changing neq {} to eq.'.format(self.counter)) return ast.copy_location(new_node, node) # helps debugging if isinstance(node.ops, ast.Is): self.counter += 1 if self.counter == self.nodeToMutate: new_node = ast.Compare() new_node.left = node.left new_node.comparators = node.comparators new_node.ops = ast.IsNot() print('changing is {} to isnot.'.format(self.counter)) return ast.copy_location(new_node, node) # helps debugging if isinstance(node.ops, ast.IsNot): self.counter += 1 if self.counter == self.nodeToMutate: new_node = ast.Compare() new_node.left = node.left new_node.comparators = node.comparators new_node.ops = ast.Is() print('changing isnot {} to is.'.format(self.counter)) return ast.copy_location(new_node, node) # helps debugging if isinstance(node.ops, ast.In): self.counter += 1 if self.counter == self.nodeToMutate: new_node = ast.Compare() new_node.left = node.left new_node.comparators = node.comparators new_node.ops = ast.NotIn() print('changing In {} to InNot.'.format(self.counter)) return ast.copy_location(new_node, node) # helps debugging if isinstance(node.ops, ast.NotIn): self.counter += 1 if self.counter == self.nodeToMutate: new_node = ast.Compare() new_node.left = node.left new_node.comparators = node.comparators new_node.ops = ast.In() print('changing Notin {} to in.'.format(self.counter)) return ast.copy_location(new_node, node) # helps debugging return self.generic_visit(node)
Symbol.new("*"): compile_multiply, Symbol.new("/"): compile_divide, Symbol.new("//"): compile_floordivide, Symbol.new("%"): lambda p: ast.BinOp(build_ast(p[1]), ast.Mod(), build_ast(p[2])), Symbol.new("&"): lambda p: ast.BinOp(build_ast(p[1]), ast.BitAnd(), build_ast(p[2])), Symbol.new("**"): lambda p: ast.BinOp(build_ast(p[1]), ast.Pow(), build_ast(p[2])), Symbol.new(">>"): lambda p: ast.BinOp(build_ast(p[1]), ast.RShift(), build_ast(p[2])), Symbol.new("<<"): lambda p: ast.BinOp(build_ast(p[1]), ast.LShift(), build_ast(p[2])), Symbol.new("^"): lambda p: ast.BinOp(build_ast(p[1]), ast.BitXor(), build_ast(p[2])), Symbol.new("<"): lambda p: ast.Compare(build_ast(p[1]), [ast.Lt() for x in p[1::2]], [build_ast(x) for x in p[2::2]]), Symbol.new(">"): lambda p: ast.Compare(build_ast(p[1]), [ast.Gt() for x in p[1::2]], [build_ast(x) for x in p[2::2]]), Symbol.new("<="): lambda p: ast.Compare(build_ast(p[1]), [ast.LtE() for x in p[1::2]], [build_ast(x) for x in p[2::2]]), Symbol.new(">="): lambda p: ast.Compare(build_ast(p[1]), [ast.GtE() for x in p[1::2]], [build_ast(x) for x in p[2::2]]), Symbol.new("=="): compile_equals, Symbol.new("!="): lambda p: ast.Compare(build_ast(p[1]), [ast.NotEq() for x in p[1::2]], [build_ast(x) for x in p[2::2]]), Symbol.new("is"): lambda p: ast.Compare(build_ast(p[1]), [ast.Is() for x in p[1::2]], [build_ast(x) for x in p[2::2]]), Symbol.new("is-not"): lambda p: ast.Compare(build_ast(p[1]), [ast.IsNot() for x in p[1::2]], [build_ast(x) for x in p[2::2]]), Symbol.new("define"): compile_define, Symbol.new("dict-set"): lambda p: ast.Assign([ast.Subscript(build_ast(p[1]), ast.Index(build_ast(p[2])), ast.Store())], build_ast(p[3])), #Symbol.new("caadr"): lambda p: compiler.ast.Subscript(compiler.ast.Subscript(build_ast(p[1]), 0, compiler.ast.Const(1)), 0, compiler.ast.Const(0)), Symbol.new("caar"): lambda p: ast.Subscript(ast.Subscript(build_ast(p[1]), ast.Index(ast.Num(0)), ast.Load()), ast.Index(ast.Num(0)), ast.Load()), #Symbol.new("cadddr"): lambda p: compiler.ast.Subscript(build_ast(p[1]), 0, compiler.ast.Const(3)), #Symbol.new("caddr"): lambda p: compiler.ast.Subscript(build_ast(p[1]), 0, compiler.ast.Const(2)), Symbol.new("cadr"): lambda p: ast.Subscript(build_ast(p[1]), ast.Index(ast.Num(1)), ast.Load()), Symbol.new("car"): lambda p: ast.Subscript(build_ast(p[1]), ast.Index(ast.Num(0)), ast.Load()), Symbol.new("cdar"): lambda p: ast.Subscript(ast.Subscript(build_ast(p[1]), ast.Index(ast.Num(0)), ast.Load()), ast.Slice(ast.Num(1), None, None), ast.Load()), #Symbol.new("cddr"): lambda p: compiler.ast.Slice(build_ast(p[1]), 0, compiler.ast.Const(2), None), Symbol.new("cdr"): lambda p: ast.Subscript(build_ast(p[1]), ast.Slice(ast.Num(1), None, None), ast.Load()), Symbol.new("cons"): lambda p: ast.BinOp(ast.List([build_ast(p[1])], ast.Load()), ast.Add(), build_ast(p[2])), #Symbol.new("append"): lambda p: ast.Call(ast.Attribute(ast.Name("functools", ast.Load()), "reduce", ast.Load()), [ast.Attribute(ast.Name("operator", ast.Load()), "add", ast.Load()), build_ast(p[1])], [], None, None), #Symbol.new("apply"): lambda p: ast.Call(build_ast(p[1]), [build_ast(p[2])], [], None, None),
def __init__(self, base_node): BaseMutator.__init__(self, base_node) self.original_ops = base_node.ops index_count = 0 for op in base_node.ops: if type(op) in [ ast.Gt, ast.GtE, ast.Lt, ast.LtE, ast.Eq, ast.NotEq, ast.Is, ast.IsNot, ast.In, ast.NotIn ]: if type(op) is ast.Eq: ops_mutant_Eq = copy.deepcopy(base_node.ops) ops_mutant_Eq[index_count] = ast.NotEq() self.mutations.append({"ops": ops_mutant_Eq}) if type(op) is ast.NotEq: ops_mutant_NotEq = copy.deepcopy(base_node.ops) ops_mutant_NotEq[index_count] = ast.Eq() self.mutations.append({"ops": ops_mutant_NotEq}) if type(op) is ast.LtE: ops_mutant_LtE = copy.deepcopy(base_node.ops) ops_mutant_LtE[index_count] = ast.Gt() self.mutations.append({"ops": ops_mutant_LtE}) if type(op) is ast.GtE: ops_mutant_GtE = copy.deepcopy(base_node.ops) ops_mutant_GtE[index_count] = ast.Lt() self.mutations.append({"ops": ops_mutant_GtE}) if type(op) is ast.Lt: ops_mutant_Lt = copy.deepcopy(base_node.ops) ops_mutant_Lt[index_count] = ast.GtE() self.mutations.append({"ops": ops_mutant_Lt}) if type(op) is ast.Gt: ops_mutant_Gt = copy.deepcopy(base_node.ops) ops_mutant_Gt[index_count] = ast.LtE() self.mutations.append({"ops": ops_mutant_Gt}) if type(op) is ast.Is: ops_mutant_Is = copy.deepcopy(base_node.ops) ops_mutant_Is[index_count] = ast.IsNot() self.mutations.append({"ops": ops_mutant_Is}) if type(op) is ast.IsNot: ops_mutant_IsNot = copy.deepcopy(base_node.ops) ops_mutant_IsNot[index_count] = ast.Is() self.mutations.append({"ops": ops_mutant_IsNot}) if type(op) is ast.In: ops_mutant_In = copy.deepcopy(base_node.ops) ops_mutant_In[index_count] = ast.NotIn() self.mutations.append({"ops": ops_mutant_In}) if type(op) is ast.NotIn: ops_mutant_NotIn = copy.deepcopy(base_node.ops) ops_mutant_NotIn[index_count] = ast.In() self.mutations.append({"ops": ops_mutant_NotIn}) index_count += 1
def is_(self, left, right): return ast.Compare(left=to_ast(left), ops=[ast.Is()], comparators=[to_ast(right)])