Esempio n. 1
0
    def visit_Macro(self, node):
        body = []

        # Resolve defaults
        for name in self.defaults:
            body += template(
                "NAME = econtext[KEY]",
                NAME=name, KEY=ast.Str(s="__" + name)
            )


        # Visit macro body
        nodes = itertools.chain(*tuple(map(self.visit, node.body)))

        # Append visited nodes
        body += template("__i18n_domain = None")
        body += nodes

        function_name = "render" if node.name is None else \
                        "render_%s" % mangle(node.name)

        function = ast.FunctionDef(
            name=function_name, args=ast.arguments(
                args=[
                    param(self._current_stack),
                    param(self._defined_models[""]),
                    param("econtext"),
                    param("rcontext"),
                    ],
                defaults=[],
            ),
            body=body
            )

        yield function
Esempio n. 2
0
    def visit_Start(self, node):
        try:
            line, column = node.prefix.location
        except AttributeError:
            line, column = 0, 0

        yield Comment(
            " %s%s ... (%d:%d)\n"
            " --------------------------------------------------------" %
            (node.prefix, node.name, line, column))

        if not hasattr(node, "repeatable"):
            print "ea"
        if node.repeatable:
            push = template("STACK.repeat(N)",
                            STACK=self._current_stack,
                            N=ast.Str(s=node.name))
        elif node.replayable:
            push = template("STACK.replay(N)",
                            STACK=self._current_stack,
                            N=ast.Str(s=node.name))
        else:
            push = template("STACK.u(N)",
                            STACK=self._current_stack,
                            N=ast.Str(s=node.name))
        for stmt in push:
            yield stmt

        if node.attributes:
            for attribute in node.attributes:
                for stmt in self.visit(attribute):
                    yield stmt
Esempio n. 3
0
    def visit_Macro(self, node):
        body = []

        # Resolve defaults
        for name in self.defaults:
            body += template("NAME = econtext[KEY]",
                             NAME=name,
                             KEY=ast.Str(s="__" + name))

        # Visit macro body
        nodes = itertools.chain(*tuple(map(self.visit, node.body)))

        # Append visited nodes
        body += template("__i18n_domain = None")
        body += nodes

        function_name = "render" if node.name is None else \
                        "render_%s" % mangle(node.name)

        function = ast.FunctionDef(name=function_name,
                                   args=ast.arguments(
                                       args=[
                                           param(self._current_stack),
                                           param(self._defined_models[""]),
                                           param("econtext"),
                                           param("rcontext"),
                                       ],
                                       defaults=[],
                                   ),
                                   body=body)

        yield function
Esempio n. 4
0
    def visit_Start(self, node):
        try:
            line, column = node.prefix.location
        except AttributeError:
            line, column = 0, 0

        yield Comment(
            " %s%s ... (%d:%d)\n"
            " --------------------------------------------------------" % (
                node.prefix, node.name, line, column))

        if not hasattr(node, "repeatable"):
            print "ea"
        if node.repeatable:
            push = template("STACK.repeat(N)", STACK=self._current_stack, N=ast.Str(s=node.name))
        elif node.replayable:
            push = template("STACK.replay(N)", STACK=self._current_stack, N=ast.Str(s=node.name))
        else:
            push = template("STACK.u(N)", STACK=self._current_stack, N=ast.Str(s=node.name))
        for stmt in push:
            yield stmt

        if node.attributes:
            for attribute in node.attributes:
                for stmt in self.visit(attribute):
                    yield stmt
Esempio n. 5
0
    def visit_Name(self, node):
        """Translation name."""

        if not self._translations:
            raise TranslationError("Not allowed outside of translation.",
                                   node.name)

        if node.name in self._translations[-1]:
            raise TranslationError("Duplicate translation name: %s." %
                                   node.name)

        self._translations[-1].add(node.name)
        body = []

        # prepare new stream
        stream, append = self._get_translation_identifiers(node.name)
        body += template("s = new_list", s=stream, new_list=LIST) + \
                template("a = s.append", a=append, s=stream)

        # generate code
        code = self.visit(node.node)
        swap(ast.Suite(body=code), load(append), "__append")
        body += code

        # output msgid
        text = Text('${%s}' % node.name)
        body += self.visit(text)

        # Concatenate stream
        body += template("stream = ''.join(stream)", stream=stream)

        return body
Esempio n. 6
0
    def visit_Name(self, node):
        """Translation name."""

        if not self._translations:
            raise TranslationError(
                "Not allowed outside of translation.", node.name)

        if node.name in self._translations[-1]:
            raise TranslationError(
                "Duplicate translation name: %s." % node.name)

        self._translations[-1].add(node.name)
        body = []

        # prepare new stream
        stream, append = self._get_translation_identifiers(node.name)
        body += template("s = new_list", s=stream, new_list=LIST) + \
                template("a = s.append", a=append, s=stream)

        # generate code
        code = self.visit(node.node)
        swap(ast.Suite(body=code), load(append), "__append")
        body += code

        # output msgid
        text = Text('${%s}' % node.name)
        body += self.visit(text)

        # Concatenate stream
        body += template("stream = ''.join(stream)", stream=stream)

        return body
Esempio n. 7
0
    def visit_Module(self, node):
        body = []

        body += template("__marker = object()")
        body += template("__filename = f", f=ast.Str(s=self.filename))
        body += self.visit(node.program)

        return body
Esempio n. 8
0
    def visit_Module(self, node):
        body = []

        body += template("__marker = object()")
        body += template("__filename = f", f=ast.Str(s=self.filename))
        body += self.visit(node.program)

        return body
Esempio n. 9
0
    def visit_Content(self, node):
        name = "__content"
        body = self._engine(node.expression, store(name))

        if node.translate:
            body += emit_translate(name, name)

        if node.is_structure:
            body += template("STACK.n(NAME)", STACK=self._current_stack, NAME=name)
        else:
            body += emit_convert(name)
            body += template("STACK.t(NAME)", STACK=self._current_stack, NAME=name)

        return body
Esempio n. 10
0
    def visit_BindRepeat(self, node):
        body = []

        body.append(Comment("start model-repeat-binding"))

        new_stack = identifier("stack", id(node))
        old_stack = self._current_stack
        body += template("CAPTURED_STACK = STACK.capture_for_repeat()",
                         CAPTURED_STACK=new_stack,
                         STACK=old_stack)

        new_stack = identifier("stack", id(node))

        self._current_stack = new_stack
        self._aliases.append(self._aliases[-1].copy())

        model_name = identifier("model_%s" % node.alias, id(node))
        self._defined_models[node.alias] = model_name

        inner_on_add = []
        inner_on_add += self.visit(node.node)
        inner_on_add += template("return STACK.repeat_el",
                                 STACK=self._current_stack)

        on_add_name = identifier("on_add", id(node))
        on_add_func = [
            ast.FunctionDef(name=on_add_name,
                            args=ast.arguments(
                                args=[load(model_name)],
                                defaults=(),
                            ),
                            body=inner_on_add)
        ]
        body += on_add_func

        collection = "__collection"
        initializer = self._engine(node.expression, store(collection))
        initializer += template("BIND_REPEAT(COLLECTION, ON_ADD)",
                                BIND_REPEAT=Symbol(bind_repeat),
                                COLLECTION=load(collection),
                                ON_ADD=on_add_name)
        body += initializer

        self._aliases.pop()
        self._current_stack = old_stack

        body.append(Comment("end model-repeat-binding"))
        return body
Esempio n. 11
0
    def visit_Assignment(self, node):
        for name in node.names:
            if name in COMPILER_INTERNALS_OR_DISALLOWED:
                raise TranslationError("Name disallowed by compiler.", name)

            if name.startswith('__'):
                raise TranslationError(
                    "Name disallowed by compiler (double underscore).", name)

        assignment = self._engine(node.expression, store("__value"))

        if len(node.names) != 1:
            target = ast.Tuple(
                elts=[store_econtext(name) for name in node.names],
                ctx=ast.Store(),
            )
        else:
            target = store_econtext(node.names[0])

        assignment.append(ast.Assign(targets=[target], value=load("__value")))

        for name in node.names:
            if not node.local:
                assignment += template("rcontext[KEY] = __value",
                                       KEY=ast.Str(s=native_string(name)))

        return assignment
Esempio n. 12
0
 def __call__(self, target, engine):
     # Make call to superclass to assign value to target
     assignment = super().__call__(target, engine)
     transform = template("target = transform(econtext, target)",
                          target=target,
                          transform=self.transform)
     return assignment + transform
Esempio n. 13
0
    def __call__(self, expression, target):
        if isinstance(target, string_type):
            target = store(target)

        try:
            stmts = self.translate(expression, target)
        except ExpressionError:
            if self.strict:
                raise

            exc = sys.exc_info()[1]
            p = pickle.dumps(exc)

            stmts = template(
                "__exc = loads(p)", loads=self.loads_symbol, p=ast.Str(s=p)
                )

            token = Token(exc.token, exc.offset, filename=exc.filename)

            stmts += set_error(token, load("__exc"))
            stmts += [ast.Raise(exc=load("__exc"))]

        # Apply visitor to each statement
        for stmt in stmts:
            self.visitor(stmt)

        return stmts
Esempio n. 14
0
    def _find_translation_components(self, parts):
        components = []
        for part in parts[1:]:
            interpolation_args = []

            def replace(match):
                start, end = match.span()
                interpolation_args.append(part[start + 1: end])
                return "%s"

            while True:
                part, count = self.interpolation_regex.subn(replace, part)
                if count == 0:
                    break

            if interpolation_args:
                component = template(
                    "format % args",
                    format=ast.Str(part),
                    args=ast.Tuple(
                        list(map(load, interpolation_args)), ast.Load()
                    ),
                    mode="eval",
                )
            else:
                component = ast.Str(part)

            components.append(component)

        return components
