-
Notifications
You must be signed in to change notification settings - Fork 1
/
OBSERVATIONS
116 lines (90 loc) · 5.32 KB
/
OBSERVATIONS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
Observations
============
This file tracks things that might not work out as easy as planned or are
otherwise noteworthy.
Differences in Sematics
-----------------------
The following differences in semantics might cause a problem:
- Jinja2 currently adheres to the `__html__` special method that is also
used by Mako and Genshi (and the markupsafe package) to figure out how
autoescaping is supposed to work. Django does not do that, instead
it has its own special string type. Also that string behaves
differently on concatenation than the markupsafe one.
- Jinja2 performs constant folding, Django probably does not respond too
well to that as blocks can change autoescaping behavior and similar
things at runtime. This should not be too much of a problem as we can
just mark these blocks as volatile and the constant folding stops.
- Django includes pull in all locals into the same context. That is
generally also what Jinja2 is aiming for, so for as long as imports
are not used in Django there should not be a problem.
- Django resolves unknown variables to TEMPLATE_STRING_IF_INVALID which
can be a format string with ``%s`` for the variable name. Is a
transition to undefined objects possible? More importantly: are
undefines necessary on the compiler level?
- Context's are a biggy. In django filters and tags are stored on the
parser which means that the number of available parsers/filters is
available at template “parse / compile time”. However the actual
variables are stored at runtime in the context and there is only one
context. If a block originates in another file it will share the
context with the template it ultimately ends up being rendered in.
On the other hand there is Jinja2 which has different context's for
each block unless the block is opted in to be “scoped” which in
retrospect was a mistake.
The proper behavior for the compiler probably would be to have the
abilty to reused a new level on the context for blocks or a new level
on the module level context. Both behavior makes sense but it has
different semantics.
As the runtime info object, the compiler config and context are
already conceptionally separated it should be easy to have both
behavior so that it can be switched.
- One big problem for the identifier handling in Jinja2 is the fact that
the if-statement has different scoping rules in that it does not
introduce a new scope. This means that Jinja2 had to compensate for
the branch that was not taken in case variables were not assigned in
that branch that were in the other. Right now the template
compilation system here does not support this which simplifies the
code a lot. Because however this is very useful we should still
support this. Note very template engine will want to have Django
semantics regarding scoping. However that implementation then should
allow it to disable scopes in general which also means that it have to
take empty loops and else clauses to loops into account.
Jinja2 Long-Term Todo List that Might Be Worth Considering
----------------------------------------------------------
- A while ago there was a proposal for Jinja2 to have different escaping
schemes for different templates. Right now in Jinja2 you either have
or don't have autoescaping enabled, but autoescaping always means
escaping according to the HTML/XML/SGML rules. It would be nice to be
able to switch the escaping scheme based on what template you're
operating on. (LaTeX, reStructuredText, etc.).
We could in theory come closer to that goal by moving the markup_type
from the compiler config to the state. Reasonable?
Django Performance Limitations
------------------------------
- Django provides {{ forloop.parentloop }} which means that identifier
tracking to `forloop` won't work to speed up loops that don't need the
loop context. The current loop context in the runtime discards that
information, the django backend will have to override
context.wrap_loop and attach that value to the context. In fact the
django forloop thing would even have to emulate a dictionary interface
to say backwards compatible in that regard.
- Django has customiziable to-unicode behavior (smart_str)
- Django does not complain on unpacking tuples in loops.
Possible Counters
-----------------
- The template compiler could just use a general configuration object
that is passed around and controls these differences (what to use for
autoescaping)
- Django adopts the same semantics as the other environments for
escaping. That would also give it the speedup of markupsafe for the
escaping operations.
Other Things
------------
- ast.fix_missing_locations only sets actually missing locations, not
locations that are `None`. This should be changed as the latter is
quite useful and in fact required by our internal toolchain.
--> fix in cpython for 3.3
- The AST internal validation often yields weird results. This could be
improved. For instance passing a list where an expression is required
will give the error 'missing field "lineno"' instead of complaining
that the type is not correct. Generally the location of the error
does not exit which makes it hard to do that.