add True, False, None

This commit is contained in:
danhanson committed 2026-09-10 15:00:39 -05:00
1 parent c0a2e0099c
commit 913ca69e6c
9 files changed
+40372 -39523

No files matched your search

+6
View File
@@ -277,6 +277,12 @@ documentation or memory. Both checks are worth repeating whenever tags, filters
- Django has no number token: `[\w.]+` is one lexeme and `int()`/`float()` decides whether it is a literal,
so `1a`, `1e`, `0x1f`, `1.2.3`, `1__0` and `1.` are variable _lookups_ there and errors here.
- Django has no boolean or `None` token either. `True`, `False` and `None` are lookups, which resolve
because `BaseContext._reset_dicts` seeds every context with `{"True": True, "False": False, "None": None}`.
They are `boolean` and `none` literals here, so that a tool reading `queries/locals.scm` does not count
them as references to something the template never defines. Shadowing still parses — `{% with True=1 %}`
binds an `identifier`, because the keyword is not valid where a binding name is — but `{{ True.x }}` is
an error here and an ordinary two-part lookup in Django, which renders `string_if_invalid`.
- A `with` binding written twice (`{% with a=1 a=2 %}`, and the same in `{% include %}` and
`{% blocktranslate %}`) is an error here and not in Django, where `token_kwargs` builds a dict and the
later value wins. It has no use, so it is treated as the mistake it almost certainly is.
+4 -1
View File
@@ -342,7 +342,8 @@ const django = grammar({
seq($.value, optional(seq("|", $.filter_expression))),
filter_expression: ($) => seq($.filter, repeat(seq("|", $.filter))),
value: ($) => choice($.literal, $.variable_attribute),
literal: ($) => choice($.number, $.string, $.translated_string),
literal: ($) =>
choice($.number, $.string, $.translated_string, $.boolean, $.none),
// digits, with single underscores allowed between them, as Python's
// int() and float() accept ("1_000") and Django's Variable relies on
number: ($) =>
@@ -354,6 +355,8 @@ const django = grammar({
* string: "_( 'a' )" is a syntax error there, not a translated literal.
*/
translated_string: ($) => seq("_(", $.string, ")"),
boolean: ($) => choice("True", "False"),
none: ($) => "None",
attribute: ($) => /[a-zA-Z0-9][a-zA-Z0-9_]*(?:\.[a-zA-Z0-9][a-zA-Z0-9_]*)*/,
variable_attribute: ($) =>
seq($.identifier, optional(seq(".", $.attribute))),
+2
View File
@@ -41,6 +41,8 @@ variable: (identifier) @variable.parameter
(number) @number
(string) @string
(boolean) @constant.builtin
(none) @constant.builtin
(library
(identifier) @module)
+25
View File
@@ -122,6 +122,14 @@
{
"type": "SYMBOL",
"name": "translated_string"
},
{
"type": "SYMBOL",
"name": "boolean"
},
{
"type": "SYMBOL",
"name": "none"
}
]
},
@@ -150,6 +158,23 @@
}
]
},
"boolean": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "True"
},
{
"type": "STRING",
"value": "False"
}
]
},
"none": {
"type": "STRING",
"value": "None"
},
"attribute": {
"type": "PATTERN",
"value": "[a-zA-Z0-9][a-zA-Z0-9_]*(?:\\.[a-zA-Z0-9][a-zA-Z0-9_]*)*"
+25
View File
@@ -396,6 +396,11 @@
]
}
},
{
"type": "boolean",
"named": true,
"fields": {}
},
{
"type": "cache_clause",
"named": true,
@@ -1699,6 +1704,14 @@
"multiple": false,
"required": true,
"types": [
{
"type": "boolean",
"named": true
},
{
"type": "none",
"named": true
},
{
"type": "number",
"named": true
@@ -2650,6 +2663,14 @@
"type": ">=",
"named": false
},
{
"type": "False",
"named": false
},
{
"type": "True",
"named": false
},
{
"type": "_(",
"named": false
@@ -3074,6 +3095,10 @@
"type": "media",
"named": false
},
{
"type": "none",
"named": true
},
{
"type": "noop",
"named": false
+40163 -39522
View File
File diff suppressed because it is too large. Load diff
+26
View File
@@ -156,3 +156,29 @@ If Operator Adjacent To Value
{% if 1and 2 %}yes{% endif %}
---
==================
If Is Not None
==================
{% if status is not None %}yes{% endif %}
---
(template
(content)
(if_group
(if_clause
(predicate
(filtered_value
(value
(variable_attribute
(identifier))))
(binaryOperator)
(filtered_value
(value
(literal
(none)))))
(template
(content))))
(content))
+100
View File
@@ -361,3 +361,103 @@ Template Variable With Spaced Filter
(filter_expression
(filter))))
(content))
==================
Template Variable True
==================
{{ True }}
---
(template
(content)
(template_variable
(filtered_value
(value
(literal
(boolean)))))
(content))
==================
Template Variable False
==================
{{ False }}
---
(template
(content)
(template_variable
(filtered_value
(value
(literal
(boolean)))))
(content))
==================
Template Variable None
==================
{{ None }}
---
(template
(content)
(template_variable
(filtered_value
(value
(literal
(none)))))
(content))
==================
Template Variable Boolean As Filter Argument
==================
{{ value|default:True }}
---
(template
(content)
(template_variable
(filtered_value
(value
(variable_attribute
(identifier)))
(filter_expression
(filter
argument: (value
(literal
(boolean)))))))
(content))
==================
Template Variable Name Beginning With A Literal
==================
{{ Truest }}
---
(template
(content)
(template_variable
(filtered_value
(value
(variable_attribute
(identifier)))))
(content))
==================
Template Variable Attribute Of A Literal
:error
==================
{{ None.x }}
---
+21
View File
@@ -111,3 +111,24 @@ With Repeating A Binding Of The Tag Before It
(template
(content))))
(content))
==================
With A Binding Named After A Literal
==================
{% with True=1 %}a{% endwith %}
---
(template
(content)
(with_group
(with_clause
variable: (identifier)
(filtered_value
(value
(literal
(number))))
(template
(content))))
(content))