Opened 20 months ago
Closed 19 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 , 20 months ago
comment:2 by , 20 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 , 20 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 , 20 months ago
| Component: | general → rendering |
|---|---|
| Milestone: | → 1.6.1 |
| Owner: | set to |
| Status: | new → assigned |
follow-up: 7 comment:5 by , 20 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 , 20 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 , 20 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 dgettextdoes 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 , 19 months ago
| Release Notes: | modified (diff) |
|---|
Proposed changes in [bd056f646/jomae.git].
comment:9 by , 19 months ago
Replying to Clemens <c.feige@…>:
Yes, you are right, the text
dgettextdoes 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 , 19 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 , 19 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: