Edgewall Software

Opened 7 years ago

Closed 7 years ago

Last modified 4 years ago

#12798 closed defect (fixed)

/timeline?max=10format=rss page dumps raw stack trace — at Version 14

Reported by: Jun Omae Owned by:
Priority: normal Milestone: 1.3.2
Component: timeline Version:
Severity: normal Keywords:
Cc: Branch:
Release Notes:
  • Fix typo, __slot__, in trac.util.html.
  • Fix UnicodeEncodeError raised from Element.__str__.
  • Fix TemplateRuntimeError raised in error.html when faulty plugins are more than one.
API Changes:
Internal Changes:

Description (last modified by Jun Omae)

/timeline?max=10format=rss page dumps raw stack trace (query string has no & characters).

Traceback (most recent call last):
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/trac/web/api.py", line 784, in send_error
    metadata)
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/trac/web/chrome.py", line 1410, in render_template
    fragment, iterable, method)
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/trac/web/chrome.py", line 1502, in _render_jinja_template
    iterable)
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/trac/web/chrome.py", line 1616, in generate_template_stream
    bytes = template.render(data).encode('utf-8')
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/trac/templates/error.html", line 89, in top-level template code
    <input type="submit" name="create" value="${_('Create')}" />
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/trac/templates/layout.html", line 12, in top-level template code
    # import "macros.html" as jmacros with context
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/trac/templates/theme.html", line 22, in top-level template code
    # block body
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/trac/templates/theme.html", line 128, in block "body"
    # block content
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/trac/templates/error.html", line 186, in block "content"
    ${faulty_plugins|map('name')|join(', ')}
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/jinja2/filters.py", line 322, in do_join
    value = list(value)
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/jinja2/filters.py", line 852, in do_map
    yield func(item)
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/jinja2/filters.py", line 984, in <lambda>
    name, item, args, kwargs, context=context)
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/jinja2/environment.py", line 451, in call_filter
    fail_for_missing_callable('no filter named %r', name)
  File "/usr/local/virtualenv/1.3dev/lib/python2.7/site-packages/jinja2/environment.py", line 97, in fail_for_missing_callable
    raise TemplateRuntimeError(msg)
TemplateRuntimeError: no filter named 'name'

Change History (15)

comment:1 by Ryan J Ollos, 7 years ago

Description: modified (diff)

comment:2 by Ryan J Ollos, 7 years ago

I don't get a traceback when I navigate there.

comment:3 by Jun Omae, 7 years ago

Hmm.

  1. If logged in, got TemplateRuntimeError: no filter named 'name'.
  2. If not logged in, got UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-7: ordinal not in range(128).

It might be caused by the session data. Also, I'm configuring Japanese in preferences panel to confirm localized messages on trunk.

Last edited 7 years ago by Jun Omae (previous) (diff)

comment:4 by Jun Omae, 7 years ago

Description: modified (diff)

The query string has no & characters.

by Ryan J Ollos, 7 years ago

comment:5 by Ryan J Ollos, 7 years ago

With no & I'm getting BadRequest:

comment:6 by Jun Omae, 7 years ago

I got second error on my development environment with Japanese and compiled catalog.

2017-05-08 18:41:43,633 Trac[main] ERROR: [192.168.11.23] Internal Server Error: <RequestWithSession "GET '/timeline?max=abc'">, referrer 'http://192.168.11.27:3000/1.3-sqlite/timeline?max=abc'
Traceback (most recent call last):
  File "/home/jun66j5/src/tracdev/git/trac/web/main.py", line 640, in _dispatch_request
    dispatcher.dispatch(req)
  File "/home/jun66j5/src/tracdev/git/trac/web/main.py", line 242, in dispatch
    resp = chosen_handler.process_request(req)
  File "/home/jun66j5/src/tracdev/git/trac/timeline/web_ui.py", line 95, in process_request
    maxrows = req.args.getint('max', 50 if format == 'rss' else 0)
  File "/home/jun66j5/src/tracdev/git/trac/web/api.py", line 400, in getint
    "%(name)s.", name=tag.em(name)))
  File "/home/jun66j5/src/tracdev/git/trac/web/api.py", line 246, in __init__
    self.detail))
  File "/home/jun66j5/src/tracdev/git/trac/util/html.py", line 354, in __str__
    return str(self.__unicode__())
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-7: ordinal not in range(128)

It seems the following patch fixes it.

  • trac/util/html.py

    diff --git a/trac/util/html.py b/trac/util/html.py
    index 9eca3076c..bfb666760 100644
    a b class Fragment(object):  
    351351        return u''.join(escape(c, False) for c in self.children)
    352352
    353353    def __str__(self):
    354         return str(self.__unicode__())
     354        return self.__unicode__().encode('utf-8')
    355355
    356356    def __add__(self, other):
    357357        return Fragment(self, other)
  • trac/web/api.py

    diff --git a/trac/web/api.py b/trac/web/api.py
    index 6a0dc3658..345b38861 100644
    a b class HTTPException(TracBaseError):  
    241241            self.detail = detail
    242242        if args:
    243243            self.detail = self.detail % args
    244         super(HTTPException, self).__init__('%s %s (%s)' % (self.code,
    245                                                             self.reason,
    246                                                             self.detail))
     244        super(HTTPException, self).__init__(u'%s %s (%s)' % (self.code,
     245                                                             self.reason,
     246                                                             self.detail))
    247247
    248248    @property
    249249    def message(self):

