Merge lp:~vorlon/aptdaemon/lp.1034806 into lp:aptdaemon

Proposed by Steve Langasek on 2012-08-11
Status: Merged
Merged at revision: 859
Proposed branch: lp:~vorlon/aptdaemon/lp.1034806
Merge into: lp:aptdaemon
Diff against target: 158 lines (+92/-9)
3 files modified
aptdaemon/core.py (+20/-8)
aptdaemon/utils.py (+7/-1)
tests/regressions/test_lp768691.py (+65/-0)
To merge this branch: bzr merge lp:~vorlon/aptdaemon/lp.1034806
Reviewer Review Type Date Requested Status
Aptdaemon Developers 2012-08-11 Pending
Review via email: mp+119227@code.launchpad.net

Description of the change

Fixes for str/unicode confusion in aptdaemon. These don't matter much in
practice for python3, but I think python2 compatibility is still a goal for
aptdaemon upstream.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'aptdaemon/core.py'
2--- aptdaemon/core.py 2012-06-06 13:53:40 +0000
3+++ aptdaemon/core.py 2012-08-11 02:38:19 +0000
4@@ -68,6 +68,12 @@
5
6 # Setup i18n
7 _ = lambda msg: gettext.dgettext("aptdaemon", msg)
8+if sys.version >= '3':
9+ _gettext_method = "gettext"
10+ _ngettext_method = "ngettext"
11+else:
12+ _gettext_method = "ugettext"
13+ _ngettext_method = "ungettext"
14
15 APTDAEMON_DBUS_INTERFACE = 'org.debian.apt'
16 APTDAEMON_DBUS_PATH = '/org/debian/apt'
17@@ -1220,6 +1226,16 @@
18 """Set the kwargs which will be send to the AptWorker."""
19 self.kwargs = kwargs
20
21+ def _get_translations(self):
22+ """Get a usable translations object, no matter what."""
23+ if self._translation:
24+ return self._translation
25+ else:
26+ domain = "aptdaemon"
27+ return gettext.translation(domain, gettext.bindtextdomain(domain),
28+ gettext.bind_textdomain_codeset(domain),
29+ fallback=True)
30+
31 def gettext(self, msg):
32 """Translate the given message to the language of the transaction.
33 Fallback to the system default.
34@@ -1227,19 +1243,15 @@
35 # Avoid showing the header of the mo file for an empty string
36 if not msg:
37 return ""
38- if self._translation:
39- return self._translation.gettext(msg)
40- else:
41- return gettext.gettext(msg)
42+ translation = self._get_translations()
43+ return getattr(translation, _gettext_method)(msg)
44
45 def ngettext(self, singular, plural, count):
46 """Translate the given plural message to the language of the
47 transaction. Fallback to the system default.
48 """
49- if self._translation:
50- return self._translation.ngettext(singular, plural, count)
51- else:
52- return gettext.ngettext(singular, plural, count)
53+ translation = self._get_translations()
54+ return getattr(translation, _ngettext_method)(singular, plural, count)
55
56
57 class TransactionQueue(GObject.GObject):
58
59=== modified file 'aptdaemon/utils.py'
60--- aptdaemon/utils.py 2012-05-09 00:49:57 +0000
61+++ aptdaemon/utils.py 2012-08-11 02:38:19 +0000
62@@ -24,11 +24,17 @@
63
64 __all__ = ("deprecated", "IsoCodes")
65
66+import sys
67 import gettext
68 import functools
69 import warnings
70 from xml.etree import ElementTree
71
72+if sys.version >= '3':
73+ _gettext_method = "gettext"
74+else:
75+ _gettext_method = "ugettext"
76+
77 def deprecated(func):
78 """This is a decorator which can be used to mark functions
79 as deprecated. It will result in a warning being emitted
80@@ -76,7 +82,7 @@
81 return None
82 trans = gettext.translation(domain=self.norm, fallback=True,
83 languages=[locale])
84- return trans.gettext(name)
85+ return getattr(trans,_gettext_method)(name)
86
87 def get_name(self, value):
88 try:
89
90=== added file 'tests/regressions/test_lp768691.py'
91--- tests/regressions/test_lp768691.py 1970-01-01 00:00:00 +0000
92+++ tests/regressions/test_lp768691.py 2012-08-11 02:38:19 +0000
93@@ -0,0 +1,65 @@
94+#!/usr/bin/env python
95+# -*- coding: utf-8 -*-
96+"""Tests if we can handle different encodings well."""
97+
98+import locale
99+import logging
100+import os
101+import sys
102+import unittest
103+
104+from aptdaemon import core, enums, test, errors, utils
105+
106+DEBUG=True
107+
108+if sys.version >= '3':
109+ unicode = str
110+
111+class GettextTest(test.AptDaemonTestCase):
112+
113+ """Regression test for LP: #768691 and LP: #926340
114+
115+ The gettext.translation.gettext() method returns a string in Python 2.
116+ If we try to perform a string format operation, Python wants to convert
117+ string to unicode. If the daemon is running with a different
118+ default encoding as the translated message this results in an error.
119+ By defaulf aptdaemon runs as C if activated by D-Bus.
120+ """
121+
122+ def setUp(self):
123+ # Use the mo files from the build
124+ local_mo_files = os.path.join(test.get_tests_dir(),
125+ "../build/mo")
126+ if not os.path.isdir(local_mo_files):
127+ self.skipTest("Please run setup.py build before since local mo "
128+ "files are required. Run python setup.py build_i18n")
129+ core.gettext._default_localedir = local_mo_files
130+
131+ self.trans = core.Transaction(None, enums.ROLE_FIX_BROKEN_DEPENDS,
132+ None, os.getpid(), os.getuid(),
133+ sys.argv[0], "org.debian.apt.test",
134+ connect=False)
135+ self.codes = utils.IsoCodes("iso_639", tag="iso_639_1_code",
136+ fallback_tag="iso_639_2T_code")
137+
138+ def test(self):
139+ """Test if the installation of an unauthenticated packages fails
140+ if simulate hasn't been called explicitly before.
141+ """
142+ self.trans._set_locale("de_DE.UTF-8")
143+ ret = self.trans.gettext("CD/DVD '%s' is required")
144+ self.assertTrue(isinstance(ret, unicode))
145+ error = errors.TransactionFailed(enums.ERROR_NO_PACKAGE,
146+ "CD/DVD '%s' is required", "lala")
147+ self.trans.error = error
148+
149+ utils.gettext._default_localedir = "/usr/share/locale"
150+ lang = self.codes.get_localised_name("en", "ru.UTF-8")
151+ self.assertTrue(isinstance(lang, unicode))
152+
153+if __name__ == "__main__":
154+ if DEBUG:
155+ logging.basicConfig(level=logging.DEBUG)
156+ unittest.main()
157+
158+# vim: ts=4 et sts=4

Subscribers

People subscribed via source and target branches

to status/vote changes: