def _compile_module_file(template, text, filename, outputpath): identifier = template.module_id lexer = Lexer(text, filename, disable_unicode=template.disable_unicode, input_encoding=template.input_encoding, preprocessor=template.preprocessor) node = lexer.parse() source = codegen.compile(node, template.uri, filename, default_filters=template.default_filters, buffer_filters=template.buffer_filters, imports=template.imports, source_encoding=lexer.encoding, generate_magic_comment=True) # make tempfiles in the same location as the ultimate # location. this ensures they're on the same filesystem, # avoiding synchronization issues. (dest, name) = tempfile.mkstemp(dir=os.path.dirname(outputpath)) if isinstance(source, unicode): source = source.encode(lexer.encoding or 'ascii') os.write(dest, source) os.close(dest) shutil.move(name, outputpath)
def _compile_module_file(template, text, filename, outputpath): identifier = template.module_id lexer = Lexer(text, filename, disable_unicode=template.disable_unicode, input_encoding=template.input_encoding, preprocessor=template.preprocessor) node = lexer.parse() source = codegen.compile(node, template.uri, filename, default_filters=template.default_filters, buffer_filters=template.buffer_filters, imports=template.imports, source_encoding=lexer.encoding, generate_magic_comment=True) (dest, name) = tempfile.mkstemp() if isinstance(source, unicode): source = source.encode(lexer.encoding or 'ascii') os.write(dest, source) os.close(dest) shutil.move(name, outputpath)
def _compile_text(template, text, filename): identifier = template.module_id lexer = Lexer(text, filename, disable_unicode=template.disable_unicode, input_encoding=template.input_encoding, preprocessor=template.preprocessor) node = lexer.parse() source = codegen.compile(node, template.uri, filename, default_filters=template.default_filters, buffer_filters=template.buffer_filters, imports=template.imports, source_encoding=lexer.encoding, generate_magic_comment=template.disable_unicode) cid = identifier if not util.py3k and isinstance(cid, unicode): cid = cid.encode() module = types.ModuleType(cid) code = compile(source, cid, 'exec') exec code in module.__dict__, module.__dict__ return (source, module)
def _compile_module_file(template, text, filename, outputpath): identifier = template.module_id (dest, name) = tempfile.mkstemp() lexer = Lexer(text, filename, input_encoding=template.input_encoding, preprocessor=template.preprocessor) node = lexer.parse() source = codegen.compile(node, template.uri, filename, default_filters=template.default_filters, buffer_filters=template.buffer_filters, imports=template.imports, source_encoding=lexer.encoding) os.write(dest, source) os.close(dest) shutil.move(name, outputpath)
def _compile_text(template, text, filename): identifier = template.module_id lexer = Lexer(text, filename, input_encoding=template.input_encoding, preprocessor=template.preprocessor) node = lexer.parse() source = codegen.compile(node, template.uri, filename, default_filters=template.default_filters, buffer_filters=template.buffer_filters, imports=template.imports, source_encoding=lexer.encoding) #print source cid = identifier module = imp.new_module(cid) code = compile(source, cid, 'exec') exec code in module.__dict__, module.__dict__ return (source, module)
def _compile(template, text, filename, generate_magic_comment): lexer = Lexer(text, filename, disable_unicode=template.disable_unicode, input_encoding=template.input_encoding, preprocessor=template.preprocessor) node = lexer.parse() source = codegen.compile(node, template.uri, filename, default_filters=template.default_filters, buffer_filters=template.buffer_filters, imports=template.imports, source_encoding=lexer.encoding, generate_magic_comment=generate_magic_comment, disable_unicode=template.disable_unicode, strict_undefined=template.strict_undefined, enable_loop=template.enable_loop, reserved_names=template.reserved_names) return source, lexer
def test_code(self): template = \ """text <% print "hi" for x in range(1,5): print x %> more text <%! import foo %> """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, [ Text('text\n ', (1, 1)), Code('\nprint "hi"\nfor x in range(1,5):\n ' 'print x\n \n', False, (2, 5)), Text('\nmore text\n ', (6, 7)), Code('\nimport foo\n \n', True, (8, 5)), Text('\n', (10, 7))]) )
def test_tricky_code_2(self): template = """<% # someone's comment %> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode( {}, [ Code( """ # someone's comment """, False, (1, 1), ), Text("\n ", (3, 3)), ], ), )
def test_expression(self): template = \ """ this is some ${text} and this is ${textwith | escapes, moreescapes} <%def name="hi()"> give me ${foo()} and ${bar()} </%def> ${hi()} """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, [Text('\n this is some ', (1, 1)), Expression('text', [], (2, 22)), Text(' and this is ', (2, 29)), Expression('textwith ', ['escapes', 'moreescapes' ], (2, 42)), Text('\n ', (2, 76)), DefTag('def', {'name': 'hi()'}, (3, 9), [Text('\n give me ', (3, 27)), Expression('foo()', [], (4, 21)), Text(' and ', (4, 29)), Expression('bar()', [], (4, 34)), Text('\n ', (4, 42))]), Text('\n ' , (5, 16)), Expression('hi()', [], (6, 9)), Text('\n', (6, 16))]))
def test_comment_after_statement(self): template = """ % if x: #comment hi % else: #next hi % endif #end """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode( {}, [ Text("\n", (1, 1)), ControlLine("if", "if x: #comment", False, (2, 1)), Text(" hi\n", (3, 1)), ControlLine("else", "else: #next", False, (4, 1)), Text(" hi\n", (5, 1)), ControlLine("if", "endif #end", True, (6, 1)), ], ), )
def test_expr_in_attribute(self): """test some slightly trickier expressions. you can still trip up the expression parsing, though, unless we integrated really deeply somehow with AST.""" template = \ """ <%call expr="foo>bar and 'lala' or 'hoho'"/> <%call expr='foo<bar and hoho>lala and "x" + "y"'/> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('\n ', (1, 1)), CallTag('call', {'expr': "foo>bar and 'lala' or 'hoho'"}, (2, 13), []), Text('\n ', (2, 57)), CallTag('call', {'expr': 'foo<bar and hoho>lala and "x" + "y"'}, (3, 13), []), Text('\n ', (3, 64)) ]))
def test_tricky_code_3(self): template = """<% print('hi') # this is a comment # another comment x = 7 # someone's '''comment print(''' there ''') # someone else's comment %> '''and now some text '''""" nodes = Lexer(template).parse() self._compare( nodes, TemplateNode( {}, [ Code( """ print('hi') # this is a comment # another comment x = 7 # someone's '''comment print(''' there ''') # someone else's comment """, False, (1, 1), ), Text(" '''and now some text '''", (10, 3)), ], ), )
def test_ns_tag_open(self): template = """ <%self:go x="1" y="${process()}"> this is the body </%self:go> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode( {}, [ Text( """ """, (1, 1), ), CallNamespaceTag( "self:go", {"x": "1", "y": "${process()}"}, (3, 13), [ Text( """ this is the body """, (3, 46), ) ], ), Text("\n ", (5, 24)), ], ), )
def test_percent_escape(self): template = """ %% some whatever. %% more some whatever % if foo: % endif """ node = Lexer(template).parse() self._compare( node, TemplateNode( {}, [ Text("""\n\n""", (1, 1)), Text("""% some whatever.\n\n""", (3, 2)), Text(" %% more some whatever\n", (5, 2)), ControlLine("if", "if foo:", False, (6, 1)), ControlLine("if", "endif", True, (7, 1)), Text(" ", (8, 1)), ], ), )
def test_tricky_code_3(self): template = \ """<% print 'hi' # this is a comment # another comment x = 7 # someone's '''comment print ''' there ''' # someone else's comment %> '''and now some text '''""" nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Code( """\nprint 'hi'\n# this is a comment\n""" """# another comment\nx = 7 """ """# someone's '''comment\nprint '''\n """ """there\n '''\n# someone else's """ """comment\n\n""", False, (1, 1)), Text(" '''and now some text '''", (10, 3)) ]))
def test_ternary_control(self): template = \ """ % if x: hi % elif y+7==10: there % elif lala: lala % else: hi % endif """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)), ControlLine('if', 'if x:', False, (2, 1)), Text(' hi\n', (3, 1)), ControlLine('elif', 'elif y+7==10:', False, (4, 1)), Text(' there\n', (5, 1)), ControlLine('elif', 'elif lala:', False, (6, 1)), Text(' lala\n', (7, 1)), ControlLine('else', 'else:', False, (8, 1)), Text(' hi\n', (9, 1)), ControlLine('if', 'endif', True, (10, 1))]))
def test_docs(self): template = \ """ <%doc> this is a comment </%doc> <%def name="foo()"> <%doc> this is the foo func </%doc> </%def> """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, [Text('\n ', (1, 1)), Comment('''\n this is a comment\n ''', (2, 9)), Text('\n ', (4, 16)), DefTag('def', {'name': 'foo()'}, (5, 9), [Text('\n ', (5, 28)), Comment('''\n this is the foo func\n''' ''' ''', (6, 13)), Text('\n ', (8, 20))]), Text('\n ', (9, 16))]))
def test_code_and_tags(self): template = \ """ <%namespace name="foo"> <%def name="x()"> this is x </%def> <%def name="y()"> this is y </%def> </%namespace> <% result = [] data = get_data() for x in data: result.append(x+7) %> result: <%call expr="foo.x(result)"/> """ nodes = Lexer(template).parse() self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)), NamespaceTag('namespace', {'name': 'foo'}, (2, 1), [Text('\n ', (2, 24)), DefTag('def', {'name': 'x()'}, (3, 5), [Text('''\n this is x\n ''', (3, 22))]), Text('\n ', (5, 12)), DefTag('def', {'name' : 'y()'}, (6, 5), [Text('''\n this is y\n ''', (6, 22))]), Text('\n', (8, 12))]), Text('''\n\n''', (9, 14)), Code('''\nresult = []\ndata = get_data()\n''' '''for x in data:\n result.append(x+7)\n\n''', False, (11, 1)), Text('''\n\n result: ''', (16, 3)), CallTag('call', {'expr': 'foo.x(result)' }, (18, 13), []), Text('\n', (18, 42))]))
def test_integration(self): template = """<%namespace name="foo" file="somefile.html"/> ## inherit from foobar.html <%inherit file="foobar.html"/> <%def name="header()"> <div>header</div> </%def> <%def name="footer()"> <div> footer</div> </%def> <table> % for j in data(): <tr> % for x in j: <td>Hello ${x| h}</td> % endfor </tr> % endfor </table> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode( {}, [ NamespaceTag( "namespace", {"file": "somefile.html", "name": "foo"}, (1, 1), [], ), Text("\n", (1, 46)), Comment("inherit from foobar.html", (2, 1)), InheritTag("inherit", {"file": "foobar.html"}, (3, 1), []), Text("""\n\n""", (3, 31)), DefTag( "def", {"name": "header()"}, (5, 1), [Text("""\n <div>header</div>\n""", (5, 23))], ), Text("\n", (7, 8)), DefTag( "def", {"name": "footer()"}, (8, 1), [Text("""\n <div> footer</div>\n""", (8, 23))], ), Text("""\n\n<table>\n""", (10, 8)), ControlLine("for", "for j in data():", False, (13, 1)), Text(" <tr>\n", (14, 1)), ControlLine("for", "for x in j:", False, (15, 1)), Text(" <td>Hello ", (16, 1)), Expression("x", ["h"], (16, 23)), Text("</td>\n", (16, 30)), ControlLine("for", "endfor", True, (17, 1)), Text(" </tr>\n", (18, 1)), ControlLine("for", "endfor", True, (19, 1)), Text("</table>\n", (20, 1)), ], ), )
def test_text_tag(self): template = """ ## comment % if foo: hi % endif <%text> # more code % more code <%illegal compionent>/></> <%def name="laal()">def</%def> </%text> <%def name="foo()">this is foo</%def> % if bar: code % endif """ node = Lexer(template).parse() self._compare( node, TemplateNode( {}, [ Text("\n", (1, 1)), Comment("comment", (2, 1)), ControlLine("if", "if foo:", False, (3, 1)), Text(" hi\n", (4, 1)), ControlLine("if", "endif", True, (5, 1)), Text(" ", (6, 1)), TextTag( "text", {}, (6, 9), [ Text( "\n # more code\n\n " " % more code\n " "<%illegal compionent>/></>\n" ' <%def name="laal()">def</%def>' '\n\n\n ', (6, 16), ) ], ), Text("\n\n ", (14, 17)), DefTag( "def", {"name": "foo()"}, (16, 9), [Text("this is foo", (16, 28))], ), Text("\n\n", (16, 46)), ControlLine("if", "if bar:", False, (18, 1)), Text(" code\n", (19, 1)), ControlLine("if", "endif", True, (20, 1)), Text(" ", (21, 1)), ], ), )
def test_code_and_tags(self): template = """ <%namespace name="foo"> <%def name="x()"> this is x </%def> <%def name="y()"> this is y </%def> </%namespace> <% result = [] data = get_data() for x in data: result.append(x+7) %> result: <%call expr="foo.x(result)"/> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode( {}, [ Text("\n", (1, 1)), NamespaceTag( "namespace", {"name": "foo"}, (2, 1), [ Text("\n ", (2, 24)), DefTag( "def", {"name": "x()"}, (3, 5), [ Text( """\n this is x\n """, (3, 22), ) ], ), Text("\n ", (5, 12)), DefTag( "def", {"name": "y()"}, (6, 5), [ Text( """\n this is y\n """, (6, 22), ) ], ), Text("\n", (8, 12)), ], ), Text("""\n\n""", (9, 14)), Code( """\nresult = []\ndata = get_data()\n""" """for x in data:\n result.append(x+7)\n\n""", False, (11, 1), ), Text("""\n\n result: """, (16, 3)), CallTag("call", {"expr": "foo.x(result)"}, (18, 13), []), Text("\n", (18, 42)), ], ), )
def test_noexpr_allowed(self): template = \ """ <%namespace name="${foo}"/> """ self.assertRaises(exceptions.CompileException, Lexer(template).parse)
def test_nonexistent_tag(self): template = """ <%lala x="5"/> """ self.assertRaises(exceptions.CompileException, Lexer(template).parse)
def __init__(self, *args, **kwargs): Lexer.__init__(self, *args, **kwargs) self.disable_unicode = True
def test_old_multiline_comment(self): template = """#*""" node = Lexer(template).parse() self._compare(node, TemplateNode({}, [Text('''#*''', (1, 1))]))
def test_tricky_code(self): template = """<% print('hi %>') %>""" nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [Code("print('hi %>') \n", False, (1, 1))]))