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
Change History
comment:1 Changed 19 months ago by anonymous
- Resolution set to invalid
- Status changed from new to closed
comment:2 follow-up: ↓ 3 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: 139 139 self._current.args = (get_locale, env_path) 140 140 141 141 def activate(self, locale, env_path=None): 142 return # Uncomment to run tests with missing locales 142 143 try: 143 144 locale_dir = pkg_resources.resource_filename('trac', 'locale') 144 145 except Exception:
I get 6 errors and 21 failures.
Changed 19 months ago by rblank
- Attachment 9699-missing-locales-r10259.patch added
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: ↓ 10 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: ↓ 13 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: ↓ 14 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.



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