Modify ↓
Opened 4 months ago
Closed 7 weeks ago
#13773 closed defect (fixed)
Custom max and min filters for Jinja2 templates accept an iterable object
Reported by: | Jun Omae | Owned by: | Jun Omae |
---|---|---|---|
Priority: | normal | Milestone: | 1.6.1 |
Component: | rendering | Version: | 1.4 |
Severity: | normal | Keywords: | |
Cc: | Branch: | ||
Release Notes: |
|
||
API Changes: | |||
Internal Changes: |
Description
Trac core provides custom max
and min
filters, however the same filters have been added in Jinja2 3.0. The max
and min
filters in Trac don't accept an iterable object but the same filters in Jinja2 accept an iterable object.
I just encountered this error, I spent 2 days.
>>> tmpl = chrome.jenv.from_string('${ data|map("upper")|max(default="?") }') >>> tmpl.render(data=['Aaa', 'Bbb', 'ccc']) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/jun66j5/venv/py311/lib/python3.11/site-packages/jinja2/environment.py", line 1304, in render self.environment.handle_exception() File "/home/jun66j5/venv/py311/lib/python3.11/site-packages/jinja2/environment.py", line 939, in handle_exception raise rewrite_traceback_stack(source=source) File "<template>", line 1, in top-level template code File "/home/jun66j5/venv/trac/1.6/lib/python3.11/site-packages/trac/util/presentation.py", line 141, in max_filter if len(seq): ^^^^^^^^ TypeError: object of type 'generator' has no len()
>>> from jinja2 import Environment, BaseLoader >>> jenv = Environment(loader=BaseLoader()) >>> tmpl = jenv.from_string('{{ data|map("upper")|max }}') >>> tmpl.render(data=['Aaa', 'Bbb', 'ccc']) 'CCC'
Work around is to apply list
filter before max
.
-${ data|map("upper")|max(default="?") } +${ data|map("upper")|list|max(default="?") }
Patch:
-
trac/util/presentation.py
diff --git a/trac/util/presentation.py b/trac/util/presentation.py index 196a6c2b0..fc561ffb7 100644
a b def htmlattr_filter(_eval_ctx, d, autospace=True): 138 138 139 139 def max_filter(seq, default=None): 140 140 """Returns the max value from the sequence.""" 141 if len(seq): 142 return max(seq) 143 return default 141 return max(seq, default=default) 144 142 145 143 def min_filter(seq, default=None): 146 144 """Returns the min value from the sequence.""" 147 if len(seq): 148 return min(seq) 149 return default 145 return min(seq, default=default) 150 146 151 147 152 148 def trim_filter(value, what=None):
Attachments (0)
Change History (2)
comment:1 by , 7 weeks ago
comment:2 by , 7 weeks ago
Release Notes: | modified (diff) |
---|---|
Resolution: | → fixed |
Status: | assigned → closed |
Type: | enhancement → defect |
Version: | → 1.4 |
Note:
See TracTickets
for help on using tickets.
I noticed the
min
filter is never used due to a typo….trac/util/presentation.py
x=min_filter,