Esempio n. 15
0
    def visit_CodeBlock(self, node):
        stmts = template(textwrap.dedent(node.source.strip('\n')))

        for stmt in stmts:
            self._visitor(stmt)

        return stmts
Esempio n. 16
0
class PythonExpr(BasePythonExpr):
    builtins = {
        name: template(
            "tales(econtext, rcontext, name)",
            tales=Builtin("tales"),
            name=ast.Str(s=name),
            mode="eval",
        )
        for name in ("path", "exists", "string", "nocall")
    }

    def __call__(self, target, engine):
        return self.translate(self.expression, target)

    def rewrite(self, node):
        builtin = self.builtins.get(node.id)
        if builtin is not None:
            return template(
                "get(name) if get(name) is not None else builtin",
                get=Builtin("get"),
                name=ast.Str(s=node.id),
                builtin=builtin,
                mode="eval",
            )

    @property
    def transform(self):
        return NameLookupRewriteVisitor(self.rewrite)
Esempio n. 17
0
    def __call__(self, expression, target):
        if isinstance(target, string_type):
            target = store(target)

        try:
            stmts = self.translate(expression, target)
        except ExpressionError:
            if self.strict:
                raise

            exc = sys.exc_info()[1]
            p = pickle.dumps(exc)

            stmts = template("__exc = loads(p)",
                             loads=self.loads_symbol,
                             p=ast.Str(s=p))

            token = Token(exc.token, exc.offset, filename=exc.filename)

            stmts += set_error(token, load("__exc"))
            stmts += [ast.Raise(exc=load("__exc"))]

        # Apply visitor to each statement
        for stmt in stmts:
            self.visitor(stmt)

        return stmts
Esempio n. 18
0
    def visit_Assignment(self, node):
        for name in node.names:
            if name in COMPILER_INTERNALS_OR_DISALLOWED:
                raise TranslationError(
                    "Name disallowed by compiler.", name
                    )

            if name.startswith('__'):
                raise TranslationError(
                    "Name disallowed by compiler (double underscore).",
                    name
                    )

        assignment = self._engine(node.expression, store("__value"))

        if len(node.names) != 1:
            target = ast.Tuple(
                elts=[store_econtext(name) for name in node.names],
                ctx=ast.Store(),
            )
        else:
            target = store_econtext(node.names[0])

        assignment.append(ast.Assign(targets=[target], value=load("__value")))

        for name in node.names:
            if not node.local:
                assignment += template(
                    "rcontext[KEY] = __value", KEY=ast.Str(s=native_string(name))
                    )

        return assignment
Esempio n. 19
0
class PythonExpr(BasePythonExpr):
    builtins = dict((name,
                     template("tales(econtext, rcontext, name)",
                              tales=Builtin("tales"),
                              name=ast.Str(s=name),
                              mode="eval")) for name in ('path', 'exists'))

    def __init__(self, expression):
        self.expression = expression

    def __call__(self, target, engine):
        return self.translate(self.expression, target)

    def rewrite(self, node):
        builtin = self.builtins.get(node.id)
        if builtin is not None:
            return template("get(name) if get(name) is not None else builtin",
                            get=Builtin("get"),
                            name=ast.Str(s=node.id),
                            builtin=builtin,
                            mode="eval")

    @property
    def transform(self):
        return NameLookupRewriteVisitor(self.rewrite)
Esempio n. 20
0
    def _find_translation_components(self, parts):
        components = []
        for part in parts[1:]:
            interpolation_args = []

            def replace(match):
                start, end = match.span()
                interpolation_args.append(part[start + 1:end])
                return "%s"

            while True:
                part, count = self.interpolation_regex.subn(replace, part)
                if count == 0:
                    break

            if interpolation_args:
                component = template(
                    "format % args",
                    format=ast.Str(part),
                    args=ast.Tuple(list(map(load, interpolation_args)),
                                   ast.Load()),
                    mode="eval",
                )
            else:
                component = ast.Str(part)

            components.append(component)

        return components
    def __call__(self, target, engine):
        assignment = super(SlotExpr, self).__call__(target, engine)

        return assignment + template(
            "target = transform(econtext, target)",
            target = target,
            transform=Symbol(slot_renderer))
Esempio n. 22
0
    def visit_Attribute(self, node):
        f = node.space + "%s," + node.quote + "%s" + node.quote

        # Static attributes are just outputted directly
        if isinstance(node.expression, ast.Str):
            s = f % (node.name, node.expression.s)
            return template("STACK.a(N,S)", STACK=self._current_stack, N=ast.Str(s=node.name), S=ast.Str(s=node.expression.s))

        target = identifier("attr", node.name)
        body = self._engine(node.expression, store(target))
        return body + template(
            "if VALUE is not None: STACK.a(NAME,  VALUE)",
            STACK=self._current_stack,
            NAME=ast.Str(s=node.name),
            VALUE=target,
            )
Esempio n. 23
0
    def visit_CodeBlock(self, node):
        stmts = template(textwrap.dedent(node.source.strip('\n')))

        for stmt in stmts:
            self._visitor(stmt)

        return stmts
