Beispiel #1
0
    def visit_ClassDef(self, node):
        node = self.generic_visit(node)

        # free variables of the class block become parameters of the function
        scopes = getattr(node, "scopes", {})
        free = [var for var, scope in scopes.iteritems() if scope == scoping.Scope.FREE]
        free_param = [ast.Name(id=var, ctx=ast.Param()) for var in free]
        free_args = [ast.Name(id=var, ctx=ast.Load()) for var in free]

        # free variables of sub-blocks. Those need name mangling to avoid
        # collisions with variables local to the class block.
        passthrough = self.find_passthrough_vars(node)
        pt_param = [ast.Name(id=naming.passthrough_var(var), ctx=ast.Param()) for var in passthrough]
        pt_args = [ast.Name(id=var, ctx=ast.Load()) for var in passthrough]

        # function to execute the class body and collect the attributes
        func = ast.FunctionDef()
        func.name = self.id_factory("class_" + node.name)
        func.args = ast.arguments(args=free_param + pt_param, vararg=None, kwarg=None, defaults=[])
        func.body = node.body + [ast.Return(value=mk_name("__pydron_members__"))]
        func.decorator_list = []

        # replicate name mangling of `LocalizeFreeVariables`
        all_args = free_args + pt_args
        if self._inside_class():
            for arg in all_args:
                arg.id = naming.passthrough_var(arg.id)

        # create the class
        typefunc = mk_call("__pydron_read_global__", [mk_str("type")])
        class_expr = mk_call_expr(typefunc, [mk_str(node.name), mk_tuple(node.bases), mk_call(func.name, all_args)])

        for decorator in reversed(node.decorator_list):
            class_expr = mk_call_expr(decorator, [class_expr])

        stmt = mk_assign(node.name, class_expr)

        return [func, stmt]
Beispiel #2
0
 def visit_ClassDef(self, node):
     node = self.generic_visit(node)
     
     # free variables of the class block become parameters of the function
     scopes = getattr(node, 'scopes', {})
     free = [var for var,scope in scopes.iteritems() if scope == scoping.Scope.FREE]
     free_param = [ast.Name(id=var, ctx=ast.Param()) for var in free]
     free_args = [ast.Name(id=var, ctx=ast.Load()) for var in free]
     
     # free variables of sub-blocks. Those need name mangling to avoid
     # collisions with variables local to the class block.
     passthrough = self.find_passthrough_vars(node)
     pt_param = [ast.Name(id=naming.passthrough_var(var), ctx=ast.Param()) for var in passthrough]
     pt_args = [ast.Name(id=var, ctx=ast.Load()) for var in passthrough]
     
     # function to execute the class body and collect the attributes
     func = ast.FunctionDef()
     func.name = self.id_factory("class_" + node.name)
     func.args = ast.arguments(args=free_param + pt_param, vararg=None, kwarg=None, defaults=[])
     func.body = node.body + [ast.Return(value=mk_name('__pydron_members__')) ]
     func.decorator_list = []
     
     # replicate name mangling of `LocalizeFreeVariables`
     all_args = free_args + pt_args
     if self._inside_class():
         for arg in all_args:
             arg.id = naming.passthrough_var(arg.id)
     
     # create the class
     typefunc = mk_call('__pydron_read_global__', [mk_str('type')])
     class_expr = mk_call_expr(typefunc, [mk_str(node.name), mk_tuple(node.bases), mk_call(func.name, all_args)])
     
     for decorator in reversed(node.decorator_list):
         class_expr = mk_call_expr(decorator, [class_expr])
     
     stmt = mk_assign(node.name, class_expr)
     
     return [func, stmt]
 def _dedecorate(self, node):
     if not node.decorator_list:
         return node
     
     # use a temporary name
     orig_id = node.name
     node.name = self.id_factory(orig_id)
     
     # call the decorators
     obj = mk_name(node.name)
     for decorator_expr in reversed(node.decorator_list):
         obj = mk_call_expr(decorator_expr, [obj])
         
     # assign to the original name
     assignment_stmt = mk_assign(orig_id, obj)
     
     node.decorator_list = []
     
     return [node, assignment_stmt]
Beispiel #4
0
    def _dedecorate(self, node):
        if not node.decorator_list:
            return node

        # use a temporary name
        orig_id = node.name
        node.name = self.id_factory(orig_id)

        # call the decorators
        obj = mk_name(node.name)
        for decorator_expr in reversed(node.decorator_list):
            obj = mk_call_expr(decorator_expr, [obj])

        # assign to the original name
        assignment_stmt = mk_assign(orig_id, obj)

        node.decorator_list = []

        return [node, assignment_stmt]
Beispiel #5
0
    def visit_With(self, node):
        node = self.generic_visit(node)

        # Build equivalent code with try catch finally.
        # PEP-0343 provides the equivalent code for us.

        statements = []

        # mgr = node.expr
        mgr_id = self.id_factory("mgr")
        s = mk_assign(mgr_id, node.context_expr)
        statements.append(s)

        # exit = type(msg).__exit__
        exit_id = self.id_factory("exit")
        s = mk_assign(exit_id,
                      mk_attr(mk_call('type', [mk_name(mgr_id)]), "__exit__"))
        statements.append(s)

        # value = type(msg).__enter__(mgr)
        value_id = self.id_factory("value")
        s = mk_assign(
            value_id,
            mk_call_expr(
                mk_attr(mk_call('type', [mk_name(mgr_id)]), "__enter__"),
                [mk_name(mgr_id)]))
        statements.append(s)

        # exc = True
        exc_id = self.id_factory("exc")
        s = mk_assign(exc_id, mk_name("True"))
        statements.append(s)

        # try:
        tryfinally_body = []
        tryfinally_finalbody = []
        s = ast.TryFinally(body=tryfinally_body,
                           finalbody=tryfinally_finalbody)
        statements.append(s)

        #     try:
        tryexcept_body = []
        tryexcept_except = []
        expt_handler = ast.ExceptHandler(type=None,
                                         name=None,
                                         body=tryexcept_except)
        s = ast.TryExcept(body=tryexcept_body,
                          handlers=[expt_handler],
                          orelse=[])
        tryfinally_body.append(s)

        #         node.optional_vars = value
        if node.optional_vars:
            s = ast.Assign(targets=[node.optional_vars],
                           value=mk_name(value_id))
            tryexcept_body.append(s)

        #         body
        tryexcept_body.extend(node.body)

        #     except:

        #         exc = False
        s = mk_assign(exc_id, mk_name("False"))
        tryexcept_except.append(s)

        #         sys.exc_info()
        sys_exc_info = mk_call_expr(mk_attr(mk_name('sys'), "exc_info"), [])
        #         exit(mgr, *sys.exc_info())
        exit_call = mk_call(exit_id, [mk_name(mgr_id)], vararg=sys_exc_info)
        #         not exit(mgr, *sys.exc_info())
        test = ast.UnaryOp(op=ast.Not(), operand=exit_call)

        #        if not exit(mgr, *sys.exc_info()):
        #            raise
        s = ast.If(test=test,
                   body=[ast.Raise(type=None, inst=None, tback=None)],
                   orelse=[])
        tryexcept_except.append(s)

        # finally:

        #     if exc:
        #       exit(mgr, None, None, None)
        exit_call = mk_call(exit_id, [
            mk_name(mgr_id),
            mk_name("None"),
            mk_name("None"),
            mk_name("None")
        ])
        s = ast.If(test=mk_name(exc_id),
                   body=[ast.Expr(value=exit_call)],
                   orelse=[])
        tryfinally_finalbody.append(s)

        return statements
Beispiel #6
0
 def visit_With(self, node):
     node = self.generic_visit(node)
     
     # Build equivalent code with try catch finally.
     # PEP-0343 provides the equivalent code for us.
     
     statements = []
     
     # mgr = node.expr
     mgr_id = self.id_factory("mgr")
     s = mk_assign(mgr_id, node.context_expr)
     statements.append(s)
     
     # exit = type(msg).__exit__
     exit_id = self.id_factory("exit")
     s = mk_assign(exit_id, mk_attr(mk_call('type', [mk_name(mgr_id)]), "__exit__"))
     statements.append(s)
     
     # value = type(msg).__enter__(mgr)
     value_id = self.id_factory("value")
     s = mk_assign(value_id, mk_call_expr(mk_attr(mk_call('type', [mk_name(mgr_id)]), "__enter__"), [mk_name(mgr_id)]))
     statements.append(s)
     
     # exc = True
     exc_id = self.id_factory("exc")
     s = mk_assign(exc_id, mk_name("True"))
     statements.append(s)
     
     # try:
     tryfinally_body = []
     tryfinally_finalbody = []
     s = ast.TryFinally(body=tryfinally_body, finalbody=tryfinally_finalbody)
     statements.append(s)
     
     #     try:
     tryexcept_body = []
     tryexcept_except = []
     expt_handler = ast.ExceptHandler(type=None,name=None,body=tryexcept_except)
     s = ast.TryExcept(body=tryexcept_body, handlers=[expt_handler], orelse=[])
     tryfinally_body.append(s)
     
     #         node.optional_vars = value
     if node.optional_vars:
         s = ast.Assign(targets=[node.optional_vars], value=mk_name(value_id))
         tryexcept_body.append(s)
         
     #         body
     tryexcept_body.extend(node.body)
         
     #     except:
 
     #         exc = False
     s = mk_assign(exc_id, mk_name("False"))
     tryexcept_except.append(s)
     
     #         sys.exc_info()
     sys_exc_info = mk_call_expr(mk_attr(mk_name('sys'), "exc_info"), [])
     #         exit(mgr, *sys.exc_info())
     exit_call = mk_call(exit_id, [mk_name(mgr_id)], vararg=sys_exc_info)
     #         not exit(mgr, *sys.exc_info())
     test = ast.UnaryOp(op=ast.Not(), operand=exit_call)
     
     #        if not exit(mgr, *sys.exc_info()):
     #            raise
     s = ast.If(test=test, body=[ast.Raise(type=None, inst=None, tback=None)], orelse=[])
     tryexcept_except.append(s)
     
     # finally:
     
     #     if exc:
     #       exit(mgr, None, None, None)
     exit_call = mk_call(exit_id, [mk_name(mgr_id), mk_name("None"), mk_name("None"), mk_name("None")])
     s = ast.If(test=mk_name(exc_id), body=[ast.Expr(value=exit_call)], orelse=[])
     tryfinally_finalbody.append(s)
     
     return statements