Edgewall Software
Modify

Ticket #9699 (closed defect: fixed)

Opened 19 months ago

Last modified 17 months ago

TypeError: sequence item 0: expected string, LazyProxy found

Reported by: mjaeger Owned by: rblank
Priority: high Milestone: 0.12.2
Component: ticket system Version: 0.12-stable
Severity: normal Keywords:
Cc: cmlenz
Release Notes:
API Changes:

Description

How to Reproduce

While doing a GET operation on /ticket/1, Trac issued an internal error.

The error appears when I want to view the detail page of a ticket. I also got this error when creating a new ticket, but the ticket was created anyway. I can see the tickets in the timeline and in the ticket reports page, but i cannot access the detail page. Maybe this has something todo with Babel?

Request parameters:

{'id': u'1'}

User agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; de-de) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5

System Information

Trac 0.12.1
Babel 0.9.5 (translations unavailable)
Genshi 0.6
mod_python 3.3.1
MySQL server: "5.0.51a-3ubuntu5.7", client: "5.0.51a", thread-safe: 0
MySQLdb 1.2.2
Python 2.5.2 (r252:60911, Jan 20 2010, 23:30:56)
[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)]
setuptools 0.6c8
Subversion 1.4.6 (r28521)
jQuery 1.4.2

Enabled Plugins

Python Traceback

Traceback (most recent call last):
  File "build/bdist.linux-x86_64/egg/trac/web/main.py", line 511, in _dispatch_request
    dispatcher.dispatch(req)
  File "build/bdist.linux-x86_64/egg/trac/web/main.py", line 237, in dispatch
    resp = chosen_handler.process_request(req)
  File "build/bdist.linux-x86_64/egg/trac/ticket/web_ui.py", line 169, in process_request
    return self._process_ticket_request(req)
  File "build/bdist.linux-x86_64/egg/trac/ticket/web_ui.py", line 569, in _process_ticket_request
    get_reporter_id(req, 'author'), field_changes)
  File "build/bdist.linux-x86_64/egg/trac/ticket/web_ui.py", line 1518, in _insert_ticket_data
    req, ticket, action)
  File "build/bdist.linux-x86_64/egg/trac/ticket/default_workflow.py", line 321, in render_ticket_action_control
    return (this_action['name'], tag(*control), '. '.join(hints))
TypeError: sequence item 0: expected string, LazyProxy found

Attachments

9699-missing-locales-r10259.patch (1.5 KB) - added by rblank 19 months ago.
Avoid using LazyProxy when locale activation fails.

Download all attachments as: .zip

Change History

comment:1 Changed 19 months ago by anonymous

  • Resolution set to invalid
  • Status changed from new to closed

I got the resolution. The problem was installing Babel AFTER Trac. Reinstalling Trac fixed the problem.

comment:2 follow-up: Changed 19 months ago by rblank

  • Milestone set to 0.12.2
  • Owner set to rblank

That's weird. I thought we had added some code in 0.12.1 to catch this condition (#9439), and indeed the "(translations unavailable)" in your Bable version confirms this.

I think I know where this comes from. The control passed to tag() on line 321 is assumed to contain markup for each workflow option. Some of the values are constructed with tag_(), which is indeed wrapped in a LazyProxy in this case due to missing translations. Then Genshi raises the TypeError because tag() doesn't know how to deal with a LazyProxy.

We could probably argue that this is a bug in Genshi, and that it shouldn't check the explicit type of the items, but I don't see how it could do differently.

Another option would be to create LazyProxy subclasses that inherit from the expected return type, but that's probably not going to work in all cases.

Even another option would be to flag missing translations in activate(), and not to wrap the translation functions in that case.

I think I understand why we wrap the translation functions in LazyProxy, but is that really necessary in Trac? Aren't translations activated early enough that we could avoid this completely?

Thoughts?

comment:3 in reply to: ↑ 2 Changed 19 months ago by cboos

  • Resolution invalid deleted
  • Status changed from closed to reopened

Replying to rblank:

… Then Genshi raises the TypeError because tag() doesn't know how to deal with a LazyProxy.

There are a couple of places which have been "fixed" in an ad-hoc way (e.g. r9388), but it would be better to have a general solution.

Even another option would be to flag missing translations in activate(), and not to wrap the translation functions in that case.

Well, the idea of my has_babel-False patch was to use the no-op functions in a situation like this one, which would avoid the problem in most cases.