Esempio n. 24
0
        def __call__(self, target, engine):
            assignment = super(MacroExpr, self).__call__(target, engine)

            return assignment + template(
                "target = traverse(context, request, view, target.strip())",
                target=target,
                traverse=self.traverser,
            )
Esempio n. 25
0
    def visit_BindChange(self, node):
        body = []

        body.append(Comment("start model-binding"))

        new_stack = identifier("stack", id(node))
        old_stack = self._current_stack
        body += template("CAPTURED_STACK = STACK.capture()",
                         CAPTURED_STACK=new_stack,
                         STACK=old_stack)

        self._current_stack = new_stack
        self._aliases.append(self._aliases[-1].copy())

        inner = self.visit(node.node)

        self._aliases.pop()
        self._current_stack = old_stack

        on_change_name = identifier("on_change", id(node))
        on_change_func = [
            ast.FunctionDef(name=on_change_name,
                            args=ast.arguments(
                                args=[],
                                defaults=(),
                            ),
                            body=inner)
        ]
        if node.model_name not in self._defined_models:
            raise TranslationError(
                "Cannot find bind model on current context.", node.model_name)

        body += on_change_func
        bind_attrs = ast.Tuple(
            elts=[ast.Str(s=attr) for attr in node.bind_attrs], ctx=ast.Load())
        bind_ons = ast.Tuple(elts=[ast.Str(s=attr) for attr in node.bind_ons],
                             ctx=ast.Load())
        body += template("BIND_CHANGE(MODEL, BIND_ONS, BIND_ATTRS, ON_CHANGE)",
                         BIND_CHANGE=Symbol(bind_change),
                         MODEL=load(self._defined_models[node.model_name]),
                         BIND_ATTRS=bind_attrs,
                         BIND_ONS=bind_ons,
                         ON_CHANGE=on_change_name)

        body.append(Comment("end model-binding"))
        return body
Esempio n. 26
0
 def rewrite(self, node):
     builtin = self.builtins.get(node.id)
     if builtin is not None:
         return template("get(name) if get(name) is not None else builtin",
                         get=Builtin("get"),
                         name=ast.Str(s=node.id),
                         builtin=builtin,
                         mode="eval")
Esempio n. 27
0
 def __call__(self, target, engine):
     slot_name = self.expression.strip()
     value = template(
         "query_slot(econtext, name)",
         query_slot=Symbol(query_slot),  # ast of query_slot
         name=ast.Str(s=slot_name),  # our name parameter to query_slot
         mode="eval")
     return [ast.Assign(targets=[target], value=value)]
Esempio n. 28
0
 def compiler(target, engine):
     value = template(
         "EXECUTE(NAME,econtext,rcontext)",
         EXECUTE=Symbol(execute),
         NAME=ast.Str(s=command),
         mode="eval",
     )
     return [ast.Assign(targets=[target], value=value)]
Esempio n. 29
0
def transform_attribute(node):
    info = "\n".join(ASTCodeGenerator(node).lines)
    return template("lookup(object, name, info, __filename)",
                    lookup=Symbol(lookup_attr),
                    object=node.value,
                    name=ast.Str(s=node.attr),
                    info=ast.Str(s=info),
                    mode="eval")
Esempio n. 30
0
 def _leave_assignment(self, names):
     for name in names:
         for stmt in template(
                 "deleteitem(econtext, KEY, BACKUP, __marker)",
                 deleteitem=Symbol(deleteitem),
                 BACKUP=identifier("backup_%s" % name, id(names)),
                 KEY=ast.Str(s=native_string(name)),
         ):
             yield stmt
Esempio n. 31
0
 def _leave_assignment(self, names):
     for name in names:
         for stmt in template(
             "deleteitem(econtext, KEY, BACKUP, __marker)",
             deleteitem=Symbol(deleteitem),
             BACKUP=identifier("backup_%s" % name, id(names)),
             KEY=ast.Str(s=native_string(name)),
             ):
             yield stmt
 def __call__(self, target, c_engine):
     return template(
         "target = compile_zt_expr(type, expression, econtext=econtext)"
         "(c2z_context(econtext))",
         target=target,
         compile_zt_expr=_compile_zt_expr_node,
         type=ast.Str(self.type),
         expression=ast.Str(self.expression),
         c2z_context=_c_context_2_z_context_node)
Esempio n. 33
0
    def visit_Content(self, node):
        name = "__content"
        body = self._engine(node.expression, store(name))

        if node.translate:
            body += emit_translate(name, name)

        if node.is_structure:
            body += template("STACK.n(NAME)",
                             STACK=self._current_stack,
                             NAME=name)
        else:
            body += emit_convert(name)
            body += template("STACK.t(NAME)",
                             STACK=self._current_stack,
                             NAME=name)

        return body
