Edgewall Software
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:
  • Allowed passing a generator to max and min filters in Jinja2 templates.
  • Fixed a typo mix for min filter in Jinja2 templates.
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):  
    138138
    139139def max_filter(seq, default=None):
    140140    """Returns the max value from the sequence."""
    141     if len(seq):
    142         return max(seq)
    143     return default
     141    return max(seq, default=default)
    144142
    145143def min_filter(seq, default=None):
    146144    """Returns the min value from the sequence."""
    147     if len(seq):
    148         return min(seq)
    149     return default
     145    return min(seq, default=default)
    150146
    151147
    152148def trim_filter(value, what=None):

Attachments (0)

Change History (2)

comment:1 by Jun Omae, 7 weeks ago

I noticed the min filter is never used due to a typo….

  • trac/util/presentation.py

     
    5050        groupattr=groupattr_filter,
    5151        htmlattr=htmlattr_filter,
    5252        max=max_filter,
    53         mix=min_filter,
     53        min=min_filter,
    5454        trim=trim_filter,
    5555    )
    5656    jenv.tests.update(

comment:2 by Jun Omae, 7 weeks ago

Release Notes: modified (diff)
Resolution: fixed
Status: assignedclosed
Type: enhancementdefect
Version: 1.4

Fixed in [17849] and merged in [17852].

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Jun Omae.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Jun Omae to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.