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
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
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
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
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
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
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
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
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
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
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
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
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 visit_CodeBlock(self, node): stmts = template(textwrap.dedent(node.source.strip('\n'))) for stmt in stmts: self._visitor(stmt) return stmts
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)
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
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
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)
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))
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, )
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, )
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
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")
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)]
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)]
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")
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)
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
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
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" )
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)
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" )
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)
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
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
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
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)
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
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()
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)
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()))
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, )
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, )
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, )
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)
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)
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))