Esempio n. 34
0
    def visit_BindReplay(self, node):
        body = []

        body.append(Comment("start replay-binding"))

        new_stack = identifier("stack", id(node))
        old_stack = self._current_stack
        body += template("CAPTURED_STACK = STACK.capture()",
                         CAPTURED_STACK=new_stack,
                         STACK=old_stack)

        self._current_stack = new_stack
        self._aliases.append(self._aliases[-1].copy())

        inner = self.visit(node.node)

        self._aliases.pop()
        self._current_stack = old_stack

        on_event_name = identifier("on_event", id(node))
        on_event_func = [
            ast.FunctionDef(name=on_event_name,
                            args=ast.arguments(
                                args=[],
                                defaults=(),
                            ),
                            body=inner)
        ]

        body += on_event_func

        bindable = "__bindable"
        body += self._engine(node.expression, store(bindable))
        events = ast.Tuple(elts=[ast.Str(s=attr) for attr in node.events],
                           ctx=ast.Load())

        body += template("BIND_REPLAY(BINDABLE, EVENTS, ON_EVENT)",
                         BIND_REPLAY=Symbol(bind_replay),
                         BINDABLE=bindable,
                         EVENTS=events,
                         ON_EVENT=on_event_name)

        body.append(Comment("end model-binding"))
        return body
Esempio n. 35
0
    def visit_OnError(self, node):
        body = []

        fallback = identifier("__fallback")
        body += template("fallback = len(__stream)", fallback=fallback)

        self._enter_assignment((node.name, ))
        fallback_body = self.visit(node.fallback)
        self._leave_assignment((node.name, ))

        error_assignment = template(
            "econtext[key] = cls(__exc, rcontext['__error__'][-1][1:3])",
            cls=ErrorInfo,
            key=ast.Str(s=node.name),
            )

        body += self.visit(node.node)

        return body
Esempio n. 36
0
    def visit_OnError(self, node):
        body = []

        fallback = identifier("__fallback")
        body += template("fallback = len(__stream)", fallback=fallback)

        self._enter_assignment((node.name, ))
        fallback_body = self.visit(node.fallback)
        self._leave_assignment((node.name, ))

        error_assignment = template(
            "econtext[key] = cls(__exc, rcontext['__error__'][-1][1:3])",
            cls=ErrorInfo,
            key=ast.Str(s=node.name),
        )

        body += self.visit(node.node)

        return body
Esempio n. 37
0
    def visit_Attribute(self, node):
        f = node.space + "%s," + node.quote + "%s" + node.quote

        # Static attributes are just outputted directly
        if isinstance(node.expression, ast.Str):
            s = f % (node.name, node.expression.s)
            return template("STACK.a(N,S)",
                            STACK=self._current_stack,
                            N=ast.Str(s=node.name),
                            S=ast.Str(s=node.expression.s))

        target = identifier("attr", node.name)
        body = self._engine(node.expression, store(target))
        return body + template(
            "if VALUE is not None: STACK.a(NAME,  VALUE)",
            STACK=self._current_stack,
            NAME=ast.Str(s=node.name),
            VALUE=target,
        )
Esempio n. 38
0
 def rewrite(self, node):
     builtin = self.builtins.get(node.id)
     if builtin is not None:
         return template(
             "get(name) if get(name) is not None else builtin",
             get=Builtin("get"),
             name=ast.Str(s=node.id),
             builtin=builtin,
             mode="eval"
             )
Esempio n. 39
0
class TileExpression(StringExpr):
    render_tile = Static(
        template("cls()", cls=Symbol(TileProviderTraverser), mode='eval'))

    def __call__(self, target, engine):
        assignment = super(TileExpression, self).__call__(target, engine)
        return assignment + template(
            'target = render_tile(context, request, target.strip())',
            target=target,
            render_tile=self.render_tile)
Esempio n. 40
0
def transform_attribute(node):
    info = "\n".join(ASTCodeGenerator(node).lines)
    return template(
        "lookup(object, name, info, __filename)",
        lookup=Symbol(lookup_attr),
        object=node.value,
        name=ast.Str(s=node.attr),
        info=ast.Str(s=info),
        mode="eval"
    )
Esempio n. 41
0
    def __call__(self, target, engine):
        compiler = engine.parse(self.expression)
        body = compiler.assign_value(target)

        def mw_render(content):
            return self.wrapper_class(MediaWiki(content).as_string())

        return body + template("from smc.mw import MediaWiki ; target = MediaWiki(target).as_string()",
                               target=target,
                               wrapper=self.wrapper_class)
Esempio n. 42
0
    def visit_BindRepeat(self, node):
        body = []

        body.append(Comment("start model-repeat-binding"))

        new_stack = identifier("stack", id(node))
        old_stack = self._current_stack
        body += template("CAPTURED_STACK = STACK.capture_for_repeat()", CAPTURED_STACK=new_stack, STACK=old_stack)

        new_stack = identifier("stack", id(node))

        self._current_stack = new_stack
        self._aliases.append(self._aliases[-1].copy())

        model_name = identifier("model_%s" % node.alias, id(node))
        self._defined_models[node.alias] = model_name

        inner_on_add = []
        inner_on_add += self.visit(node.node)
        inner_on_add += template("return STACK.repeat_el", STACK=self._current_stack)

        on_add_name = identifier("on_add", id(node))
        on_add_func = [ast.FunctionDef(
            name=on_add_name, args=ast.arguments(
                args=[load(model_name)],
                defaults=(),
            ),
            body=inner_on_add
        )]
        body += on_add_func

        collection = "__collection"
        initializer = self._engine(node.expression, store(collection))
        initializer += template("BIND_REPEAT(COLLECTION, ON_ADD)",
            BIND_REPEAT=Symbol(bind_repeat), COLLECTION=load(collection), ON_ADD=on_add_name)
        body += initializer

        self._aliases.pop()
        self._current_stack = old_stack

        body.append(Comment("end model-repeat-binding"))
        return body
