Example #1
0
def test_immutable_to_mutable(tree):
    def _test(tree, mtree):
        assert type(tree) is type(mtree)
        if isinstance(tree, ast.AST):
            for field, value in ast.iter_fields(tree):
                _test(value, getattr(mtree, field))
        elif isinstance(tree, list):
            assert len(tree) == len(mtree)
            for c, mc in zip(tree, mtree):
                _test(c, mc)
        else:
            assert tree == mtree

    itree = immutable_ast.immutable(tree)
    mtree = immutable_ast.mutable(itree)
    _test(tree, mtree)
Example #2
0
def test_mutable_to_immutable(tree):
    def _test(tree, itree):
        if isinstance(tree, ast.AST):
            assert isinstance(itree, immutable_ast.AST)
            assert isinstance(tree, type(itree))
            assert tree._fields == itree._fields
            assert ImmutableMeta._mutable_to_immutable[type(tree)] is type(
                itree)
            for field, value in ast.iter_fields(tree):
                _test(value, getattr(itree, field))
        elif isinstance(tree, list):
            assert isinstance(itree, tuple)
            assert len(tree) == len(itree)
            for c, ic in zip(tree, itree):
                _test(c, ic)
        else:
            assert tree == itree

    itree = immutable_ast.immutable(tree)
    _test(tree, itree)
Example #3
0
def test_eq(tree):
    itree = immutable_ast.immutable(tree)
    jtree = immutable_ast.immutable(tree)
    assert itree == jtree
    assert hash(itree) == hash(jtree)
Example #4
0
    def rewrite(self,
            tree: ast.AST,
            env: SymbolTable,
            metadata: tp.MutableMapping) -> PASS_ARGS_T:
        if not isinstance(tree, ast.FunctionDef):
            raise TypeError('ssa should only be applied to functions')

        # Going to use this in an assert later but need to get the info
        # before any transformation happens
        NR = _never_returns(tree.body)

        # Find all attributes that are written
        targets = collect_targets(tree, ast.Attribute)
        replacer = AttrReplacer({})
        init_reads = []
        id_to_attr = {}
        attr_to_name = {}

        for t in targets:
            i_t = immutable(t)
            if not isinstance(t.value, ast.Name):
                raise NotImplementedError(f'Only supports writing attributes '
                                          f'of Name not {type(t.value)}')
            elif i_t not in attr_to_name:
                name = ast.Name(
                        id=gen_free_name(tree, env, '_'.join((t.value.id, t.attr))),
                        ctx=ast.Store())
                # store the maping of names to attrs
                id_to_attr[name.id] = t
                attr_to_name[i_t] = name
                #replace writes to the attr with writes to the name
                replacer.add_replacement(t, name)
                #replace reads to the attr with reads to the name
                replacer.add_replacement(_flip_ctx(t), _flip_ctx(name))

                # read the init value
                if sys.version_info < (3, 8):
                    assign = ast.Assign(targets=[deepcopy(name)], value=_flip_ctx(t))
                else:
                    assign = ast.Assign(
                            targets=[deepcopy(name)], value=_flip_ctx(t),
                            type_comment=None)
                init_reads.append(immutable(assign))
            else:
                name = attr_to_name[i_t]
                replacer.add_replacement(t, name)
                replacer.add_replacement(_flip_ctx(t), _flip_ctx(name))



        # Replace references to the attr with the name generated above
        tree = replacer.visit(tree)

        # insert initial reads
        tree.body = [mutable(r) for r in init_reads] + tree.body

        # Perform ssa
        r_name = gen_free_prefix(tree, env, self.return_prefix)
        visitor = SSATransformer(env, r_name, id_to_attr.keys(), self.strict)
        tree = visitor.visit(tree)

        #insert the write backs to the attrs
        for name, conditons in visitor.attr_states.items():
            if conditons:
                tree.body.append(
                    ast.Assign(
                        targets=[deepcopy(id_to_attr[name])],
                        value=_fold_conditions(conditons)
                    )
                )
            else:
                tree.body.append(
                    ast.Assign(
                        targets=[deepcopy(id_to_attr[name])],
                        value=ast.Name(visitor.name_table[name], ast.Load())
                    )
                )

        # insert the return
        if visitor.returns:
            tree.body.append(
                ast.Return(
                    value=_fold_conditions(visitor.returns)
                )
            )
        else:
            assert NR
        return tree, env, metadata
Example #5
0
    def vist_Call(self, node: ast.Call):
        if self.count_calls:
            self.cses[immutable(node)] += 1

        return self.generic_visit(node)
Example #6
0
 def _get_key(self, node):
     if isinstance(node, ast.Attribute):
         # Need the immutable value so its comparable
         return immutable(node)
     else:
         return None
Example #7
0
 def visit_IfExpr(self, node: ast.IfExp):
     self.cses[immutable(node)] += 1
     self.generic_visit(node)
Example #8
0
 def visit_Compare(self, node: ast.Compare):
     self.cses[immutable(node)] += 1
     self.generic_visit(node)
Example #9
0
 def visit_BoolOp(self, node: ast.BoolOp):
     self.cses[immutable(node)] += 1
     self.generic_visit(node)
Example #10
0
 def visit_UnaryOp(self, node: ast.UnaryOp):
     self.cses[immutable(node)] += 1
     self.generic_visit(node)
Example #11
0
 def _get_key(node: ast.AST):
     if isinstance(node, ast.expr):
         # Need the immutable value so its comparable
         return immutable(node)
     else:
         return None