Example #1
0
    def test_basic_hook(self):
        # define the hook
        def threebecomestwo(ast, enc, filename):
            class ChangeConstVisitor:
                def visitConst(self, node):
                    if node.value == 3:
                        node.value = 2

                def defaultvisit(self, node):
                    for child in node.getChildNodes():
                        child.accept(self)

                def __getattr__(self, attrname):
                    if attrname.startswith('visit'):
                        return self.defaultvisit
                    raise AttributeError(attrname)
                
            ast.accept(ChangeConstVisitor())
            return ast

        # install the hook
        import parser
        parser.install_compiler_hook(threebecomestwo)
        d = {}
        exec "a = 3" in d
        assert d['a'] == 2 # well, yes ...
Example #2
0
    def test_removal_of_broken_hooks(self):
        def hook(ast, enc, filename):
            1/0
        import parser
        parser.install_compiler_hook(hook)
        raises(ZeroDivisionError, "eval('1')")
        assert eval("1") == 1

        def hook2(ast, enc, filename):
            return 1
        parser.install_compiler_hook(hook2)
        raises(TypeError, "eval('2')")
        assert eval("2") == 2
Example #3
0
    def test_ast_parser(self):
        # define the hook
        def change_globals(ast, enc, filename):
            class ChangeGlobalsVisitor:
                def visitConst(self, node):
                    pass

                def defaultvisit(self, node):
                    for child in node.getChildNodes():
                        child.accept(self)

                def __getattr__(self, attrname):
                    if attrname.startswith('visit'):
                        return self.defaultvisit
                    raise AttributeError(attrname)
                
            ast.accept(ChangeConstVisitor())
            return ast

        # install the hook
        import parser
        parser.install_compiler_hook(change_globals)
Example #4
0
    def test_constant_fold_add(self):
        import parser

        class Folder(object):
            def defaultvisit(self, node):
                return node

            def __getattr__(self, attrname):
                if attrname.startswith('visit'):
                    return self.defaultvisit
                raise AttributeError(attrname)

            def visitAdd(self, node):
                left = node.left
                right = node.right
                if isinstance(left, parser.ASTConst) and \
                       isinstance(right, parser.ASTConst):
                    if type(left.value) == type(right.value):
                        return parser.ASTConst(left.value + right.value)
                return node

        def hook(ast, enc, filename):
            return ast.mutate(Folder())

        parser.install_compiler_hook(hook)
        code = compile("1+2", "", "eval")
        parser.install_compiler_hook(None)
        import dis, sys, StringIO
        s = StringIO.StringIO()
        so = sys.stdout
        sys.stdout = s
        try:
            dis.dis(code)
        finally:
            sys.stdout = so
        output = s.getvalue()
        assert 'BINARY_ADD' not in output
Example #5
0
    def test_constant_fold_add(self):
        import parser

        class Folder:
            def defaultvisit(self, node):
                return node

            def __getattr__(self, attrname):
                if attrname.startswith("visit"):
                    return self.defaultvisit
                raise AttributeError(attrname)

            def visitAdd(self, node):
                left = node.left
                right = node.right
                if isinstance(left, parser.ASTConst) and isinstance(right, parser.ASTConst):
                    if type(left.value) == type(right.value):
                        return parser.ASTConst(left.value + right.value)
                return node

        def hook(ast, enc, filename):
            return ast.mutate(Folder())

        parser.install_compiler_hook(hook)
        code = compile("1+2", "", "eval")
        parser.install_compiler_hook(None)
        import dis, sys, StringIO

        s = StringIO.StringIO()
        so = sys.stdout
        sys.stdout = s
        try:
            dis.dis(code)
        finally:
            sys.stdout = so
        output = s.getvalue()
        assert "BINARY_ADD" not in output
Example #6
0
 def __init__(self):
     self.advices = []
     self.joinpoints = {}
     self._id = 1
     parser.install_compiler_hook(self.weave)
Example #7
0
import parser


class ConstMutator(parser.ASTMutator):
    def visitConst(self, node):
        if node.value == 3:
            node.value = 2
        return node


def threebecomestwo(ast, enc, filename):
    ast.mutate(ConstMutator())
    return ast


# install the hook
parser.install_compiler_hook(threebecomestwo)
print eval('3*2')
Example #8
0
def get_statements(source):
    module = source2ast(source)
    return module.node.nodes

class Tracer(ASTMutator):
    def visitAssName(self, assname):
        assign = assname
        while not isinstance(assign, ASTAssign):
            assign = assign.parent
        stmt = assign.parent
        varname = assname.name
        before_stmts = get_statements(BEFORE_LOG_SOURCE % ((varname,) * 5))
        after_stmts = get_statements(AFTER_LOG_SOURCE % (varname, varname))
        stmt.insert_before(assign, before_stmts)
        stmt.insert_after(assign, after_stmts)
        return assname


def _trace(ast, enc, filename):
    return ast.accept(Tracer())

install_compiler_hook(_trace)


code = """
a = 3
b = 2
a = 1
"""
exec code
import parser
class ConstMutator(parser.ASTMutator):
    def visitConst(self, node):
        if node.value == 3:
            node.value = 2
        return node

def threebecomestwo(ast, enc, filename):
    ast.mutate(ConstMutator())
    return ast

# install the hook
parser.install_compiler_hook(threebecomestwo)
print eval('3*2')