The only remaining issue would have been for the extraction errors, which can happen at server startup when multiple concurrent requests trigger the initial extraction: some will fail with a pkg_resources.ExtractionError, LazyProxy will be used and the request will nevertheless succeed provided it doesn't hit a part of the code which can't handle those, like reported here.

I think I understand why we wrap the translation functions in LazyProxy, but is that really necessary in Trac?

If the use of LazyProxy in the gettext functions is limited to cope with early extraction problems, we could indeed "fix" that by using the NullTranslationsBabel instance instead of the (missing) active one, but I just wonder if there are no other reasons to use the LazyProxy

Aren't translations activated early enough that we could avoid this completely?

Not yet, but that was indeed the idea I had back then in #9439. The goal could be to get rid of LazyProxy completely.

Thoughts?

Definitely worth reopening ;-)

comment:4 Changed 19 months ago by rblank

We have quite a few occurrences of this issue. They show up in the test suite when adding the following line:

  • trac/util/translation.py

    diff --git a/trac/util/translation.py b/trac/util/translation.py
    a b try: 
    139139            self._current.args = (get_locale, env_path) 
    140140 
    141141        def activate(self, locale, env_path=None): 
     142            return # Uncomment to run tests with missing locales 
    142143            try: 
    143144                locale_dir = pkg_resources.resource_filename('trac', 'locale') 
    144145            except Exception: 

I get 6 errors and 21 failures.

Changed 19 months ago by rblank

Avoid using LazyProxy when locale activation fails.

comment:5 Changed 19 months ago by rblank

9699-missing-locales-r10259.patch fixes all occurrences mentioned in comment:4, by avoiding wrapping in LazyProxy when activation fails. The patch includes a line to trigger the issue.

comment:6 Changed 19 months ago by cboos

Well, it seems that with the patch isactive can't even return False anymore? If so, this is effectively disabling the use of LazyProxy entirely.

comment:7 Changed 19 months ago by rblank

Heh, that does indeed seem so :) I hadn't noticed the call to activate() in isactive(). Too much magic going on in that module…

comment:8 Changed 19 months ago by rblank

Well, almost. There's still the case where one of the translation functions is called before make_activable(), but I assume that one is called so early that it just never happens.

comment:9 follow-up: Changed 19 months ago by jchulce@…

How does one apply that patch? I'm new to trac, and that error is driving me crazy

comment:10 in reply to: ↑ 9 Changed 19 months ago by rblank

Replying to jchulce@…:

How does one apply that patch?

You shouldn't. Instead, you should uninstall Trac and re-install it (after making sure Babel is installed).

comment:11 Changed 19 months ago by anonymous

Thanks!

comment:12 follow-up: Changed 17 months ago by cboos

  • Cc cmlenz added

We should apply the 9699-missing-locales-r10259.patch for 0.12.2.

On trunk, I'll experiment with removing the LazyProxy usage completely (googlegroups:trac-dev:fd27d050b9568445). Also, last try to get cmlenz in the loop, if he can recall why LazyProxy were introduced and enlighten us…

comment:13 in reply to: ↑ 12 ; follow-up: Changed 17 months ago by rblank

Replying to cboos:

We should apply the 9699-missing-locales-r10259.patch for 0.12.2.

Are you sure? Especially w.r.t. your comment:6.

comment:14 in reply to: ↑ 13 Changed 17 months ago by cboos

Replying to rblank:

Replying to cboos:

We should apply the 9699-missing-locales-r10259.patch for 0.12.2.

Are you sure? Especially w.r.t. your comment:6.

Yes, the patch fixes the issue and is minimally intrusive, so if there's any reason we should re-introduce the current logic about activation, we can easily do so. Maybe you could add a comment saying that for now, in practice isactive always returns True.

While working on notification.py, I've seen again the comment related to LazyObject made in r9388, which got me thinking we had some use in the past for LazyObjects, although probably not legitimate ones (caching "translated" strings?). At this point, I'm a bit reluctant to change drastically the logic related to activation 0.12-stable, we may do that in trunk if we see no problems with this change.

comment:15 Changed 17 months ago by rblank

  • Resolution set to fixed
  • Status changed from reopened to closed

Patch applied in [10397], and closing. Let's open a new ticket for removal of LazyProxy on trunk.

comment:16 Changed 17 months ago by anonymous

the solution to re-install Trac again after installing Babel worked for me.

View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
to The owner will be changed from rblank. Next status will be 'closed'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.