Edgewall Software
Modify

Opened 9 years ago

Closed 8 years ago

Last modified 8 years ago

#9699 closed defect (fixed)

TypeError: sequence item 0: expected string, LazyProxy found

Reported by: mjaeger Owned by: Remy Blank
Priority: high Milestone: 0.12.2
Component: ticket system Version: 0.12-stable
Severity: normal Keywords:
Cc: Christopher Lenz Branch:
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 (1)

9699-missing-locales-r10259.patch (1.5 KB ) - added by Remy Blank 9 years ago.
Avoid using LazyProxy when locale activation fails.

Download all attachments as: .zip

Change History (17)

comment:1 by anonymous, 9 years ago

Resolution: invalid
Status: newclosed

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

comment:2 by Remy Blank, 9 years ago

Milestone: 0.12.2
Owner: set to Remy Blank

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?

in reply to:  2 comment:3 by Christian Boos, 9 years ago

Resolution: invalid
Status: closedreopened

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 by Remy Blank, 9 years ago

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.

by Remy Blank, 9 years ago

Avoid using LazyProxy when locale activation fails.

comment:5 by Remy Blank, 9 years ago

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 by Christian Boos, 9 years ago

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 by Remy Blank, 9 years ago

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 by Remy Blank, 9 years ago

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 by jchulce@…, 9 years ago

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

in reply to:  9 comment:10 by Remy Blank, 9 years ago

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 by anonymous, 9 years ago

Thanks!

comment:12 by Christian Boos, 8 years ago

Cc: Christopher Lenz 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…

in reply to:  12 ; comment:13 by Remy Blank, 8 years ago

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.

in reply to:  13 comment:14 by Christian Boos, 8 years ago

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 by Remy Blank, 8 years ago

Resolution: fixed
Status: reopenedclosed

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

comment:16 by anonymous, 8 years ago

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

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Remy Blank.
The resolution will be deleted.
to The owner will be changed from Remy Blank 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.