Esempio n. 43
0
    def visit_BindChange(self, node):
        body = []

        body.append(Comment("start model-binding"))

        new_stack = identifier("stack", id(node))
        old_stack = self._current_stack
        body += template("CAPTURED_STACK = STACK.capture()", CAPTURED_STACK=new_stack, STACK=old_stack)

        self._current_stack = new_stack
        self._aliases.append(self._aliases[-1].copy())

        inner = self.visit(node.node)

        self._aliases.pop()
        self._current_stack = old_stack

        on_change_name = identifier("on_change", id(node))
        on_change_func = [ast.FunctionDef(
            name=on_change_name, args=ast.arguments(
                args=[],
                defaults=(),
            ),
            body=inner
        )]
        if node.model_name not in self._defined_models:
            raise TranslationError(
                "Cannot find bind model on current context.", node.model_name)

        body += on_change_func
        bind_attrs = ast.Tuple(
            elts=[ast.Str(s=attr) for attr in node.bind_attrs],
            ctx=ast.Load())
        bind_ons = ast.Tuple(
            elts=[ast.Str(s=attr) for attr in node.bind_ons],
            ctx=ast.Load())
        body += template("BIND_CHANGE(MODEL, BIND_ONS, BIND_ATTRS, ON_CHANGE)",
            BIND_CHANGE=Symbol(bind_change), MODEL=load(self._defined_models[node.model_name]),
            BIND_ATTRS=bind_attrs, BIND_ONS=bind_ons, ON_CHANGE=on_change_name)

        body.append(Comment("end model-binding"))
        return body
Esempio n. 44
0
    def __call__(self, target, engine):
        # Make call to superclass to assign value to target
        assignment = super(ContextExpressionMixin, self).\
                     __call__(target, engine)

        transform = template(
            "target = transform(econtext, target)",
            target=target,
            transform=self.transform,
            )

        return assignment + transform
Esempio n. 45
0
    def __call__(self, target, engine):
        # Make call to superclass to assign value to target
        assignment = super(ContextExpressionMixin, self).\
                     __call__(target, engine)

        transform = template(
            "target = transform(econtext, target)",
            target=target,
            transform=self.transform,
        )

        return assignment + transform
Esempio n. 46
0
    def translate(self, string, target):
        """
        >>> from chameleon.tales import test
        >>> test(PathExpr('None')) is None
        True
        """
        string = string.strip()

        if not string:
            return template("target = None", target=target)

        m = self.path_regex.match(string)
        if m is None:
            raise ExpressionError("Not a valid path-expression.", string)

        nocall, path = m.groups()

        # note that unicode paths are not allowed
        parts = str(path).split("/")

        components = self._find_translation_components(parts)

        base = parts[0]

        if not components:
            if len(parts) == 1 and (nocall or base == "None"):
                return template("target = base", base=base, target=target)
            else:
                components = ()

        call = template(
            "traverse(base, econtext, call, path_items)",
            traverse=self.traverser,
            base=load(base),
            call=load(str(not nocall)),
            path_items=ast.Tuple(elts=components),
            mode="eval",
        )

        return template("target = value", target=target, value=call)
Esempio n. 47
0
    def translate(self, string, target):
        """
        >>> from chameleon.tales import test
        >>> test(PathExpr('None')) is None
        True
        """
        string = string.strip()

        if not string:
            return template("target = None", target=target)

        m = self.path_regex.match(string)
        if m is None:
            raise ExpressionError("Not a valid path-expression.", string)

        nocall, path = m.groups()

        # note that unicode paths are not allowed
        parts = str(path).split("/")

        components = self._find_translation_components(parts)

        base = parts[0]

        if not components:
            if len(parts) == 1 and (nocall or base == "None"):
                return template("target = base", base=base, target=target)
            else:
                components = ()

        call = template(
            "traverse(base, econtext, call, path_items)",
            traverse=self.traverser,
            base=load(base),
            call=load(str(not nocall)),
            path_items=ast.Tuple(elts=components),
            mode="eval",
        )

        return template("target = value", target=target, value=call)