Another issue, I think __slot__ in Fragment is typo….

 class Fragment(object):
     """A fragment represents a sequence of strings or elements."""

-    __slot__ = ('children')
+    __slots__ = ('children',)
$ git grep -w '__slot__' -- '*.py'
trac/util/html.py:    __slot__ = ('children')
trac/util/html.py:    __slot__ = ('tag', 'attrib')
trac/util/html.py:    __slot__ = ()

comment:7 by Jun Omae, 7 years ago

The root cause is located at:

  • trac/templates/error.html

    diff --git a/trac/templates/error.html b/trac/templates/error.html
    index 141b7d885..5e7b809e3 100644
    a b  
    183183        Note that the following plugins seem to be involved:
    184184
    185185        #       endtrans
    186         ${faulty_plugins|map('name')|join(', ')}
     186        ${faulty_plugins|map(attribute='name')|join(', ')}
    187187        #     endif
    188188        <strong>
    189189          ${_("Please report this issue to the plugin maintainer.")}

in reply to:  6 ; comment:8 by Jun Omae, 7 years ago

Replying to Jun Omae:

Another issue, I think __slot__ in Fragment is typo….

Fixed in [15911].

in reply to:  8 comment:9 by Christian Boos, 7 years ago

Replying to Jun Omae:

Replying to Jun Omae:

Another issue, I think __slot__ in Fragment is typo….

Fixed in [15911].

Nice catch, sorry for the typo.

However, wouldn't self.attrib = self._dict_from_kwargs(kwargs) if kwargs else {} be slightly less efficient as it creates an empty dict each time there's no attributes for an element?

comment:10 by Jun Omae, 7 years ago

First, I just replaced __slot__ with __slots__ in Fragment class. However, the following errors occurred.

Traceback (most recent call last):
  File "/src/tracdev/git/trac/util/tests/html.py", line 295, in test_tracerror_with_tracerror_with_fragment
    tag.a('Trac', href='http://trac.edgewall.org/'))
  File "/src/tracdev/git/trac/util/html.py", line 431, in __call__
    self.attrib = d
AttributeError: 'Element' object attribute 'attrib' is read-only

Reconsidering…, I noticed we could do like this (unit tests passed). Thoughts?

  • trac/util/html.py

    diff --git a/trac/util/html.py b/trac/util/html.py
    index ff77295ea..c1dbd3ba6 100644
    a b class XMLElement(Fragment):  
    395395
    396396    __slots__ = ('tag', 'attrib')
    397397
     398    EMPTY_ATTRIB = {}
     399
    398400    VOID_ELEMENTS = ()
    399401
    400402    CLOSE_TAG = u'/>'
    class XMLElement(Fragment):  
    402404    def __init__(self, tag, *args, **kwargs):
    403405        Fragment.__init__(self, *args)
    404406        self.tag = unicode(tag)
    405         self.attrib = self._dict_from_kwargs(kwargs) if kwargs else {}
     407        self.attrib = self._dict_from_kwargs(kwargs) \
     408                      if kwargs else self.EMPTY_ATTRIB
    406409
    407410    def _attr_value(self, k, v):
    408411        return v

in reply to:  10 ; comment:11 by anonymous, 7 years ago

Replying to Jun Omae:

First, I just replaced __slot__ with __slots__ in Fragment class. However, the following errors occurred.

AttributeError: 'Element' object attribute 'attrib' is read-only

Ah, right, I overlooked this part of the __slots__ mechanism:

__slots__ are implemented at the class level by creating descriptors for each variable name. As a result, class attributes cannot be used to set default values for instance variables defined by __slots__; otherwise, the class attribute would overwrite the descriptor assignment.3.4.2.4. __slots__

Reconsidering…, I noticed we could do like this (unit tests passed). Thoughts?

Yes, I think that's what we should do.

$ python -mtimeit -s'empty=dict()' '[empty for e in xrange(0,1000)]'
10000 loops, best of 3: 33 usec per loop

$ python -mtimeit -s'empty=dict()' '[dict() for e in xrange(0,1000)]'
10000 loops, best of 3: 135 usec per loop

$ python -mtimeit -s'empty=dict()' '[{} for e in xrange(0,1000)]'
10000 loops, best of 3: 67.4 usec per loop

in reply to:  11 comment:12 by Jun Omae, 7 years ago

Replying to 匿名:

Reconsidering…, I noticed we could do like this (unit tests passed). Thoughts?

Yes, I think that's what we should do.

Thanks. Committed in [15913].

in reply to:  6 comment:13 by Jun Omae, 7 years ago

Replying to Jun Omae:

I got second error on my development environment with Japanese and compiled catalog.

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-7: ordinal not in range(128)

Fixed in [15917].

comment:14 by Jun Omae, 7 years ago

Release Notes: modified (diff)
Resolution: fixed
Status: newclosed

Changes in comment:7 has been applied in [15964].

Note: See TracTickets for help on using tickets.