@@ -810,6 +810,172 @@ def test_tricky_expression(self):
810810 ),
811811 )
812812
813+ def test_dict_expression (self ):
814+ template = """
815+ <%def name="dtest(d)">
816+ % for k,v in d.items():
817+ ${k} = ${v}
818+ % endfor
819+ </%def>
820+
821+ <%self:dtest d="${
822+ {
823+ 'id':'4',
824+ 'foo':'barr'
825+ }
826+ }" />
827+ """
828+ nodes = Lexer (template ).parse ()
829+ self ._compare (
830+ nodes ,
831+ TemplateNode (
832+ {},
833+ [
834+ Text ("\n " , (1 , 1 )),
835+ DefTag (
836+ "def" ,
837+ {"name" : "dtest(d)" },
838+ (2 , 9 ),
839+ [
840+ Text ("\n " , (2 , 31 )),
841+ ControlLine (
842+ "for" , "for k,v in d.items():" , False , (3 , 1 )
843+ ),
844+ Text (" " , (4 , 1 )),
845+ Expression ("k" , [], (4 , 13 )),
846+ Text (" = " , (4 , 17 )),
847+ Expression ("v" , [], (4 , 20 )),
848+ Text ("\n " , (4 , 24 )),
849+ ControlLine ("for" , "endfor" , True , (5 , 1 )),
850+ Text (" " , (6 , 1 )),
851+ ],
852+ ),
853+ Text ("\n \n " , (6 , 16 )),
854+ CallNamespaceTag (
855+ "self:dtest" ,
856+ {
857+ "d" : "${\n "
858+ "{\n 'id':'4',\n "
859+ " 'foo':'barr'\n "
860+ " }\n "
861+ " }"
862+ },
863+ (8 , 9 ),
864+ [],
865+ ),
866+ Text ("\n " , (13 , 30 )),
867+ ],
868+ ),
869+ )
870+
871+ def test_dict_expression_2 (self ):
872+ template = """
873+ <%def name="thing(thing)">
874+ ${type(thing)}
875+ </%def>
876+
877+ <%self:thing thing="foo" />
878+
879+ <%self:thing thing="${5}" />
880+
881+ <%self:thing thing="${[1,2,3]}" />
882+
883+ <%self:thing thing="${{'id':'4'}, {'id': 5}}" />
884+
885+
886+ <%
887+ foo="this is foo"
888+ g=False
889+ %>
890+
891+ <%def name="bar(x, y)">
892+ ${x} ${y}
893+ </%def>
894+
895+ <%self:bar x=" ${{'id':4}} " y="x${g and '1' or '2'}y"/>
896+
897+ <%self:dtest d="${ {
898+ 'x-on:click':foo,
899+ 'foo':'bar'
900+ } }" />
901+ """
902+ nodes = Lexer (template ).parse ()
903+ self ._compare (
904+ nodes ,
905+ TemplateNode (
906+ {},
907+ [
908+ Text ("\n " , (1 , 1 )),
909+ DefTag (
910+ "def" ,
911+ {"name" : "thing(thing)" },
912+ (2 , 9 ),
913+ [
914+ Text ("\n " , (2 , 35 )),
915+ Expression ("type(thing)" , [], (3 , 13 )),
916+ Text ("\n " , (3 , 27 )),
917+ ],
918+ ),
919+ Text ("\n \n " , (4 , 16 )),
920+ CallNamespaceTag (
921+ "self:thing" , {"thing" : "foo" }, (6 , 9 ), []
922+ ),
923+ Text ("\n \n " , (6 , 36 )),
924+ CallNamespaceTag (
925+ "self:thing" , {"thing" : "${5}" }, (8 , 9 ), []
926+ ),
927+ Text ("\n \n " , (8 , 37 )),
928+ CallNamespaceTag (
929+ "self:thing" , {"thing" : "${[1,2,3]}" }, (10 , 9 ), []
930+ ),
931+ Text ("\n \n " , (10 , 43 )),
932+ CallNamespaceTag (
933+ "self:thing" ,
934+ {"thing" : "${{'id':'4'}, {'id': 5}}" },
935+ (12 , 9 ),
936+ [],
937+ ),
938+ Text ("\n \n \n " , (12 , 57 )),
939+ Code (
940+ '\n foo="this is foo"\n g=False\n \n ' ,
941+ False ,
942+ (15 , 9 ),
943+ ),
944+ Text ("\n \n " , (18 , 11 )),
945+ DefTag (
946+ "def" ,
947+ {"name" : "bar(x, y)" },
948+ (20 , 9 ),
949+ [
950+ Text ("\n " , (20 , 32 )),
951+ Expression ("x" , [], (21 , 13 )),
952+ Text (" " , (21 , 17 )),
953+ Expression ("y" , [], (21 , 18 )),
954+ Text ("\n " , (21 , 22 )),
955+ ],
956+ ),
957+ Text ("\n \n " , (22 , 16 )),
958+ CallNamespaceTag (
959+ "self:bar" ,
960+ {"x" : " ${{'id':4}} " , "y" : "x${g and '1' or '2'}y" },
961+ (24 , 9 ),
962+ [],
963+ ),
964+ Text ("\n \n " , (24 , 65 )),
965+ CallNamespaceTag (
966+ "self:dtest" ,
967+ {
968+ "d" : "${ {\n 'x-on:click':foo,\n "
969+ " 'foo':'bar'\n } }"
970+ },
971+ (26 , 9 ),
972+ [],
973+ ),
974+ Text ("\n " , (29 , 16 )),
975+ ],
976+ ),
977+ )
978+
813979 def test_tricky_code (self ):
814980 template = """<% print('hi %>') %>"""
815981 nodes = Lexer (template ).parse ()
0 commit comments