Esempio n. 48
0
    def visit_BindReplay(self, node):
        body = []

        body.append(Comment("start replay-binding"))

        new_stack = identifier("stack", id(node))
        old_stack = self._current_stack
        body += template("CAPTURED_STACK = STACK.capture()", CAPTURED_STACK=new_stack, STACK=old_stack)

        self._current_stack = new_stack
        self._aliases.append(self._aliases[-1].copy())

        inner = self.visit(node.node)

        self._aliases.pop()
        self._current_stack = old_stack

        on_event_name = identifier("on_event", id(node))
        on_event_func = [ast.FunctionDef(
            name=on_event_name, args=ast.arguments(
                args=[],
                defaults=(),
            ),
            body=inner
        )]

        body += on_event_func

        bindable = "__bindable"
        body += self._engine(node.expression, store(bindable))
        events = ast.Tuple(
            elts=[ast.Str(s=attr) for attr in node.events],
            ctx=ast.Load())

        body += template("BIND_REPLAY(BINDABLE, EVENTS, ON_EVENT)",
            BIND_REPLAY=Symbol(bind_replay), BINDABLE=bindable,
            EVENTS=events, ON_EVENT=on_event_name)

        body.append(Comment("end model-binding"))
        return body
Esempio n. 49
0
    def visit_Element(self, node):
        self._aliases.append(self._aliases[-1].copy())

        for stmt in self.visit(node.start):
            yield stmt

        for stmt in self.visit(node.content):
            yield stmt

        for stmt in template("STACK.o()", STACK=self._current_stack):
            yield stmt

        self._aliases.pop()
Esempio n. 50
0
    def visit_Element(self, node):
        self._aliases.append(self._aliases[-1].copy())

        for stmt in self.visit(node.start):
            yield stmt

        for stmt in self.visit(node.content):
            yield stmt

        for stmt in template("STACK.o()", STACK=self._current_stack):
            yield stmt

        self._aliases.pop()
Esempio n. 51
0
    def __call__(self, node):
        name = node.id

        # Don't rewrite names that begin with an underscore; they are
        # internal and can be assumed to be locally defined. This
        # policy really should be part of the template program, not
        # defined here in the compiler.

        if isinstance(node.ctx, ast.Load):
            if self.validate_model and name.startswith("__model_"):
                name = node.id[8:]
                if not name in self.defined_models:
                    err = ParseError(
                        "Cannot find model",
                        Token(name,
                              pos=node.lineno,
                              source=self.source,
                              filename=self.filename))
                    raise err
                node.id = self.defined_models[name]
                return node

        if name.startswith('__') or name in self.internals:
            return node

        if name == "el":
            return Builtin("None")

        if isinstance(node.ctx, ast.Store):
            return store_econtext(name)

        aliased = self.aliases.get(name)
        if aliased is not None:
            return load(aliased)

        # If the name is a Python global, first try acquiring it from
        # the dynamic context, then fall back to the global.
        if name in self.builtins:
            return template(
                "getitem(econtext, key, name)",
                getitem=Symbol(getitem),
                mode="eval",
                key=ast.Str(s=name),
                name=load(name),
            )

        # Otherwise, simply acquire it from the dynamic context.
        return load_econtext(name)
Esempio n. 52
0
    def __call__(self, node):
        name = node.id

        # Don't rewrite names that begin with an underscore; they are
        # internal and can be assumed to be locally defined. This
        # policy really should be part of the template program, not
        # defined here in the compiler.

        if isinstance(node.ctx, ast.Load):
            if self.validate_model and name.startswith("__model_"):
                name = node.id[8:]
                if not name in self.defined_models:
                    err = ParseError(
                        "Cannot find model", Token(name, pos=node.lineno, source=self.source, filename=self.filename))
                    raise err
                node.id = self.defined_models[name]
                return node

        if name.startswith('__') or name in self.internals:
            return node

        if name == "el":
            return Builtin("None")

        if isinstance(node.ctx, ast.Store):
            return store_econtext(name)

        aliased = self.aliases.get(name)
        if aliased is not None:
            return load(aliased)

        # If the name is a Python global, first try acquiring it from
        # the dynamic context, then fall back to the global.
        if name in self.builtins:
            return template(
                "getitem(econtext, key, name)",
                getitem=Symbol(getitem),
                mode="eval",
                key=ast.Str(s=name),
                name=load(name),
                )

        # Otherwise, simply acquire it from the dynamic context.
        return load_econtext(name)
Esempio n. 53
0
 def __call__(self, target, c_engine):
     # The convoluted handling of ``attrs`` below was necessary
     # for some ``chameleon`` versions to work around
     # "https://github.com/malthe/chameleon/issues/323".
     # The work round is partial only: until the ``chameleon``
     # problem is fixed, `attrs` cannot be used inside ``tal:define``.
     # Potentially, ``attrs`` handling could be simplified
     # for ``chameleon > 3.8.0``.
     return template(
         "try: __zt_tmp = attrs\n"
         "except NameError: __zt_tmp = None\n"
         "target = compile_zt_expr(type, expression, econtext=econtext)"
         "(c2z_context(econtext, __zt_tmp))",
         target=target,
         compile_zt_expr=_compile_zt_expr_node,
         type=ast.Str(self.type),
         expression=ast.Str(self.expression),
         c2z_context=_c_context_2_z_context_node,
         attrs=ast.Name("attrs", ast.Load()))
