Opened 9 months ago
Closed 8 months ago
#13745 closed defect (fixed)
Babel issue KeyError: 'dgettext'
Reported by: | clemens | Owned by: | Jun Omae |
---|---|---|---|
Priority: | normal | Milestone: | 1.6.1 |
Component: | i18n | Version: | 1.6 |
Severity: | normal | Keywords: | |
Cc: | c.feige@… | Branch: | |
Release Notes: |
|
||
API Changes: | |||
Internal Changes: |
Description
There seems to be a problem with babel with the CcSelectorPlugin. This plugin produces an error message if Babel is not installed. But since this root cause seems to be with the TRAC core, I am submitting the ticket here (and not at the Track-Hacks site).
Plugin error when Babel is not installed
I have been using the CcSelectorPlugin for many years. Now I re-installed my TRAC server (now with TRAC 1.6). Intentionally I decided to install TRAC without Babel because we do not want multi-lingual support.
After installing CcSelectorPlugin (Version 0.3, TrackHacks Revision 18597, from Nov. 2023, installation via PIP) it presents the following error when I click the "CC Selection" button:
Trac detected an internal error: KeyError: 'dgettext'
The Python Traceback points to site-packages/trac/util/translation.py
.
Python Traceback File "/data/trac/python/lib/python3.11/site-packages/trac/web/main.py", line 609, in dispatch_request dispatcher.dispatch(req) File "/data/trac/python/lib/python3.11/site-packages/trac/web/main.py", line 301, in dispatch raise e File "/data/trac/python/lib/python3.11/site-packages/trac/web/main.py", line 265, in dispatch output = chrome.render_template(req, template, data, metadata) File "/data/trac/python/lib/python3.11/site-packages/trac/web/chrome.py", line 1381, in render_template template, data = self.prepare_template(req, filename, data, text, File "/data/trac/python/lib/python3.11/site-packages/trac/web/chrome.py", line 1487, in prepare_template domain_functions = translation.domain_functions(domain, symbols) File "/data/trac/python/lib/python3.11/site-packages/trac/util/translation.py", line 92, in domain_functions return [_functions[s] for s in symbols] File "/data/trac/python/lib/python3.11/site-packages/trac/util/translation.py", line 92, in <listcomp> return [_functions[s] for s in symbols]
Discussion
Of course the solution is to install Babel, which will solve the problem.
Nevertheless IMHO either a plug-in should clearly state its dependencies during installation (or during run-time or in the documentation). Best of course would be would be, if the plug-in could run without Babel. After all, Babel is just optional for TRAC.
Although I am reporting an issue with a plugin this is supposed to be an issue with the TRAC core. This issue was discussed on the TRAC mailing list and I was told to open a ticket here.
Attachments (0)
Change History (11)
comment:1 by , 9 months ago
comment:2 by , 9 months ago
This is the answer I received from Jun Omae on the mailing list. He already made some experiments and statements which I am quoting here:
QUOTE:
That is an issue of Trac core since 1.4.x. It is reproduced with Trac 1.4.4 and 1.6 without Babel. Please report it to trac.edgewall.org/newticket.
TRAC 1.6:
$ python3.11 -m venv /dev/shm/trac-1.6 $ /dev/shm/trac-1.6/bin/pip install -q Trac~=1.6.0 $ /dev/shm/trac-1.6/bin/python Python 3.11.8 (main, Feb 25 2024, 16:41:26) [GCC 9.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import babel Traceback (most recent call last): File "<stdin>", line 1, in <module> ModuleNotFoundError: No module named 'babel' >>> import trac >>> trac.__version__ '1.6' >>> from trac.test import EnvironmentStub, MockRequest >>> from trac.web.chrome import Chrome >>> env = EnvironmentStub() >>> req = MockRequest(env) >>> chrome = Chrome(env) >>> chrome.prepare_template(req, 'layout.html', {}, domain='messages') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/dev/shm/trac-1.6/lib/python3.11/site-packages/trac/web/chrome.py", line 1487, in prepare_template domain_functions = translation.domain_functions(domain, symbols) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/dev/shm/trac-1.6/lib/python3.11/site-packages/trac/util/translation.py", line 92, in domain_functions return [_functions[s] for s in symbols] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/dev/shm/trac-1.6/lib/python3.11/site-packages/trac/util/translation.py", line 92, in <listcomp> return [_functions[s] for s in symbols] ~~~~~~~~~~^^^ KeyError: 'dgettext' >>>
TRAC 1.4:
$ virtualenv -p /usr/bin/python2.7 /dev/shm/trac-1.4 $ /dev/shm/trac-1.4/bin/pip install -q Trac~=1.4.0 $ /dev/shm/trac-1.4/bin/python Python 2.7.18 (default, Jul 1 2022, 12:27:04) [GCC 9.4.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import babel Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named babel >>> import trac >>> trac.__version__ '1.4.4' >>> from trac.test import EnvironmentStub, MockRequest >>> from trac.web.chrome import Chrome >>> env = EnvironmentStub() >>> req = MockRequest(env) >>> chrome = Chrome(env) >>> chrome.prepare_template(req, 'layout.html', {}, domain='messages') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/dev/shm/trac-1.4/lib/python2.7/site-packages/trac/web/chrome.py", line 1614, in prepare_template domain_functions = translation.domain_functions(domain, symbols) File "/dev/shm/trac-1.4/lib/python2.7/site-packages/trac/util/translation.py", line 92, in domain_functions return [_functions[s] for s in symbols] KeyError: 'dngettext' >>>
comment:3 by , 9 months ago
This issue can be reproduced with/without Babel.
>>> import trac, babel >>> (trac.__version__, babel.__version__) ('1.6', '2.14.0') >>> from trac.env import Environment >>> from trac.test import MockRequest >>> from trac.web.chrome import Chrome >>> from trac.util import read_file >>> >>> env = Environment('/dev/shm/tracenv-1.6') >>> req = MockRequest(env) >>> chrome = Chrome(env) >>> print(read_file('/dev/shm/tracenv-1.6/templates/test.html')) ${dgettext("messages", "Your changes have been saved.")} >>> t = chrome.render_template(req, 'test.html', {'data': 42}, {'domain': 'messages', 'iterable': False}) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/dev/shm/trac-1.6/lib/python3.11/site-packages/trac/web/chrome.py", line 1411, in render_template return self.generate_template_stream(template, data, text, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/dev/shm/trac-1.6/lib/python3.11/site-packages/trac/web/chrome.py", line 1533, in generate_template_stream return b''.join(generate()) ^^^^^^^^^^^^^^^^^^^^ File "/dev/shm/trac-1.6/lib/python3.11/site-packages/trac/web/chrome.py", line 1531, in generate for chunk in stream: File "/dev/shm/trac-1.6/lib/python3.11/site-packages/jinja2/environment.py", line 1662, in __next__ return self._next() # type: ignore ^^^^^^^^^^^^ File "/dev/shm/trac-1.6/lib/python3.11/site-packages/jinja2/environment.py", line 1639, in _buffered_generator c = next(self._gen) ^^^^^^^^^^^^^^^ File "/dev/shm/trac-1.6/lib/python3.11/site-packages/jinja2/environment.py", line 1354, in generate yield self.environment.handle_exception() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/dev/shm/trac-1.6/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/dev/shm/tracenv-1.6/templates/test.html", line 1, in top-level template code ${dgettext("messages", "Your changes have been saved.")} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/dev/shm/trac-1.6/lib/python3.11/site-packages/trac/util/translation.py", line 295, in <lambda> return lambda *args, **kw: _functions[symbol](domain, *args, **kw) ~~~~~~~~~~^^^^^^^^ KeyError: 'dgettext' >>>
comment:4 by , 9 months ago
Component: | general → rendering |
---|---|
Milestone: | → 1.6.1 |
Owner: | set to |
Status: | new → assigned |
follow-up: 7 comment:5 by , 9 months ago
The current version of CCSelectorPlugin from trunk has nowhere "dgettext" in the code. Which means you're using an old version.
Correct plugin for ≥ 1.6 can be found here: https://trac-hacks.org/svn/ccselectorplugin/trunk/
I don't think there is anything wrong in core.
comment:6 by , 9 months ago
Any plugins don't have the root cause. It occurs when process_request
returns domain
in metadata
parameter. Chrome
class injects domain functions (_, gettext, dgettext, …) to the template instance on rendering process, however, KeyError
is raised.
The issue is absolutely in Trac core.
>>> import babel Traceback (most recent call last): File "<stdin>", line 1, in <module> ModuleNotFoundError: No module named 'babel' >>> from trac.env import Environment >>> from trac.test import EnvironmentStub, MockRequest >>> from trac.web.api import IRequestHandler >>> from trac.core import Component, implements >>> from trac.web.main import RequestDispatcher >>> >>> class Foo(Component): ... implements(IRequestHandler) ... def match_request(self, req): ... return req.path_info == '/test' ... def process_request(self, req): ... return 'layout.html', {'data': 42}, {'domain': 'messages'} ... >>> env = EnvironmentStub() >>> req = MockRequest(env, path_info='/test') >>> dispatcher = RequestDispatcher(env) >>> dispatcher.dispatch(req) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/jun66j5/src/tracdev/git/trac/web/main.py", line 301, in dispatch raise e File "/home/jun66j5/src/tracdev/git/trac/web/main.py", line 265, in dispatch output = chrome.render_template(req, template, data, metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/jun66j5/src/tracdev/git/trac/web/chrome.py", line 1381, in render_template template, data = self.prepare_template(req, filename, data, text, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/jun66j5/src/tracdev/git/trac/web/chrome.py", line 1487, in prepare_template domain_functions = translation.domain_functions(domain, symbols) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/jun66j5/src/tracdev/git/trac/util/translation.py", line 92, in domain_functions return [_functions[s] for s in symbols] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/jun66j5/src/tracdev/git/trac/util/translation.py", line 92, in <listcomp> return [_functions[s] for s in symbols] ~~~~~~~~~~^^^ KeyError: 'dgettext' >>>
follow-up: 9 comment:7 by , 9 months ago
Replying to Dirk Stöcker:
The current version of CCSelectorPlugin from trunk has nowhere "dgettext" in the code. Which means you're using an old version.
Correct plugin for ≥ 1.6 can be found here: https://trac-hacks.org/svn/ccselectorplugin/trunk/
I don't think there is anything wrong in core.
I am quite sure that I am using the most recent version of the CCSelectorPlugin (Version 0.3, TrackHacks Revision 18597, from Nov. 2023) because I just installed it myself few days ago with this command:
pip install svn+https://trac-hacks.org/svn/ccselectorplugin/trunk/
Yes, you are right, the text dgettext
does not appear in the plug-in code.
This was something I checked when I came across this error, too.
I am not sure if this tells us where this root problem is, in the plugin or in the core.
Seems that Jun has found something…
comment:8 by , 8 months ago
Release Notes: | modified (diff) |
---|
Proposed changes in [bd056f646/jomae.git].
comment:9 by , 8 months ago
Replying to Clemens <c.feige@…>:
Yes, you are right, the text
dgettext
does not appear in the plug-in code. This was something I checked when I came across this error, too. I am not sure if this tells us where this root problem is, in the plugin or in the core.
That is a defect in Trac core. Work around for the plugin is avoid process_request
returning {'domain': 'cc_selector'}
as metadata like the following:
-
cc_selector/cc_selector.py
77 77 'cc_developers': cc_developers, 78 78 'show_fullname': self.show_fullname 79 79 } 80 return 'cc_selector_jinja.html', data , {'domain': 'cc_selector'}80 return 'cc_selector_jinja.html', data -
cc_selector/templates/cc_selector_jinja.html
1 1 # import "macros.html" as jmacros with context 2 # set _ = partial(dgettext, 'cc_selector') 2 3 <!DOCTYPE html> 3 4 <html> 4 5 <head>
comment:10 by , 8 months ago
Added [ac30ba8be/jomae.git] to the proposed changes. The tag_
function is available in Jinja2 template but tagn_
, dtgettext
and dtngettext
are unavailable. The changes allow the latter functions.
comment:11 by , 8 months ago
Component: | rendering → i18n |
---|---|
Release Notes: | modified (diff) |
Resolution: | → fixed |
Status: | assigned → closed |
I want to contribute some details about my TRAC where I found this issue: