Todo Before Release =================== This has to be implemented before the release: Drop special casing template globals ------------------------------------ The idea some time ago was to partially evaluate templates at compile time. For that we decided to not allow globals being overridden by locals as the static compiler could have changed semantics. Turns out that the static compiler blows up the complexity to something nobody wants to support which means that this restriction is kinda pointless. That should go for good. Pull Attributes Onces --------------------- Imagine the following template:: {% if foo.bar %} {{ baz(foo.bar) }} {% endif %} Problem with that is that it compiles to this:: if environment.subscribe(l_foo, 'bar'): if 0: yield None yield u'\n %s\n' % ( l_baz(environment.subscribe(l_foo, 'bar')), ) As `environment.subscribe` is more expensive then regular attribute lookups (it tries getitem/getattr and in sandbox mode also permissions) multiple lookups with the same parameters in the same scope should get local aliases. The result we have is that one:: t1 = environment.subscribe(l_foo, 'bar') if t1: if 0: yield None yield u'\n %s\n' % ( l_baz(t1), ) However that should only happen if the attribute is accessed multiple times unlike locals and filters/tests which are always pulled. We're not doing that for filters/tests/locals as nested scopes may access it and testing is too complicated for the tiny performance improvement but easy for attribute lookups, keeping the complexity of the whole thing in mind.