Esempio n. 54
0
def set_error(token, exception):
    try:
        line, column = token.location
        filename = token.filename
    except AttributeError:
        line, column = 0, 0
        filename = "<string>"

    string = safe_native(token)

    return template(
        "rcontext.setdefault('__error__', [])."
        "append((string, line, col, src, exc))",
        string=ast.Str(s=string),
        line=ast.Num(n=line),
        col=ast.Num(n=column),
        src=ast.Str(s=filename),
        sys=Symbol(sys),
        exc=exception,
    )
Esempio n. 55
0
def set_error(token, exception):
    try:
        line, column = token.location
        filename = token.filename
    except AttributeError:
        line, column = 0, 0
        filename = "<string>"

    string = safe_native(token)

    return template(
        "rcontext.setdefault('__error__', [])."
        "append((string, line, col, src, exc))",
        string=ast.Str(s=string),
        line=ast.Num(n=line),
        col=ast.Num(n=column),
        src=ast.Str(s=filename),
        sys=Symbol(sys),
        exc=exception,
        )
Esempio n. 56
0
    def _convert_text(self, target, body=None):
        """Converts value given by ``target`` to text."""

        if self._char_escape:
            # This is a cop-out - we really only support a very select
            # set of escape characters
            other = set(self._char_escape) - self.supported_char_escape_set

            if other:
                for supported in '"', '\'', '':
                    if supported in self._char_escape:
                        quote = supported
                        break
                else:
                    raise RuntimeError(
                        "Unsupported escape set: %s." % repr(self._char_escape)
                        )
            else:
                quote = '\0'

            entity = char2entity(quote or '\0')

            result = []
            if body is not None:
                result += template("T = F", F=body, T=target)

            return result + emit_convert_and_escape(
                target,
                quote=ast.Str(s=quote),
                quote_entity=ast.Str(s=entity),
                default=self._default,
                default_marker=self._default_marker,
                )

        return emit_convert(
            target,
            default=self._default,
            default_marker=self._default_marker,
            )
Esempio n. 57
0
    def _convert_text(self, target, body=None):
        """Converts value given by ``target`` to text."""

        if self._char_escape:
            # This is a cop-out - we really only support a very select
            # set of escape characters
            other = set(self._char_escape) - self.supported_char_escape_set

            if other:
                for supported in '"', '\'', '':
                    if supported in self._char_escape:
                        quote = supported
                        break
                else:
                    raise RuntimeError("Unsupported escape set: %s." %
                                       repr(self._char_escape))
            else:
                quote = '\0'

            entity = char2entity(quote or '\0')

            result = []
            if body is not None:
                result += template("T = F", F=body, T=target)

            return result + emit_convert_and_escape(
                target,
                quote=ast.Str(s=quote),
                quote_entity=ast.Str(s=entity),
                default=self._default,
                default_marker=self._default_marker,
            )

        return emit_convert(
            target,
            default=self._default,
            default_marker=self._default_marker,
        )
Esempio n. 58
0
    def translate(self, string, target):
        """
        >>> from chameleon.tales import test
        >>> test(PathExpr('None')) is None
        True
        """
        string = string.strip()

        if not string:
            return template("target = None", target=target)

        m = self.path_regex.match(string)
        if m is None:
            raise ExpressionError("Not a valid path-expression.", string)

        nocall, path = m.groups()

        # note that unicode paths are not allowed
        parts = str(path).split('/')

        components = []
        for part in parts[1:]:
            interpolation_args = []

            def replace(match):
                start, end = match.span()
                interpolation_args.append(
                    part[start + 1:end])
                return "%s"

            while True:
                part, count = self.interpolation_regex.subn(replace, part)
                if count == 0:
                    break

            if len(interpolation_args):
                component = template(
                    "format % args", format=ast.Str(part),
                    args=ast.Tuple(
                        list(map(load, interpolation_args)),
                        ast.Load()
                        ),
                    mode="eval")
            else:
                component = ast.Str(part)

            components.append(component)

        base = parts[0]

        if not components:
            if len(parts) == 1 and (nocall or base == 'None'):
                return template("target = base", base=base, target=target)
            else:
                components = ()

        call = template(
            "traverse(base, econtext, call, path_items)",
            traverse=self.traverser,
            base=load(base),
            call=load(str(not nocall)),
            path_items=ast.Tuple(elts=components),
            mode="eval",
            )

        return template("target = value", target=target, value=call)
Esempio n. 59
0
 def __call__(self, target, engine):
     assignment = super(TileExpression, self).__call__(target, engine)
     return assignment + template(
             'target = render_tile(context, request, target.strip())',
             target=target,
             render_tile=self.render_tile)
Esempio n. 60
0
 def __call__(self, target, engine):
     assignment = super(PermissionExpr, self).__call__(target, engine)
     return assignment + template(
             'target = check_permission(context, target)',
             target=target, check_permission=Symbol(checkPermission))